@absolutejs/absolute 0.20.0-beta.3 → 0.20.0-beta.4

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/cli/index.js CHANGED
@@ -3379,6 +3379,548 @@ var init_iosSimulatorController = __esm(() => {
3379
3379
  ];
3380
3380
  });
3381
3381
 
3382
+ // src/mobile/remoteMacWire.ts
3383
+ var ABSOLUTE_REMOTE_MAC_EVENT_PREFIX = "ABSOLUTE_REMOTE_MAC\t", ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION = 1;
3384
+
3385
+ // src/mobile/remoteMacProtocol.ts
3386
+ import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
3387
+ import { chmod, mkdir as mkdir5, readFile as readFile6, rename as rename5, writeFile as writeFile5 } from "fs/promises";
3388
+ import { homedir as homedir4 } from "os";
3389
+ import {
3390
+ dirname as dirname6,
3391
+ isAbsolute as isAbsolute4,
3392
+ join as join10,
3393
+ posix,
3394
+ relative as relative5,
3395
+ resolve as resolvePath,
3396
+ sep as sep4
3397
+ } from "path";
3398
+ var PROFILE_FORMAT = 1, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () => join10(homedir4(), ".absolutejs", "mobile", "remote-macs.json"), emptyStore = () => ({
3399
+ format: PROFILE_FORMAT,
3400
+ profiles: {}
3401
+ }), loadStore = async (path = defaultProfilePath()) => {
3402
+ try {
3403
+ const parsed = JSON.parse(await readFile6(path, "utf8"));
3404
+ if (parsed.format !== PROFILE_FORMAT || typeof parsed.profiles !== "object" || parsed.profiles === null || Array.isArray(parsed.profiles))
3405
+ throw new Error("Unsupported remote Mac profile format.");
3406
+ for (const [key, profile] of Object.entries(parsed.profiles)) {
3407
+ if (typeof profile !== "object" || profile === null || validateAbsoluteRemoteMacProfileName(key) !== key || profile.name !== key || validateAbsoluteSshDestination(profile.destination) !== profile.destination || validatePort(profile.port) !== profile.port || typeof profile.createdAt !== "string" || !profile.createdAt || typeof profile.bunPath !== "string" || !profile.bunPath.startsWith("/") || /[\r\n\0]/u.test(profile.bunPath) || typeof profile.workspaceRoot !== "string" || !profile.workspaceRoot.startsWith("/") || profile.workspaceRoot === "/" || /[\r\n\0]/u.test(profile.workspaceRoot) || typeof profile.xcodeVersion !== "string" || !profile.xcodeVersion.startsWith("Xcode "))
3408
+ throw new Error(`Remote Mac profile ${JSON.stringify(key)} is invalid.`);
3409
+ }
3410
+ if (parsed.defaultProfile !== undefined && !parsed.profiles[parsed.defaultProfile])
3411
+ throw new Error("The default remote Mac profile does not exist.");
3412
+ return parsed;
3413
+ } catch (error) {
3414
+ if (error.code === "ENOENT")
3415
+ return emptyStore();
3416
+ throw error;
3417
+ }
3418
+ }, saveStore = async (store, path = defaultProfilePath()) => {
3419
+ await mkdir5(dirname6(path), { recursive: true });
3420
+ const temporary = `${path}.${randomUUID3()}.tmp`;
3421
+ await writeFile5(temporary, `${JSON.stringify(store, null, 2)}
3422
+ `, {
3423
+ mode: 384
3424
+ });
3425
+ await rename5(temporary, path);
3426
+ await chmod(path, 384);
3427
+ }, validateAbsoluteRemoteMacProfileName = (name) => {
3428
+ const normalized = name.trim().toLowerCase();
3429
+ if (!PROFILE_NAME.test(normalized))
3430
+ throw new TypeError("Remote Mac profile names must use 1-64 lowercase letters, digits, dots, dashes, or underscores.");
3431
+ return normalized;
3432
+ }, validateAbsoluteSshDestination = (destination) => {
3433
+ const normalized = destination.trim();
3434
+ if (!SSH_DESTINATION.test(normalized) || normalized.startsWith("-"))
3435
+ throw new TypeError("Remote Mac SSH destination must be a host, SSH alias, or user@host without command-line options.");
3436
+ return normalized;
3437
+ }, validatePort = (port) => {
3438
+ if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65535))
3439
+ throw new TypeError("Remote Mac SSH port must be between 1 and 65535.");
3440
+ return port;
3441
+ }, shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`, absoluteRemoteMacSshBase = (profile, options = {}) => [
3442
+ "ssh",
3443
+ "-o",
3444
+ "BatchMode=yes",
3445
+ "-o",
3446
+ "ConnectTimeout=10",
3447
+ "-o",
3448
+ "ServerAliveInterval=15",
3449
+ "-o",
3450
+ "ServerAliveCountMax=3",
3451
+ "-o",
3452
+ `StrictHostKeyChecking=${options.acceptNew ? "accept-new" : "yes"}`,
3453
+ ...profile.port ? ["-p", String(profile.port)] : [],
3454
+ profile.destination
3455
+ ], localCapture = async (command) => {
3456
+ const process2 = Bun.spawn(command, {
3457
+ stderr: "pipe",
3458
+ stdin: "ignore",
3459
+ stdout: "pipe"
3460
+ });
3461
+ const [exitCode, stdout, stderr] = await Promise.all([
3462
+ process2.exited,
3463
+ new Response(process2.stdout).text(),
3464
+ new Response(process2.stderr).text()
3465
+ ]);
3466
+ return { exitCode, stderr, stdout };
3467
+ }, defaultTransport, requireRemoteSuccess = (result, label) => {
3468
+ if (result.exitCode !== 0)
3469
+ throw new Error(`${label} failed: ${(result.stderr || result.stdout).trim() || `status ${result.exitCode}`}`);
3470
+ return result.stdout.trim();
3471
+ }, getAbsoluteRemoteMacProfile = async (name, profilePath) => {
3472
+ const store = await loadStore(profilePath);
3473
+ const selected = name ?? process.env.ABSOLUTE_IOS_REMOTE ?? store.defaultProfile;
3474
+ if (!selected)
3475
+ return;
3476
+ const profile = store.profiles[selected];
3477
+ if (!profile)
3478
+ throw new Error(`Remote Mac profile ${JSON.stringify(selected)} was not found.`);
3479
+ return profile;
3480
+ }, inspectAbsoluteRemoteMac = async (destination, options = {}) => {
3481
+ const profile = {
3482
+ destination: validateAbsoluteSshDestination(destination),
3483
+ port: validatePort(options.port)
3484
+ };
3485
+ const capture = options.transport?.capture ?? defaultTransport.capture;
3486
+ const command = [
3487
+ ...absoluteRemoteMacSshBase(profile, {
3488
+ acceptNew: options.acceptNew === true
3489
+ }),
3490
+ "/bin/sh -lc",
3491
+ shellQuote(`bun_path="$(command -v bun || true)"; if [ -z "$bun_path" ] && [ -x "$HOME/.bun/bin/bun" ]; then bun_path="$HOME/.bun/bin/bun"; fi; printf '%s\\n' "$(uname -s)" "$HOME" "$bun_path" "$(/usr/bin/xcodebuild -version 2>/dev/null | tr '\\n' ' ' || true)"`)
3492
+ ];
3493
+ const lines = requireRemoteSuccess(await capture(command), "Remote Mac handshake").split(/\r?\n/u);
3494
+ const [operatingSystem, home, bunPath, xcodeVersion] = lines;
3495
+ if (operatingSystem !== "Darwin")
3496
+ throw new Error("The SSH target is not a Mac.");
3497
+ if (!home?.startsWith("/") || !bunPath?.startsWith("/"))
3498
+ throw new Error("The remote Mac must have Bun installed and available to SSH.");
3499
+ if (!xcodeVersion?.startsWith("Xcode "))
3500
+ throw new Error("The remote Mac must have full Xcode installed and selected.");
3501
+ return { bunPath, home, os: operatingSystem, xcodeVersion };
3502
+ }, listAbsoluteRemoteMacProfiles = async (profilePath) => {
3503
+ const store = await loadStore(profilePath);
3504
+ return {
3505
+ defaultProfile: store.defaultProfile,
3506
+ profiles: Object.values(store.profiles).sort((left, right) => left.name.localeCompare(right.name))
3507
+ };
3508
+ }, pairAbsoluteRemoteMac = async (options) => {
3509
+ const name = validateAbsoluteRemoteMacProfileName(options.name);
3510
+ const destination = validateAbsoluteSshDestination(options.destination);
3511
+ const port = validatePort(options.port);
3512
+ const inspection = await inspectAbsoluteRemoteMac(destination, {
3513
+ acceptNew: true,
3514
+ port,
3515
+ transport: options.transport
3516
+ });
3517
+ const workspaceRoot = options.workspaceRoot ? options.workspaceRoot.trim() : posix.join(inspection.home, ".absolutejs", "remote-ios");
3518
+ if (!workspaceRoot.startsWith("/") || workspaceRoot === "/" || /[\r\n\0]/u.test(workspaceRoot))
3519
+ throw new TypeError("Remote Mac workspace must be an absolute macOS path.");
3520
+ const profile = {
3521
+ bunPath: inspection.bunPath,
3522
+ createdAt: new Date().toISOString(),
3523
+ destination,
3524
+ name,
3525
+ ...port ? { port } : {},
3526
+ workspaceRoot,
3527
+ xcodeVersion: inspection.xcodeVersion
3528
+ };
3529
+ const store = await loadStore(options.profilePath);
3530
+ store.profiles[name] = profile;
3531
+ store.defaultProfile = name;
3532
+ await saveStore(store, options.profilePath);
3533
+ return profile;
3534
+ }, removeAbsoluteRemoteMacProfile = async (name, profilePath) => {
3535
+ const normalized = validateAbsoluteRemoteMacProfileName(name);
3536
+ const store = await loadStore(profilePath);
3537
+ if (!store.profiles[normalized])
3538
+ return false;
3539
+ delete store.profiles[normalized];
3540
+ if (store.defaultProfile === normalized) {
3541
+ const [nextDefault] = Object.keys(store.profiles).sort();
3542
+ store.defaultProfile = nextDefault;
3543
+ }
3544
+ await saveStore(store, profilePath);
3545
+ return true;
3546
+ }, projectIdentity = (projectRoot, appId) => createHash5("sha256").update(`${resolvePath(projectRoot)}\x00${appId}`).digest("hex").slice(0, 20), createAbsoluteRemoteIosDevProject = (config, projectRoot, profile) => ({
3547
+ cap: join10(resolvePath(projectRoot), "node_modules", ".bin", "cap"),
3548
+ config,
3549
+ nativeDirectory: join10(config.nativeProjectDirectory, "ios"),
3550
+ profile,
3551
+ projectRoot: resolvePath(projectRoot),
3552
+ remote: true,
3553
+ remoteProjectRoot: posix.join(profile.workspaceRoot, "projects", projectIdentity(projectRoot, config.appId), "current"),
3554
+ xcodebuild: "remote:xcodebuild",
3555
+ xcrun: "remote:xcrun"
3556
+ }), installAbsoluteRemoteMacAgent = async (project) => {
3557
+ const artifact = await materializeAbsoluteRemoteMacAgent(project.projectRoot);
3558
+ const directory = posix.join(project.profile.workspaceRoot, "agents", `protocol-${ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION}`, artifact.sha256);
3559
+ const remotePath = posix.join(directory, "agent.js");
3560
+ const verifyScript = `test -f ${shellQuote(remotePath)} && ` + `test "$(shasum -a 256 ${shellQuote(remotePath)} | awk '{print $1}')" = ${shellQuote(artifact.sha256)}`;
3561
+ const verified = await defaultTransport.capture([
3562
+ ...absoluteRemoteMacSshBase(project.profile),
3563
+ "/bin/sh -lc",
3564
+ shellQuote(verifyScript)
3565
+ ]);
3566
+ if (verified.exitCode === 0)
3567
+ return { ...artifact, remotePath, uploaded: false };
3568
+ const temporary = posix.join(directory, `.agent-${randomUUID3()}.tmp`);
3569
+ const installScript = [
3570
+ "set -eu",
3571
+ "umask 077",
3572
+ `mkdir -p ${shellQuote(directory)}`,
3573
+ `cat > ${shellQuote(temporary)}`,
3574
+ `test "$(shasum -a 256 ${shellQuote(temporary)} | awk '{print $1}')" = ${shellQuote(artifact.sha256)}`,
3575
+ `chmod 600 ${shellQuote(temporary)}`,
3576
+ `mv ${shellQuote(temporary)} ${shellQuote(remotePath)}`
3577
+ ].join("; ");
3578
+ const upload = Bun.spawn([
3579
+ ...absoluteRemoteMacSshBase(project.profile),
3580
+ "/bin/sh -lc",
3581
+ shellQuote(installScript)
3582
+ ], {
3583
+ stderr: "pipe",
3584
+ stdin: Bun.file(artifact.path),
3585
+ stdout: "pipe"
3586
+ });
3587
+ const [exitCode, stderr] = await Promise.all([
3588
+ upload.exited,
3589
+ new Response(upload.stderr).text()
3590
+ ]);
3591
+ if (exitCode !== 0)
3592
+ throw new Error(`Remote Mac agent installation failed: ${stderr.trim() || `status ${exitCode}`}`);
3593
+ return { ...artifact, remotePath, uploaded: true };
3594
+ }, materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
3595
+ const shippedCandidates = [
3596
+ join10(import.meta.dir, "remoteMacAgentEntry.js"),
3597
+ join10(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
3598
+ ];
3599
+ let path;
3600
+ for (const candidate of shippedCandidates) {
3601
+ if (await Bun.file(candidate).exists()) {
3602
+ path = candidate;
3603
+ break;
3604
+ }
3605
+ }
3606
+ if (!path) {
3607
+ const sourceCandidates = [
3608
+ join10(import.meta.dir, "remoteMacAgentEntry.ts"),
3609
+ join10(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
3610
+ ];
3611
+ const source = await sourceCandidates.reduce(async (found, candidate) => await found ?? (await Bun.file(candidate).exists() ? candidate : undefined), Promise.resolve(undefined));
3612
+ if (!source)
3613
+ throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
3614
+ const outdir = join10(resolvePath(projectRoot), ".absolutejs", "mobile", "remote-agent");
3615
+ await mkdir5(outdir, { recursive: true });
3616
+ const result = await Bun.build({
3617
+ entrypoints: [source],
3618
+ minify: true,
3619
+ outdir,
3620
+ target: "bun"
3621
+ });
3622
+ if (!result.success)
3623
+ throw new AggregateError(result.logs, "Failed to build the AbsoluteJS remote Mac agent.");
3624
+ path = join10(outdir, "remoteMacAgentEntry.js");
3625
+ }
3626
+ const bytes = await Bun.file(path).arrayBuffer();
3627
+ const sha256 = createHash5("sha256").update(new Uint8Array(bytes)).digest("hex");
3628
+ return { bytes: bytes.byteLength, path, sha256 };
3629
+ }, portableRelativePath = (root, path) => relative5(root, path).split(sep4).join(posix.sep), portableMobileConfig = (project) => ({
3630
+ appId: project.config.appId,
3631
+ appName: project.config.appName,
3632
+ bundleDirectory: portableRelativePath(project.projectRoot, project.config.bundleDirectory),
3633
+ ...project.config.deepLinkScheme || project.config.deepLinkHosts.length > 1 || project.config.appleAppIdPrefix ? {
3634
+ deepLinks: {
3635
+ ...project.config.deepLinkScheme ? { scheme: project.config.deepLinkScheme } : {},
3636
+ hosts: project.config.deepLinkHosts,
3637
+ ...project.config.appleAppIdPrefix ? {
3638
+ apple: {
3639
+ appIdPrefix: project.config.appleAppIdPrefix
3640
+ }
3641
+ } : {}
3642
+ }
3643
+ } : {},
3644
+ entry: project.config.entry,
3645
+ ...project.config.iosVersion ? { ios: { version: project.config.iosVersion } } : {},
3646
+ nativeProject: {
3647
+ directory: portableRelativePath(project.projectRoot, project.config.nativeProjectDirectory),
3648
+ mode: "source"
3649
+ },
3650
+ platforms: ["ios"],
3651
+ server: { productionOrigin: project.config.productionOrigin }
3652
+ }), absoluteRemoteProjectSyncCommands = (project) => {
3653
+ const current = project.remoteProjectRoot;
3654
+ const parent = posix.dirname(current);
3655
+ const staging = posix.join(parent, `.incoming-${randomUUID3()}`);
3656
+ const previous = posix.join(parent, ".previous");
3657
+ const script = [
3658
+ "set -eu",
3659
+ `mkdir -p ${shellQuote(staging)}`,
3660
+ `tar -xf - -C ${shellQuote(staging)}`,
3661
+ `if [ -d ${shellQuote(posix.join(current, "node_modules"))} ]; then mv ${shellQuote(posix.join(current, "node_modules"))} ${shellQuote(posix.join(staging, "node_modules"))}; fi`,
3662
+ `if [ -d ${shellQuote(posix.join(current, ".absolutejs"))} ]; then mv ${shellQuote(posix.join(current, ".absolutejs"))} ${shellQuote(posix.join(staging, ".absolutejs"))}; fi`,
3663
+ `rm -rf ${shellQuote(previous)}`,
3664
+ `if [ -d ${shellQuote(current)} ]; then mv ${shellQuote(current)} ${shellQuote(previous)}; fi`,
3665
+ `mv ${shellQuote(staging)} ${shellQuote(current)}`,
3666
+ `rm -rf ${shellQuote(previous)}`
3667
+ ].join("; ");
3668
+ return {
3669
+ remote: [
3670
+ ...absoluteRemoteMacSshBase(project.profile),
3671
+ "/bin/sh -lc",
3672
+ shellQuote(script)
3673
+ ],
3674
+ tar: [
3675
+ "tar",
3676
+ "--exclude=.git",
3677
+ "--exclude=node_modules",
3678
+ "--exclude=build",
3679
+ "--exclude=.absolutejs",
3680
+ "-cf",
3681
+ "-",
3682
+ "-C",
3683
+ project.projectRoot,
3684
+ "."
3685
+ ]
3686
+ };
3687
+ }, syncAbsoluteRemoteMacProject = async (project) => {
3688
+ const commands = absoluteRemoteProjectSyncCommands(project);
3689
+ const archive = Bun.spawn(commands.tar, {
3690
+ stderr: "pipe",
3691
+ stdout: "pipe"
3692
+ });
3693
+ const upload = Bun.spawn(commands.remote, {
3694
+ stderr: "pipe",
3695
+ stdin: archive.stdout,
3696
+ stdout: "pipe"
3697
+ });
3698
+ const [archiveExit, uploadExit, archiveError, uploadError] = await Promise.all([
3699
+ archive.exited,
3700
+ upload.exited,
3701
+ new Response(archive.stderr).text(),
3702
+ new Response(upload.stderr).text()
3703
+ ]);
3704
+ if (archiveExit !== 0 || uploadExit !== 0)
3705
+ throw new Error(`Remote Mac project synchronization failed: ${(archiveError || uploadError).trim()}`);
3706
+ const install = await defaultTransport.capture([
3707
+ ...absoluteRemoteMacSshBase(project.profile),
3708
+ "/bin/sh -lc",
3709
+ shellQuote(`cd ${shellQuote(project.remoteProjectRoot)} && ${shellQuote(project.profile.bunPath)} install --frozen-lockfile`)
3710
+ ]);
3711
+ requireRemoteSuccess(install, "Remote Mac dependency installation");
3712
+ }, consumeLines2 = async (stream, onLine) => {
3713
+ const reader = stream.getReader();
3714
+ const decoder = new TextDecoder;
3715
+ let buffered = "";
3716
+ try {
3717
+ while (true) {
3718
+ const { done, value } = await reader.read();
3719
+ if (done)
3720
+ break;
3721
+ buffered += decoder.decode(value, { stream: true });
3722
+ const lines = buffered.split(/\r?\n/u);
3723
+ buffered = lines.pop() ?? "";
3724
+ lines.forEach(onLine);
3725
+ }
3726
+ buffered += decoder.decode();
3727
+ if (buffered)
3728
+ onLine(buffered);
3729
+ } finally {
3730
+ reader.releaseLock();
3731
+ }
3732
+ }, startAbsoluteRemoteIosDevSession = async (options) => {
3733
+ const startedAt = performance.now();
3734
+ const transport = options.transport ?? defaultTransport;
3735
+ const installAgent = options.installAgent ?? installAbsoluteRemoteMacAgent;
3736
+ const syncProject = options.syncProject ?? syncAbsoluteRemoteMacProject;
3737
+ const agentStartedAt = performance.now();
3738
+ const agent = await installAgent(options.project);
3739
+ const agentDuration = performance.now() - agentStartedAt;
3740
+ const syncStartedAt = performance.now();
3741
+ await syncProject(options.project);
3742
+ const syncDuration = performance.now() - syncStartedAt;
3743
+ const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
3744
+ const remoteCommand = [
3745
+ `cd ${shellQuote(options.project.remoteProjectRoot)}`,
3746
+ "&&",
3747
+ "exec",
3748
+ shellQuote(options.project.profile.bunPath),
3749
+ shellQuote(agent.remotePath),
3750
+ "--port",
3751
+ String(options.port),
3752
+ "--mobile-config",
3753
+ shellQuote(encodedConfig),
3754
+ ...options.https ? ["--https"] : []
3755
+ ].join(" ");
3756
+ const command = [
3757
+ ...absoluteRemoteMacSshBase(options.project.profile),
3758
+ "-o",
3759
+ "ExitOnForwardFailure=yes",
3760
+ "-R",
3761
+ `${options.port}:127.0.0.1:${options.port}`,
3762
+ "/bin/sh -lc",
3763
+ shellQuote(remoteCommand)
3764
+ ];
3765
+ const connectStartedAt = performance.now();
3766
+ const process2 = transport.spawn(command, { signal: options.signal });
3767
+ let state = "syncing";
3768
+ let ready;
3769
+ let fatal;
3770
+ const pending = new Map;
3771
+ let resolveReady;
3772
+ let rejectReady;
3773
+ const readyPromise = new Promise((resolve8, reject) => {
3774
+ resolveReady = resolve8;
3775
+ rejectReady = reject;
3776
+ });
3777
+ const handleEvent = (event) => {
3778
+ if (event.v !== ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION) {
3779
+ rejectReady(new Error("Remote Mac protocol version mismatch."));
3780
+ return;
3781
+ }
3782
+ if (event.type === "log")
3783
+ options.log?.(event.message);
3784
+ if (event.type === "native-log")
3785
+ options.nativeLog?.(event.entry);
3786
+ if (event.type === "state") {
3787
+ ({ state } = event);
3788
+ options.onStateChange?.(state);
3789
+ }
3790
+ if (event.type === "timing")
3791
+ options.onPhaseTiming?.(event);
3792
+ if (event.type === "ready") {
3793
+ ready = event;
3794
+ resolveReady();
3795
+ }
3796
+ if (event.type === "fatal") {
3797
+ fatal = new Error(event.error);
3798
+ rejectReady(fatal);
3799
+ }
3800
+ if (event.type === "response") {
3801
+ const request2 = pending.get(event.id);
3802
+ if (!request2)
3803
+ return;
3804
+ pending.delete(event.id);
3805
+ if (event.ok)
3806
+ request2.resolve(event.result);
3807
+ else
3808
+ request2.reject(new Error(event.error ?? "Remote command failed."));
3809
+ }
3810
+ };
3811
+ const stdoutDone = consumeLines2(process2.stdout, (line) => {
3812
+ if (!line.startsWith(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX))
3813
+ return;
3814
+ try {
3815
+ handleEvent(JSON.parse(line.slice(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX.length)));
3816
+ } catch {
3817
+ options.log?.(`Remote Mac emitted an invalid protocol event.`);
3818
+ }
3819
+ }).catch((error) => {
3820
+ fatal = error instanceof Error ? error : new Error("Failed to read the remote Mac protocol stream.");
3821
+ rejectReady(fatal);
3822
+ });
3823
+ const stderrDone = consumeLines2(process2.stderr, (line) => options.log?.(`[remote] ${line}`)).catch((error) => options.log?.(`[remote] ${error instanceof Error ? error.message : "Failed to read SSH stderr."}`));
3824
+ process2.exited.then(async (exitCode) => {
3825
+ await Promise.all([stdoutDone, stderrDone]);
3826
+ const error = fatal ?? new Error(`Remote Mac connection closed with status ${exitCode}.`);
3827
+ if (!ready)
3828
+ rejectReady(error);
3829
+ pending.forEach(({ reject }) => reject(error));
3830
+ pending.clear();
3831
+ return;
3832
+ });
3833
+ await readyPromise;
3834
+ if (!ready)
3835
+ throw fatal ?? new Error("Remote Mac did not become ready.");
3836
+ const totalDuration = performance.now() - startedAt;
3837
+ let currentReady = {
3838
+ ...ready,
3839
+ timings: {
3840
+ ...ready.timings,
3841
+ "remote-agent": agentDuration,
3842
+ "remote-connect": performance.now() - connectStartedAt,
3843
+ "remote-sync": syncDuration,
3844
+ total: totalDuration
3845
+ }
3846
+ };
3847
+ 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.`);
3848
+ const request = (commandName) => {
3849
+ const id = randomUUID3();
3850
+ const response = new Promise((resolve8, reject) => pending.set(id, { reject, resolve: resolve8 }));
3851
+ process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: 1 })}
3852
+ `);
3853
+ process2.stdin.flush();
3854
+ return response;
3855
+ };
3856
+ let closed = false;
3857
+ const close = async () => {
3858
+ if (closed)
3859
+ return;
3860
+ closed = true;
3861
+ await request("close").catch(() => {
3862
+ return;
3863
+ });
3864
+ process2.stdin.end();
3865
+ await process2.exited.catch(() => {
3866
+ return;
3867
+ });
3868
+ };
3869
+ const makeSession = () => ({
3870
+ close,
3871
+ nativeCacheHit: currentReady.nativeCacheHit,
3872
+ startedSimulator: currentReady.startedSimulator,
3873
+ timings: currentReady.timings,
3874
+ udid: currentReady.udid,
3875
+ rebuild: async () => {
3876
+ const rebuildStartedAt = performance.now();
3877
+ const rebuildSyncStartedAt = performance.now();
3878
+ await syncProject(options.project);
3879
+ const rebuildSyncDuration = performance.now() - rebuildSyncStartedAt;
3880
+ const result = await request("rebuild");
3881
+ currentReady = {
3882
+ ...result,
3883
+ timings: {
3884
+ ...result.timings,
3885
+ "remote-sync": rebuildSyncDuration,
3886
+ total: performance.now() - rebuildStartedAt
3887
+ }
3888
+ };
3889
+ return makeSession();
3890
+ },
3891
+ relaunch: async () => {
3892
+ await request("relaunch");
3893
+ },
3894
+ screenshot: async (destination) => {
3895
+ const result = await request("screenshot");
3896
+ const target = resolvePath(options.project.projectRoot, destination);
3897
+ const targetRelative = relative5(options.project.projectRoot, target);
3898
+ if (targetRelative.startsWith("..") || isAbsolute4(targetRelative))
3899
+ throw new Error("iOS screenshot must remain inside the project.");
3900
+ await mkdir5(dirname6(target), { recursive: true });
3901
+ await writeFile5(target, Buffer.from(result.data, "base64"));
3902
+ return target;
3903
+ },
3904
+ get state() {
3905
+ return state;
3906
+ }
3907
+ });
3908
+ return makeSession();
3909
+ };
3910
+ var init_remoteMacProtocol = __esm(() => {
3911
+ PROFILE_NAME = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/u;
3912
+ SSH_DESTINATION = /^(?:[A-Za-z0-9._-]+@)?[A-Za-z0-9._:-]+$/u;
3913
+ defaultTransport = {
3914
+ capture: localCapture,
3915
+ spawn: (command, options) => Bun.spawn(command, {
3916
+ signal: options.signal,
3917
+ stderr: "pipe",
3918
+ stdin: "pipe",
3919
+ stdout: "pipe"
3920
+ })
3921
+ };
3922
+ });
3923
+
3382
3924
  // src/dev/devCert.ts
3383
3925
  var exports_devCert = {};
3384
3926
  __export(exports_devCert, {
@@ -3396,7 +3938,7 @@ import {
3396
3938
  rmSync
3397
3939
  } from "fs";
3398
3940
  import { platform as platform2 } from "os";
3399
- import { join as join10 } from "path";
3941
+ import { join as join11 } from "path";
3400
3942
  var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[36m[dev]\x1B[0m ${msg}`), devWarn = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[33m[dev]\x1B[0m \x1B[33m${msg}\x1B[0m`), certFilesExist = () => existsSync4(CERT_PATH) && existsSync4(KEY_PATH), isCertExpired = () => {
3401
3943
  try {
3402
3944
  const certPem = readFileSync6(CERT_PATH, "utf-8");
@@ -3608,13 +4150,13 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => c
3608
4150
  const caRoot = mkcertCaRoot();
3609
4151
  if (!caRoot)
3610
4152
  return false;
3611
- const rootCa = join10(caRoot, "rootCA.pem");
4153
+ const rootCa = join11(caRoot, "rootCA.pem");
3612
4154
  if (!existsSync4(rootCa))
3613
4155
  return false;
3614
4156
  const winTemp = windowsTempDir();
3615
4157
  if (!winTemp)
3616
4158
  return false;
3617
- const staged = join10(winTemp, "absolutejs-mkcert-rootCA.crt");
4159
+ const staged = join11(winTemp, "absolutejs-mkcert-rootCA.crt");
3618
4160
  try {
3619
4161
  copyFileSync(rootCa, staged);
3620
4162
  } catch {
@@ -3650,7 +4192,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => c
3650
4192
  devLog("Trusted the local CA in the Windows store \u2014 Chrome/Edge on Windows now accept dev HTTPS");
3651
4193
  } else {
3652
4194
  const caRoot = mkcertCaRoot();
3653
- const hint = caRoot ? toWindowsPath(join10(caRoot, "rootCA.pem")) : null;
4195
+ const hint = caRoot ? toWindowsPath(join11(caRoot, "rootCA.pem")) : null;
3654
4196
  devWarn("Could not auto-trust the local CA on Windows; Windows browsers may warn.");
3655
4197
  if (hint) {
3656
4198
  console.log(` Run in PowerShell: Import-Certificate -FilePath "${hint}" -CertStoreLocation Cert:\\CurrentUser\\Root`);
@@ -3666,9 +4208,9 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => c
3666
4208
  return true;
3667
4209
  };
3668
4210
  var init_devCert = __esm(() => {
3669
- CERT_DIR = join10(process.cwd(), ".absolutejs");
3670
- CERT_PATH = join10(CERT_DIR, "cert.pem");
3671
- KEY_PATH = join10(CERT_DIR, "key.pem");
4211
+ CERT_DIR = join11(process.cwd(), ".absolutejs");
4212
+ CERT_PATH = join11(CERT_DIR, "cert.pem");
4213
+ KEY_PATH = join11(CERT_DIR, "key.pem");
3672
4214
  });
3673
4215
 
3674
4216
  // src/cli/scripts/eslintChunked.ts
@@ -3683,7 +4225,7 @@ __export(exports_eslintChunked, {
3683
4225
  eslintChunked: () => eslintChunked
3684
4226
  });
3685
4227
  import { existsSync as existsSync6 } from "fs";
3686
- import { relative as relative5, resolve as resolve9 } from "path";
4228
+ import { relative as relative6, resolve as resolve9 } from "path";
3687
4229
  var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAULT_REPORT = ".absolutejs/lint-report.txt", CHILD_HEAP_MB = 4096, DJB2_SEED = 5381, DJB2_MULTIPLIER = 33, MS_PER_SECOND = 1000, SUMMARY_RULE_WIDTH = 60, SUMMARY_COUNT_PAD = 5, PORCELAIN_STATUS_WIDTH = 3, RENAME_ARROW = " -> ", ASCII_ESC = 27, LINTABLE_EXTENSIONS, ANSI_COLOR, stripAnsi = (text) => text.replace(ANSI_COLOR, ""), shardOf = (path, shards) => [...path].reduce((accumulator, character) => (Math.imul(accumulator, DJB2_MULTIPLIER) ^ character.charCodeAt(0)) >>> 0, DJB2_SEED) % shards, gitLines = (cmd, cwd) => Bun.spawnSync(cmd, { cwd }).stdout.toString().split(`
3688
4230
  `).map((line) => line.trimEnd()).filter(Boolean), applyChangedBase = (parsed, base) => {
3689
4231
  parsed.changedOnly = true;
@@ -3764,7 +4306,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
3764
4306
  const fingerprint = createEslintCacheFingerprint(cwd);
3765
4307
  for (let shard = 0;shard < parsed.shards; shard++)
3766
4308
  prepareEslintCache({
3767
- cacheLocation: relative5(cwd, resolve9(cwd, `${cachePrefix}${shard}`)),
4309
+ cacheLocation: relative6(cwd, resolve9(cwd, `${cachePrefix}${shard}`)),
3768
4310
  cwd,
3769
4311
  fingerprint
3770
4312
  });
@@ -3890,7 +4432,7 @@ var init_eslintChunked = __esm(() => {
3890
4432
  });
3891
4433
 
3892
4434
  // src/cli/scripts/eslint.ts
3893
- import { createHash as createHash5 } from "crypto";
4435
+ import { createHash as createHash6 } from "crypto";
3894
4436
  import {
3895
4437
  existsSync as existsSync7,
3896
4438
  mkdirSync as mkdirSync5,
@@ -3899,7 +4441,7 @@ import {
3899
4441
  rmSync as rmSync3,
3900
4442
  writeFileSync as writeFileSync5
3901
4443
  } from "fs";
3902
- import { dirname as dirname6, relative as relative6, resolve as resolve10 } from "path";
4444
+ import { dirname as dirname7, relative as relative7, resolve as resolve10 } from "path";
3903
4445
  var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION = "1", CACHE_FINGERPRINT_SUFFIX = ".fingerprint", flagValue = (args, flag) => {
3904
4446
  const assignment = args.find((arg) => arg.startsWith(`${flag}=`));
3905
4447
  if (assignment)
@@ -3983,13 +4525,13 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
3983
4525
  const candidate = resolve10(directory, "node_modules", dependency, "package.json");
3984
4526
  if (existsSync7(candidate))
3985
4527
  return candidate;
3986
- const parent = dirname6(directory);
4528
+ const parent = dirname7(directory);
3987
4529
  if (parent === directory)
3988
4530
  return null;
3989
4531
  directory = parent;
3990
4532
  }
3991
4533
  }, createEslintCacheFingerprint = (cwd = process.cwd()) => {
3992
- const hash = createHash5("sha256");
4534
+ const hash = createHash6("sha256");
3993
4535
  hash.update(`absolute-eslint-cache:${CACHE_CONTRACT_VERSION}\x00`);
3994
4536
  const configPath2 = findEslintConfigPath(cwd);
3995
4537
  for (const dependency of lintDependencyNames(cwd, configPath2).sort()) {
@@ -3999,14 +4541,14 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
3999
4541
  }
4000
4542
  return hash.digest("hex");
4001
4543
  }, createEslintConfigDigest = (cwd = process.cwd()) => {
4002
- const hash = createHash5("sha256");
4544
+ const hash = createHash6("sha256");
4003
4545
  hash.update(`absolute-eslint-config:${CACHE_CONTRACT_VERSION}\x00`);
4004
4546
  const configPath2 = findEslintConfigPath(cwd);
4005
4547
  if (configPath2)
4006
- addFileToFingerprint(hash, configPath2, relative6(cwd, configPath2));
4548
+ addFileToFingerprint(hash, configPath2, relative7(cwd, configPath2));
4007
4549
  return hash.digest("hex");
4008
4550
  }, writeFingerprint = (path, fingerprint) => {
4009
- mkdirSync5(dirname6(path), { recursive: true });
4551
+ mkdirSync5(dirname7(path), { recursive: true });
4010
4552
  const temporary = `${path}.${process.pid}.tmp`;
4011
4553
  writeFileSync5(temporary, `${fingerprint}
4012
4554
  `);
@@ -4371,7 +4913,7 @@ var isRecord4 = (value) => typeof value === "object" && value !== null, getIslan
4371
4913
  var init_islands = () => {};
4372
4914
 
4373
4915
  // src/build/islandEntries.ts
4374
- import { dirname as dirname7, extname, join as join13, relative as relative7, resolve as resolve12 } from "path";
4916
+ import { dirname as dirname8, extname, join as join14, relative as relative8, resolve as resolve12 } from "path";
4375
4917
  import ts from "typescript";
4376
4918
  var frameworks, isRecord5 = (value) => typeof value === "object" && value !== null, resolveRegistryExport = (mod) => {
4377
4919
  if (isRecord5(mod.islandRegistry))
@@ -4383,7 +4925,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
4383
4925
  if (sourcePath.startsWith("file://")) {
4384
4926
  return new URL(sourcePath).pathname;
4385
4927
  }
4386
- return resolve12(dirname7(registryPath), sourcePath);
4928
+ return resolve12(dirname8(registryPath), sourcePath);
4387
4929
  }, getObjectPropertyName = (name) => {
4388
4930
  if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
4389
4931
  return name.text;
@@ -4863,7 +5405,7 @@ var init_buildMetadata = __esm(() => {
4863
5405
  });
4864
5406
 
4865
5407
  // src/mobile/releaseArtifact.ts
4866
- import { createHash as createHash6 } from "crypto";
5408
+ import { createHash as createHash7 } from "crypto";
4867
5409
  var ABSOLUTE_MOBILE_COMPATIBILITY_FORMAT = 1, ABSOLUTE_MOBILE_RETAINED_GENERATIONS = 3, SHA_256 = "sha256", RELEASE_ID_PREFIX = "amc_", MODULE_SEGMENT_PARENT = "..", EXPORT_NAME_PATTERN, frameworks3, isCanonicalRecord = (value) => {
4868
5410
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
4869
5411
  return false;
@@ -4900,7 +5442,7 @@ var ABSOLUTE_MOBILE_COMPATIBILITY_FORMAT = 1, ABSOLUTE_MOBILE_RETAINED_GENERATIO
4900
5442
  return normalizeCanonicalRecord(value, ancestors);
4901
5443
  }
4902
5444
  throw new TypeError("Compatibility metadata must contain only finite JSON values.");
4903
- }, canonicalJson = (value) => JSON.stringify(normalizeCanonicalValue(value, new Set)), hashCanonicalValue = (value) => createHash6(SHA_256).update(canonicalJson(value)).digest("hex"), requireNonEmpty = (value, field) => {
5445
+ }, canonicalJson = (value) => JSON.stringify(normalizeCanonicalValue(value, new Set)), hashCanonicalValue = (value) => createHash7(SHA_256).update(canonicalJson(value)).digest("hex"), requireNonEmpty = (value, field) => {
4904
5446
  if (!value.trim()) {
4905
5447
  throw new TypeError(`${field} must not be empty.`);
4906
5448
  }
@@ -5049,24 +5591,24 @@ var init_releaseArtifact = __esm(() => {
5049
5591
  });
5050
5592
 
5051
5593
  // src/mobile/buildRelease.ts
5052
- import { createHash as createHash7 } from "crypto";
5053
- import { readFile as readFile6 } from "fs/promises";
5054
- import { join as join14, relative as relative8, resolve as resolve13 } from "path";
5055
- var sha256 = (bytes) => createHash7("sha256").update(bytes).digest("hex"), readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]), resolveAssetPath = (buildDirectory, assetPath) => {
5594
+ import { createHash as createHash8 } from "crypto";
5595
+ import { readFile as readFile7 } from "fs/promises";
5596
+ import { join as join15, relative as relative9, resolve as resolve13 } from "path";
5597
+ var sha256 = (bytes) => createHash8("sha256").update(bytes).digest("hex"), readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]), resolveAssetPath = (buildDirectory, assetPath) => {
5056
5598
  const resolvedBuildDirectory = resolve13(buildDirectory);
5057
5599
  const resolvedAsset = resolve13(assetPath);
5058
5600
  if (resolvedAsset.startsWith(`${resolvedBuildDirectory}/`)) {
5059
5601
  return resolvedAsset;
5060
5602
  }
5061
- return join14(buildDirectory, assetPath.replace(/^\/+/, ""));
5603
+ return join15(buildDirectory, assetPath.replace(/^\/+/, ""));
5062
5604
  }, pageFor = async (metadata, manifest, buildDirectory) => {
5063
5605
  const assetPath = manifest[metadata.bundleKey];
5064
5606
  if (!assetPath) {
5065
5607
  throw new TypeError(`Mobile page ${metadata.pageId} references missing manifest asset ${metadata.bundleKey}.`);
5066
5608
  }
5067
5609
  const resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
5068
- const bytes = await readFile6(resolvedAssetPath);
5069
- const bundlePath = `/${relative8(resolve13(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
5610
+ const bytes = await readFile7(resolvedAssetPath);
5611
+ const bundlePath = `/${relative9(resolve13(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
5070
5612
  return {
5071
5613
  bundleHash: sha256(bytes),
5072
5614
  bundlePath,
@@ -5078,7 +5620,7 @@ var sha256 = (bytes) => createHash7("sha256").update(bytes).digest("hex"), readP
5078
5620
  }, buildAbsoluteMobileCompatibilityRelease = async (options) => {
5079
5621
  const [captured, producerBytes] = await Promise.all([
5080
5622
  captureAbsoluteMobileRouteGraph(options.app),
5081
- readFile6(options.producerPath)
5623
+ readFile7(options.producerPath)
5082
5624
  ]);
5083
5625
  if (captured.length === 0) {
5084
5626
  throw new TypeError("No instrumented AbsoluteJS mobile page routes were found in the finalized Elysia route graph.");
@@ -5246,17 +5788,17 @@ var init_transport = __esm(() => {
5246
5788
  // src/mobile/capacitorBundle.ts
5247
5789
  import {
5248
5790
  copyFile as copyFile4,
5249
- mkdir as mkdir6,
5791
+ mkdir as mkdir7,
5250
5792
  mkdtemp as mkdtemp3,
5251
- readFile as readFile7,
5252
- rename as rename5,
5793
+ readFile as readFile8,
5794
+ rename as rename6,
5253
5795
  rm as rm5,
5254
- writeFile as writeFile5
5796
+ writeFile as writeFile6
5255
5797
  } from "fs/promises";
5256
5798
  import { existsSync as existsSync9 } from "fs";
5257
- import { basename as basename6, dirname as dirname8, extname as extname3, join as join15, resolve as resolve14 } from "path";
5799
+ import { basename as basename6, dirname as dirname9, extname as extname3, join as join16, resolve as resolve14 } from "path";
5258
5800
  var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-mobile-bootstrap.js", INDEX_FILE = "index.html", CLIENT_IMPORT_PATTERN, errorHasCode = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, shellBootstrapModule = () => {
5259
- const candidate = ["js", "ts"].map((extension) => join15(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync9);
5801
+ const candidate = ["js", "ts"].map((extension) => join16(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync9);
5260
5802
  if (candidate)
5261
5803
  return candidate;
5262
5804
  throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
@@ -5282,8 +5824,8 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
5282
5824
  return asset;
5283
5825
  }, buildShellBootstrap = async (staging) => {
5284
5826
  const modulePath = shellBootstrapModule();
5285
- const entryPath = join15(staging, ".absolute-mobile-entry.ts");
5286
- await writeFile5(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
5827
+ const entryPath = join16(staging, ".absolute-mobile-entry.ts");
5828
+ await writeFile6(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
5287
5829
  void startAbsoluteMobileShell();
5288
5830
  `);
5289
5831
  const build = await Bun.build({
@@ -5295,7 +5837,7 @@ void startAbsoluteMobileShell();
5295
5837
  if (!build.success || build.outputs.length !== 1) {
5296
5838
  throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
5297
5839
  }
5298
- await rename5(build.outputs[0]?.path ?? "", join15(staging, BOOTSTRAP_FILE));
5840
+ await rename6(build.outputs[0]?.path ?? "", join16(staging, BOOTSTRAP_FILE));
5299
5841
  await rm5(entryPath, { force: true });
5300
5842
  }, removePreviousBundle = async (backup, moved) => {
5301
5843
  if (!moved)
@@ -5304,19 +5846,19 @@ void startAbsoluteMobileShell();
5304
5846
  }, restorePreviousBundle = async (backup, destination, moved) => {
5305
5847
  if (!moved)
5306
5848
  return;
5307
- await rename5(backup, destination);
5849
+ await rename6(backup, destination);
5308
5850
  }, installBundle = async (staging, destination) => {
5309
5851
  const backup = `${destination}.previous-${crypto.randomUUID()}`;
5310
5852
  let movedPrevious = false;
5311
5853
  try {
5312
- await rename5(destination, backup);
5854
+ await rename6(destination, backup);
5313
5855
  movedPrevious = true;
5314
5856
  } catch (error) {
5315
5857
  if (!errorHasCode(error, "ENOENT"))
5316
5858
  throw error;
5317
5859
  }
5318
5860
  try {
5319
- await rename5(staging, destination);
5861
+ await rename6(staging, destination);
5320
5862
  await removePreviousBundle(backup, movedPrevious);
5321
5863
  } catch (error) {
5322
5864
  await restorePreviousBundle(backup, destination, movedPrevious);
@@ -5329,11 +5871,11 @@ void startAbsoluteMobileShell();
5329
5871
  const extension = extname3(page.bundlePath) || ".js";
5330
5872
  const localBundlePath = `./pages/${page.bundleHash}${extension}`;
5331
5873
  const source = sourceAssetPath(buildDirectory, page.bundlePath);
5332
- await copyFile4(source, join15(staging, localBundlePath));
5874
+ await copyFile4(source, join16(staging, localBundlePath));
5333
5875
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
5334
5876
  return { ...page, localBundlePath };
5335
5877
  }, absoluteClientImports = async (sourcePath) => {
5336
- const source = await readFile7(sourcePath, "utf8");
5878
+ const source = await readFile8(sourcePath, "utf8");
5337
5879
  return [...source.matchAll(CLIENT_IMPORT_PATTERN)].flatMap((match) => {
5338
5880
  const [specifier] = match.slice(1);
5339
5881
  return specifier ? [specifier.split(/[?#]/u, 1)[0] ?? specifier] : [];
@@ -5343,8 +5885,8 @@ void startAbsoluteMobileShell();
5343
5885
  return;
5344
5886
  copied.add(specifier);
5345
5887
  const source = sourceAssetPath(buildDirectory, specifier);
5346
- const destination = join15(staging, specifier.replace(/^\/+/, ""));
5347
- await mkdir6(dirname8(destination), { recursive: true });
5888
+ const destination = join16(staging, specifier.replace(/^\/+/, ""));
5889
+ await mkdir7(dirname9(destination), { recursive: true });
5348
5890
  await copyFile4(source, destination);
5349
5891
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
5350
5892
  }, copyAbsoluteClientDependencies = async (sourcePath, buildDirectory, staging, copied) => {
@@ -5355,11 +5897,11 @@ void startAbsoluteMobileShell();
5355
5897
  throw new TypeError(`mobile.entry ${options.config.entry} is not a captured mobile page route.`);
5356
5898
  }
5357
5899
  const destination = options.config.bundleDirectory;
5358
- await mkdir6(dirname8(destination), { recursive: true });
5359
- const staging = await mkdtemp3(join15(dirname8(destination), `.${basename6(destination)}.stage-`));
5900
+ await mkdir7(dirname9(destination), { recursive: true });
5901
+ const staging = await mkdtemp3(join16(dirname9(destination), `.${basename6(destination)}.stage-`));
5360
5902
  try {
5361
- const pageDirectory = join15(staging, "pages");
5362
- await mkdir6(pageDirectory, { recursive: true });
5903
+ const pageDirectory = join16(staging, "pages");
5904
+ await mkdir7(pageDirectory, { recursive: true });
5363
5905
  const copiedDependencies = new Set;
5364
5906
  const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
5365
5907
  const manifest = {
@@ -5376,9 +5918,9 @@ void startAbsoluteMobileShell();
5376
5918
  runtime: options.artifact.runtime
5377
5919
  };
5378
5920
  await Promise.all([
5379
- writeFile5(join15(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
5921
+ writeFile6(join16(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
5380
5922
  `),
5381
- writeFile5(join15(staging, INDEX_FILE), indexHtml(options.config.appName)),
5923
+ writeFile6(join16(staging, INDEX_FILE), indexHtml(options.config.appName)),
5382
5924
  buildShellBootstrap(staging)
5383
5925
  ]);
5384
5926
  await installBundle(staging, destination);
@@ -5395,10 +5937,10 @@ var init_capacitorBundle = __esm(() => {
5395
5937
  });
5396
5938
 
5397
5939
  // src/mobile/artifactStore.ts
5398
- import { createHash as createHash8 } from "crypto";
5940
+ import { createHash as createHash9 } from "crypto";
5399
5941
  var DEFAULT_MAX_PRODUCER_BYTES = 134217728, SHA_2562 = "sha256", hashBlob = async (blob) => {
5400
5942
  const bytes = new Uint8Array(await blob.arrayBuffer());
5401
- return createHash8(SHA_2562).update(bytes).digest("hex");
5943
+ return createHash9(SHA_2562).update(bytes).digest("hex");
5402
5944
  }, verifyAbsoluteMobileCompatibilityProducer = async (release, maxProducerBytes = DEFAULT_MAX_PRODUCER_BYTES) => {
5403
5945
  const { artifact, producer } = release;
5404
5946
  if (producer.size !== artifact.producer.bytes || producer.size > maxProducerBytes) {
@@ -5414,23 +5956,23 @@ var init_artifactStore = __esm(() => {
5414
5956
  });
5415
5957
 
5416
5958
  // src/mobile/materializedBundle.ts
5417
- import { createHash as createHash9 } from "crypto";
5959
+ import { createHash as createHash10 } from "crypto";
5418
5960
  import {
5419
5961
  access as access6,
5420
- mkdir as mkdir7,
5962
+ mkdir as mkdir8,
5421
5963
  mkdtemp as mkdtemp4,
5422
- readFile as readFile8,
5423
- rename as rename6,
5964
+ readFile as readFile9,
5965
+ rename as rename7,
5424
5966
  rm as rm6,
5425
- writeFile as writeFile6
5967
+ writeFile as writeFile7
5426
5968
  } from "fs/promises";
5427
- import { dirname as dirname9, join as join16, resolve as resolvePath } from "path";
5969
+ import { dirname as dirname10, join as join17, resolve as resolvePath2 } from "path";
5428
5970
  var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE = "artifact.json", BUNDLE_ID_PATTERN, isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, bundleIdFor = (currentReleaseId, releases) => {
5429
5971
  const identity = JSON.stringify({
5430
5972
  currentReleaseId,
5431
5973
  releases: releases.map(({ releaseId }) => releaseId)
5432
5974
  });
5433
- return `amb_${createHash9("sha256").update(identity).digest("hex")}`;
5975
+ return `amb_${createHash10("sha256").update(identity).digest("hex")}`;
5434
5976
  }, parseBundleIndex = (value) => {
5435
5977
  if (!isRecord7(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
5436
5978
  throw new TypeError("Invalid materialized mobile compatibility bundle.");
@@ -5454,16 +5996,16 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
5454
5996
  releases
5455
5997
  };
5456
5998
  }, writeRelease = async (root, release) => {
5457
- const directory = join16(root, release.artifact.releaseId);
5458
- const producerPath = join16(directory, release.artifact.producer.module);
5459
- await mkdir7(dirname9(producerPath), { recursive: true });
5999
+ const directory = join17(root, release.artifact.releaseId);
6000
+ const producerPath = join17(directory, release.artifact.producer.module);
6001
+ await mkdir8(dirname10(producerPath), { recursive: true });
5460
6002
  await Promise.all([
5461
- writeFile6(join16(directory, ARTIFACT_FILE), `${JSON.stringify(release.artifact, null, "\t")}
6003
+ writeFile7(join17(directory, ARTIFACT_FILE), `${JSON.stringify(release.artifact, null, "\t")}
5462
6004
  `),
5463
- writeFile6(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
6005
+ writeFile7(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
5464
6006
  ]);
5465
6007
  }, installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
5466
- const destination = join16(bundlesRoot, bundleId);
6008
+ const destination = join17(bundlesRoot, bundleId);
5467
6009
  try {
5468
6010
  await access6(destination);
5469
6011
  return destination;
@@ -5471,10 +6013,10 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
5471
6013
  if (!errorHasCode2(error, "ENOENT"))
5472
6014
  throw error;
5473
6015
  }
5474
- const staging = await mkdtemp4(join16(bundlesRoot, ".stage-"));
6016
+ const staging = await mkdtemp4(join17(bundlesRoot, ".stage-"));
5475
6017
  try {
5476
6018
  await Promise.all(releases.map((release) => writeRelease(staging, release)));
5477
- await rename6(staging, destination);
6019
+ await rename7(staging, destination);
5478
6020
  } catch (error) {
5479
6021
  await rm6(staging, { force: true, recursive: true });
5480
6022
  if (errorHasCode2(error, "EEXIST") || errorHasCode2(error, "ENOTEMPTY")) {
@@ -5499,9 +6041,9 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
5499
6041
  }
5500
6042
  return release;
5501
6043
  });
5502
- const root = resolvePath(input.root);
5503
- const bundlesRoot = join16(root, BUNDLES_DIRECTORY);
5504
- await mkdir7(bundlesRoot, { recursive: true });
6044
+ const root = resolvePath2(input.root);
6045
+ const bundlesRoot = join17(root, BUNDLES_DIRECTORY);
6046
+ await mkdir8(bundlesRoot, { recursive: true });
5505
6047
  const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
5506
6048
  await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
5507
6049
  const index = {
@@ -5510,21 +6052,21 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
5510
6052
  format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
5511
6053
  releases: artifacts
5512
6054
  };
5513
- const pointerPath = join16(root, CURRENT_BUNDLE_FILE);
5514
- const temporaryPointerPath = join16(root, `.current-${crypto.randomUUID()}.json`);
5515
- await writeFile6(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
6055
+ const pointerPath = join17(root, CURRENT_BUNDLE_FILE);
6056
+ const temporaryPointerPath = join17(root, `.current-${crypto.randomUUID()}.json`);
6057
+ await writeFile7(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
5516
6058
  `, { flag: "wx" });
5517
- await rename6(temporaryPointerPath, pointerPath);
6059
+ await rename7(temporaryPointerPath, pointerPath);
5518
6060
  return index;
5519
6061
  }, readAbsoluteMobileMaterializedReleases = async (root) => {
5520
- const resolvedRoot = resolvePath(root);
6062
+ const resolvedRoot = resolvePath2(root);
5521
6063
  try {
5522
- const serialized = await readFile8(join16(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
6064
+ const serialized = await readFile9(join17(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
5523
6065
  const parsed = JSON.parse(serialized);
5524
6066
  const index = parseBundleIndex(parsed);
5525
- const bundleRoot = join16(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
6067
+ const bundleRoot = join17(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
5526
6068
  return Promise.all(index.releases.map(async (artifact) => {
5527
- const producer = Bun.file(join16(bundleRoot, artifact.releaseId, artifact.producer.module));
6069
+ const producer = Bun.file(join17(bundleRoot, artifact.releaseId, artifact.producer.module));
5528
6070
  await verifyAbsoluteMobileCompatibilityProducer({
5529
6071
  artifact,
5530
6072
  producer
@@ -5544,8 +6086,8 @@ var init_materializedBundle = __esm(() => {
5544
6086
  });
5545
6087
 
5546
6088
  // src/mobile/buildPipeline.ts
5547
- import { readFile as readFile9 } from "fs/promises";
5548
- import { join as join17, resolve as resolve15 } from "path";
6089
+ import { readFile as readFile10 } from "fs/promises";
6090
+ import { join as join18, resolve as resolve15 } from "path";
5549
6091
  import { pathToFileURL } from "url";
5550
6092
  var isElysiaApp = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "compile") === "function" && Array.isArray(Reflect.get(value, "routes")), isStringRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string"), serverExportName = (loaded, app) => {
5551
6093
  if (loaded.server === app)
@@ -5577,9 +6119,9 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
5577
6119
  }, finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5578
6120
  const buildDirectory = resolve15(options.buildDirectory);
5579
6121
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
5580
- const root = join17(buildDirectory, ".absolutejs", "mobile-compatibility");
6122
+ const root = join18(buildDirectory, ".absolutejs", "mobile-compatibility");
5581
6123
  const [manifestSource, previous] = await Promise.all([
5582
- readFile9(join17(buildDirectory, "manifest.json"), "utf8"),
6124
+ readFile10(join18(buildDirectory, "manifest.json"), "utf8"),
5583
6125
  readAbsoluteMobileMaterializedReleases(root)
5584
6126
  ]);
5585
6127
  const manifest = JSON.parse(manifestSource);
@@ -5632,9 +6174,9 @@ var init_buildPipeline = __esm(() => {
5632
6174
 
5633
6175
  // src/mobile/routeMetadataTransform.ts
5634
6176
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
5635
- import { dirname as dirname10, extname as extname4, relative as relative9, resolve as resolve16 } from "path";
6177
+ import { dirname as dirname11, extname as extname4, relative as relative10, resolve as resolve16 } from "path";
5636
6178
  import ts4 from "typescript";
5637
- var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLER = "handleReactPageRequest", posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts4.findConfigFile(dirname10(entry), existsSync10, "tsconfig.json") ?? ts4.findConfigFile(projectRoot, existsSync10, "tsconfig.json"), createProgram = (entry, projectRoot) => {
6179
+ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLER = "handleReactPageRequest", posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts4.findConfigFile(dirname11(entry), existsSync10, "tsconfig.json") ?? ts4.findConfigFile(projectRoot, existsSync10, "tsconfig.json"), createProgram = (entry, projectRoot) => {
5638
6180
  const configPath2 = findTsconfig(entry, projectRoot);
5639
6181
  if (!configPath2) {
5640
6182
  return ts4.createProgram([entry], {
@@ -5645,7 +6187,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLER = "handleReactPageRequest", posix
5645
6187
  target: ts4.ScriptTarget.ESNext
5646
6188
  });
5647
6189
  }
5648
- const parsed = ts4.parseJsonConfigFileContent(ts4.readConfigFile(configPath2, (path) => readFileSync10(path, "utf8")).config, ts4.sys, dirname10(configPath2));
6190
+ const parsed = ts4.parseJsonConfigFileContent(ts4.readConfigFile(configPath2, (path) => readFileSync10(path, "utf8")).config, ts4.sys, dirname11(configPath2));
5649
6191
  if (!parsed.fileNames.includes(entry))
5650
6192
  parsed.fileNames.push(entry);
5651
6193
  return ts4.createProgram(parsed.fileNames, parsed.options);
@@ -5746,7 +6288,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLER = "handleReactPageRequest", posix
5746
6288
  const declaration = symbol?.declarations?.[0];
5747
6289
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
5748
6290
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
5749
- const source = posixPath(relative9(projectRoot, file));
6291
+ const source = posixPath(relative10(projectRoot, file));
5750
6292
  return `${source}#${exportedName}`;
5751
6293
  }, resolveAlias = (symbol, checker) => {
5752
6294
  if (!(symbol.flags & ts4.SymbolFlags.Alias))
@@ -5950,7 +6492,7 @@ var init_routeMetadataTransform = __esm(() => {
5950
6492
  });
5951
6493
 
5952
6494
  // src/cli/elysiaOpenApiTypeboxPlugin.ts
5953
- import { dirname as dirname11, resolve as resolve17 } from "path";
6495
+ import { dirname as dirname12, resolve as resolve17 } from "path";
5954
6496
  var OPENAPI_TYPEBOX_PREFIX = "../node_modules/typebox/", OPENAPI_DISTRIBUTION_SEGMENT = "/@elysia/openapi/dist/", createElysiaOpenApiTypeboxPlugin = () => ({
5955
6497
  name: "absolute-elysia-openapi-typebox",
5956
6498
  setup(build) {
@@ -5960,9 +6502,9 @@ var OPENAPI_TYPEBOX_PREFIX = "../node_modules/typebox/", OPENAPI_DISTRIBUTION_SE
5960
6502
  return;
5961
6503
  }
5962
6504
  const relativePath = args.path.slice(OPENAPI_TYPEBOX_PREFIX.length);
5963
- const typeboxEntry = Bun.resolveSync("typebox", dirname11(args.importer));
6505
+ const typeboxEntry = Bun.resolveSync("typebox", dirname12(args.importer));
5964
6506
  return {
5965
- path: resolve17(dirname11(typeboxEntry), "..", relativePath)
6507
+ path: resolve17(dirname12(typeboxEntry), "..", relativePath)
5966
6508
  };
5967
6509
  });
5968
6510
  }
@@ -6023,7 +6565,7 @@ __export(exports_prerender, {
6023
6565
  PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER
6024
6566
  });
6025
6567
  import { mkdirSync as mkdirSync6, readFileSync as readFileSync11 } from "fs";
6026
- import { join as join18 } from "path";
6568
+ import { join as join19 } from "path";
6027
6569
  var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_TIMEOUT_MS = 30000, DEFAULT_FETCH_TIMEOUT_MS = 1e4, PRERENDER_BYPASS_HEADER = "X-Absolute-Prerender-Bypass", routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1).replace(/\//g, "-")}.html`, writeTimestamp = async (htmlPath) => {
6028
6570
  const metaPath = htmlPath.replace(/\.html$/, ".meta");
6029
6571
  await Bun.write(metaPath, String(Date.now()));
@@ -6093,7 +6635,7 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
6093
6635
  if (!isCompleteHtml(html))
6094
6636
  return false;
6095
6637
  const fileName = routeToFilename(route);
6096
- const filePath = join18(prerenderDir, fileName);
6638
+ const filePath = join19(prerenderDir, fileName);
6097
6639
  await Bun.write(filePath, html);
6098
6640
  await writeTimestamp(filePath);
6099
6641
  return true;
@@ -6123,13 +6665,13 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
6123
6665
  return;
6124
6666
  }
6125
6667
  const fileName = routeToFilename(route);
6126
- const filePath = join18(prerenderDir, fileName);
6668
+ const filePath = join19(prerenderDir, fileName);
6127
6669
  await Bun.write(filePath, html);
6128
6670
  await writeTimestamp(filePath);
6129
6671
  result.routes.set(route, filePath);
6130
6672
  log?.(` Pre-rendered ${route} \u2192 ${fileName} (${html.length} bytes)`);
6131
6673
  }, prerender = async (port, outDir, staticConfig, log) => {
6132
- const prerenderDir = join18(outDir, "_prerendered");
6674
+ const prerenderDir = join19(outDir, "_prerendered");
6133
6675
  mkdirSync6(prerenderDir, { recursive: true });
6134
6676
  const baseUrl = `http://localhost:${port}`;
6135
6677
  let routes;
@@ -6565,7 +7107,7 @@ var init_nativeRewrite = __esm(() => {
6565
7107
 
6566
7108
  // src/build/rewriteImportsPlugin.ts
6567
7109
  import { readdir as readdir3 } from "fs/promises";
6568
- import { join as join19 } from "path";
7110
+ import { join as join20 } from "path";
6569
7111
  var escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), jsRewriteImports = (content, replacements) => {
6570
7112
  let result = content;
6571
7113
  for (const [specifier, webPath] of replacements) {
@@ -6644,7 +7186,7 @@ ${content}`;
6644
7186
  const entries = await readdir3(dir);
6645
7187
  for (const entry of entries) {
6646
7188
  if (entry.endsWith(".js"))
6647
- allFiles.push(join19(dir, entry));
7189
+ allFiles.push(join20(dir, entry));
6648
7190
  }
6649
7191
  } catch {}
6650
7192
  }
@@ -6720,7 +7262,7 @@ var init_rewriteImports = __esm(() => {
6720
7262
  // src/cli/scripts/start.ts
6721
7263
  var {env: env2 } = globalThis.Bun;
6722
7264
  import { existsSync as existsSync11, readFileSync as readFileSync12, rmSync as rmSync4 } from "fs";
6723
- import { basename as basename7, join as join20, resolve as resolve19 } from "path";
7265
+ import { basename as basename7, join as join21, resolve as resolve19 } from "path";
6724
7266
  var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, resolvePackageVersion = (candidates) => {
6725
7267
  for (const candidate of candidates) {
6726
7268
  const version2 = readPackageVersion2(candidate);
@@ -6950,7 +7492,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
6950
7492
  if (!build)
6951
7493
  throw new Error("Could not locate build module");
6952
7494
  await build(buildConfig);
6953
- rmSync4(join20(resolvedOutdir, "_prerendered"), {
7495
+ rmSync4(join21(resolvedOutdir, "_prerendered"), {
6954
7496
  force: true,
6955
7497
  recursive: true
6956
7498
  });
@@ -7251,16 +7793,16 @@ __export(exports_build, {
7251
7793
  build: () => build
7252
7794
  });
7253
7795
  import { existsSync as existsSync13, readdirSync as readdirSync3, readFileSync as readFileSync14 } from "fs";
7254
- import { join as join21, resolve as resolve21 } from "path";
7796
+ import { join as join22, resolve as resolve21 } from "path";
7255
7797
  var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, printProfile = (buildDir) => {
7256
- const traceDir = join21(buildDir, ".absolute-trace");
7798
+ const traceDir = join22(buildDir, ".absolute-trace");
7257
7799
  if (!existsSync13(traceDir))
7258
7800
  return;
7259
7801
  const files = readdirSync3(traceDir).filter((file) => file.endsWith(".json")).sort();
7260
7802
  const latest = files[files.length - 1];
7261
7803
  if (latest === undefined)
7262
7804
  return;
7263
- const trace = JSON.parse(readFileSync14(join21(traceDir, latest), "utf-8"));
7805
+ const trace = JSON.parse(readFileSync14(join22(traceDir, latest), "utf-8"));
7264
7806
  const events = Array.isArray(trace.events) ? trace.events : [];
7265
7807
  if (events.length === 0)
7266
7808
  return;
@@ -7346,7 +7888,7 @@ __export(exports_lintProof, {
7346
7888
  createLintProof: () => createLintProof
7347
7889
  });
7348
7890
  import {
7349
- createHash as createHash10,
7891
+ createHash as createHash11,
7350
7892
  createPrivateKey,
7351
7893
  createPublicKey,
7352
7894
  sign,
@@ -7364,7 +7906,7 @@ import {
7364
7906
  writeFileSync as writeFileSync7
7365
7907
  } from "fs";
7366
7908
  import { tmpdir as tmpdir3 } from "os";
7367
- import { delimiter, dirname as dirname12, relative as relative10, resolve as resolve22 } from "path";
7909
+ import { delimiter, dirname as dirname13, relative as relative11, resolve as resolve22 } from "path";
7368
7910
  var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSION = 2, FLAG_NOT_FOUND = -1, CHUNKED_FLAG = "--chunked", TSCONFIG_PATTERN, ABSOLUTE_BINARY, runGit = (args, options) => {
7369
7911
  const proc = Bun.spawnSync(["git", ...args], {
7370
7912
  cwd: options.cwd,
@@ -7378,7 +7920,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7378
7920
  }
7379
7921
  return proc.stdout.toString().trim();
7380
7922
  }, gitRoot = (cwd) => resolve22(runGit(["rev-parse", "--show-toplevel"], { cwd })), isInside3 = (parent, candidate) => {
7381
- const path = relative10(parent, candidate);
7923
+ const path = relative11(parent, candidate);
7382
7924
  return path === "" || !path.startsWith("../") && path !== "..";
7383
7925
  }, attestationPayload = (proof) => Buffer.from([
7384
7926
  "absolute-lint-proof-attestation:1",
@@ -7389,7 +7931,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7389
7931
  lintFingerprint: proof.lintFingerprint,
7390
7932
  sourceTree: proof.sourceTree
7391
7933
  })
7392
- ].join("\x00")), publicKeyId = (key) => createHash10("sha256").update(key.export({ format: "der", type: "spki" })).digest("hex"), readEd25519PrivateKey = (cwd, location) => {
7934
+ ].join("\x00")), publicKeyId = (key) => createHash11("sha256").update(key.export({ format: "der", type: "spki" })).digest("hex"), readEd25519PrivateKey = (cwd, location) => {
7393
7935
  const path = resolve22(cwd, location);
7394
7936
  if (isInside3(realpathSync(gitRoot(cwd)), realpathSync(path))) {
7395
7937
  throw new Error("lint proof signing key must live outside the Git working tree");
@@ -7428,7 +7970,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7428
7970
  return null;
7429
7971
  const auxiliary = gitVisibleFiles(root).filter((file) => TSCONFIG_PATTERN.test(file));
7430
7972
  const configPath2 = findEslintConfigPath(root);
7431
- const configRelative = configPath2 === null ? null : relative10(root, configPath2).replaceAll("\\", "/");
7973
+ const configRelative = configPath2 === null ? null : relative11(root, configPath2).replaceAll("\\", "/");
7432
7974
  return [
7433
7975
  ...new Set([
7434
7976
  ...resolveLintTargets(args, root),
@@ -7439,7 +7981,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7439
7981
  }, createLintSourceTree = (cwd = process.cwd(), proofLocation = DEFAULT_PROOF_LOCATION, command = []) => {
7440
7982
  const root = gitRoot(cwd);
7441
7983
  const proofPath = resolve22(cwd, proofLocation);
7442
- const proofRelative = relative10(root, proofPath).replaceAll("\\", "/");
7984
+ const proofRelative = relative11(root, proofPath).replaceAll("\\", "/");
7443
7985
  if (proofRelative === ".." || proofRelative.startsWith("../") || proofRelative === "") {
7444
7986
  throw new Error("lint proof must live inside the Git working tree");
7445
7987
  }
@@ -7483,7 +8025,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7483
8025
  } finally {
7484
8026
  rmSync5(temporaryDirectory, { force: true, recursive: true });
7485
8027
  }
7486
- }, proofFingerprint = (cwd) => createHash10("sha256").update(`absolute-lint-proof:${PROOF_CONTRACT_VERSION}\x00`).update(createEslintCacheFingerprint(cwd)).update("\x00").update(createEslintConfigDigest(cwd)).digest("hex"), createLintProof = (command, options = {}) => {
8028
+ }, proofFingerprint = (cwd) => createHash11("sha256").update(`absolute-lint-proof:${PROOF_CONTRACT_VERSION}\x00`).update(createEslintCacheFingerprint(cwd)).update("\x00").update(createEslintConfigDigest(cwd)).digest("hex"), createLintProof = (command, options = {}) => {
7487
8029
  const cwd = options.cwd ?? process.cwd();
7488
8030
  const proofLocation = options.proofLocation ?? DEFAULT_PROOF_LOCATION;
7489
8031
  return {
@@ -7508,7 +8050,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
7508
8050
  signature: sign(null, attestationPayload(proof), privateKey).toString("base64")
7509
8051
  };
7510
8052
  }
7511
- mkdirSync8(dirname12(path), { recursive: true });
8053
+ mkdirSync8(dirname13(path), { recursive: true });
7512
8054
  writeFileSync7(temporary, `${JSON.stringify(proof, null, 2)}
7513
8055
  `);
7514
8056
  renameSync2(temporary, path);
@@ -7731,7 +8273,7 @@ __export(exports_ls, {
7731
8273
  runLs: () => runLs
7732
8274
  });
7733
8275
  import { existsSync as existsSync16, readFileSync as readFileSync16, statSync } from "fs";
7734
- import { basename as basename9, extname as extname5, join as join22, relative as relative11 } from "path";
8276
+ import { basename as basename9, extname as extname5, join as join23, relative as relative12 } from "path";
7735
8277
  var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELDS, readStringField = (source, key) => {
7736
8278
  const value = Reflect.get(source, key);
7737
8279
  return typeof value === "string" ? value : undefined;
@@ -7746,20 +8288,20 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
7746
8288
  } catch {
7747
8289
  return null;
7748
8290
  }
7749
- }, relativeOrSelf = (target) => relative11(process.cwd(), target) || target, configCandidates = (raw) => isWorkspaceConfig(raw) ? Object.values(raw).map((service) => ({
8291
+ }, relativeOrSelf = (target) => relative12(process.cwd(), target) || target, configCandidates = (raw) => isWorkspaceConfig(raw) ? Object.values(raw).map((service) => ({
7750
8292
  baseDir: readStringField(service, "cwd") ?? ".",
7751
8293
  source: service
7752
8294
  })) : [{ baseDir: ".", source: raw }], specsFor = (source, baseDir) => FRAMEWORK_FIELDS.flatMap((framework) => {
7753
8295
  const dir = readStringField(source, framework.field);
7754
8296
  return dir === undefined ? [] : [
7755
8297
  {
7756
- dir: join22(baseDir, dir),
8298
+ dir: join23(baseDir, dir),
7757
8299
  label: framework.label,
7758
8300
  pattern: framework.pattern
7759
8301
  }
7760
8302
  ];
7761
8303
  }), scanFramework = async (spec) => {
7762
- const { pageFiles } = await scanConventions(join22(spec.dir, "pages"), spec.pattern);
8304
+ const { pageFiles } = await scanConventions(join23(spec.dir, "pages"), spec.pattern);
7763
8305
  if (pageFiles.length === 0)
7764
8306
  return null;
7765
8307
  const pages = pageFiles.map((file) => ({
@@ -7783,10 +8325,10 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
7783
8325
  }, resolveDiskPath = (buildDir, value) => {
7784
8326
  if (existsSync16(value))
7785
8327
  return value;
7786
- const underBuild = join22(buildDir, value);
8328
+ const underBuild = join23(buildDir, value);
7787
8329
  if (existsSync16(underBuild))
7788
8330
  return underBuild;
7789
- return join22(process.cwd(), value);
8331
+ return join23(process.cwd(), value);
7790
8332
  }, fileSize = (diskPath) => {
7791
8333
  try {
7792
8334
  return statSync(diskPath).size;
@@ -7794,7 +8336,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
7794
8336
  return 0;
7795
8337
  }
7796
8338
  }, readManifestSizes = (manifestDir) => {
7797
- const manifest = JSON.parse(readFileSync16(join22(manifestDir, "manifest.json"), "utf-8"));
8339
+ const manifest = JSON.parse(readFileSync16(join23(manifestDir, "manifest.json"), "utf-8"));
7798
8340
  const sizes = new Map;
7799
8341
  Object.entries(manifest).forEach(([key, value]) => {
7800
8342
  sizes.set(key, fileSize(resolveDiskPath(manifestDir, value)));
@@ -7813,7 +8355,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
7813
8355
  }))
7814
8356
  })), manifestAge = (manifestPath) => getDurationString(Date.now() - statSync(manifestPath).mtimeMs), firstBuildDir = (candidates) => candidates.map((candidate) => {
7815
8357
  const dir = readStringField(candidate.source, "buildDirectory");
7816
- return dir === undefined ? undefined : join22(candidate.baseDir, dir);
8358
+ return dir === undefined ? undefined : join23(candidate.baseDir, dir);
7817
8359
  }).find((dir) => dir !== undefined), resolveSizesDir = (args, candidates) => parseFlagValue(args, "--outdir") ?? firstBuildDir(candidates) ?? DEFAULT_BUILD_DIR, formatSize = (bytes) => {
7818
8360
  if (bytes === null || bytes === 0)
7819
8361
  return "-";
@@ -7911,7 +8453,7 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
7911
8453
  return;
7912
8454
  }
7913
8455
  const sizesDir = resolveSizesDir(args, candidates);
7914
- const manifestPath = join22(sizesDir, "manifest.json");
8456
+ const manifestPath = join23(sizesDir, "manifest.json");
7915
8457
  if (!existsSync16(manifestPath)) {
7916
8458
  printDim(`No build at ${relativeOrSelf(manifestPath)}. Run \`absolute build\` first, or pass \`--outdir <dir>\`.`);
7917
8459
  return;
@@ -9076,8 +9618,8 @@ export { value };
9076
9618
  host.getSourceFile = (fileName, languageVersion, onError, shouldCreate) => fileName === virtualPath ? ts5.createSourceFile(fileName, source, languageVersion, true) : getSourceFile(fileName, languageVersion, onError, shouldCreate);
9077
9619
  const fileExists = host.fileExists.bind(host);
9078
9620
  host.fileExists = (fileName) => fileName === virtualPath ? true : fileExists(fileName);
9079
- const readFile10 = host.readFile.bind(host);
9080
- host.readFile = (fileName) => fileName === virtualPath ? source : readFile10(fileName);
9621
+ const readFile11 = host.readFile.bind(host);
9622
+ host.readFile = (fileName) => fileName === virtualPath ? source : readFile11(fileName);
9081
9623
  const program = ts5.createProgram([virtualPath], options, host);
9082
9624
  const checker = program.getTypeChecker();
9083
9625
  const sourceFile = program.getSourceFile(virtualPath);
@@ -9378,8 +9920,8 @@ var init_frameworks = __esm(() => {
9378
9920
  });
9379
9921
 
9380
9922
  // src/cli/generate/context.ts
9381
- import { dirname as dirname13, isAbsolute as isAbsolute4, join as join23, relative as relative12, resolve as resolve25 } from "path";
9382
- var asString = (value) => typeof value === "string" ? value : undefined, isRecord10 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute4(value) ? value : resolve25(cwd, value), resolveStylesDir = (cwd, config) => {
9923
+ import { dirname as dirname14, isAbsolute as isAbsolute5, join as join24, relative as relative13, resolve as resolve25 } from "path";
9924
+ var asString = (value) => typeof value === "string" ? value : undefined, isRecord10 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute5(value) ? value : resolve25(cwd, value), resolveStylesDir = (cwd, config) => {
9383
9925
  const styles = config.stylesConfig;
9384
9926
  if (typeof styles === "string")
9385
9927
  return resolveDir(cwd, styles);
@@ -9391,7 +9933,7 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
9391
9933
  return resolve25(cwd, "src/frontend/styles/indexes");
9392
9934
  }, configuredFrameworks = (project) => FRAMEWORK_KEYS2.filter((key) => project.frameworkDirs[key] !== undefined), frontendRootFor = (project, framework) => {
9393
9935
  const dir = project.frameworkDirs[framework];
9394
- return dir ? dirname13(dir) : resolve25(project.cwd, "src/frontend");
9936
+ return dir ? dirname14(dir) : resolve25(project.cwd, "src/frontend");
9395
9937
  }, resolveProject = async (cwd, configOverride) => {
9396
9938
  const loaded = await loadConfig(configOverride);
9397
9939
  const config = isRecord10(loaded) ? loaded : {};
@@ -9441,8 +9983,8 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
9441
9983
  message: `Multiple frameworks configured (${configured.join(", ")}). Pass --framework <name>.`,
9442
9984
  ok: false
9443
9985
  };
9444
- }, sharedDirFor = (project, framework) => join23(frontendRootFor(project, framework), "shared"), toModuleSpecifier = (fromDir, toFileNoExt) => {
9445
- const rel = relative12(fromDir, toFileNoExt).split("\\").join("/");
9986
+ }, sharedDirFor = (project, framework) => join24(frontendRootFor(project, framework), "shared"), toModuleSpecifier = (fromDir, toFileNoExt) => {
9987
+ const rel = relative13(fromDir, toFileNoExt).split("\\").join("/");
9446
9988
  return rel.startsWith(".") ? rel : `./${rel}`;
9447
9989
  };
9448
9990
  var init_context = __esm(() => {
@@ -9471,7 +10013,7 @@ var emptyOutcome = () => ({
9471
10013
  // src/cli/generate/routeWiring.ts
9472
10014
  import ts7 from "typescript";
9473
10015
  import { existsSync as existsSync20, readFileSync as readFileSync20, readdirSync as readdirSync4, writeFileSync as writeFileSync9 } from "fs";
9474
- import { dirname as dirname14, join as join24 } from "path";
10016
+ import { dirname as dirname15, join as join25 } from "path";
9475
10017
  var DEFAULT_SEPARATOR = `
9476
10018
  `, BOUNDARY_USE, applyEdits = (text, edits) => {
9477
10019
  const ordered = [...edits].sort((first, second) => second.start - first.start);
@@ -9630,14 +10172,14 @@ ${newLines.join(`
9630
10172
  for (const name of readdirSync4(pluginsDir)) {
9631
10173
  if (!name.endsWith(".ts"))
9632
10174
  continue;
9633
- const candidate = join24(pluginsDir, name);
10175
+ const candidate = join25(pluginsDir, name);
9634
10176
  if (hasChain(candidate))
9635
10177
  return candidate;
9636
10178
  }
9637
10179
  return null;
9638
10180
  }, findRoutingFile = (serverEntry) => {
9639
- const pluginsDir = join24(dirname14(serverEntry), "plugins");
9640
- const preferred = join24(pluginsDir, "pagesPlugin.ts");
10181
+ const pluginsDir = join25(dirname15(serverEntry), "plugins");
10182
+ const preferred = join25(pluginsDir, "pagesPlugin.ts");
9641
10183
  if (hasChain(preferred))
9642
10184
  return preferred;
9643
10185
  const scanned = firstChainFile(pluginsDir);
@@ -9647,7 +10189,7 @@ ${newLines.join(`
9647
10189
  return serverEntry;
9648
10190
  return null;
9649
10191
  }, buildRouteContext = (input, routingFile) => {
9650
- const specifier = `${toModuleSpecifier(dirname14(routingFile), stripExtension(input.pageFileAbs))}${input.def.pageImportExtension ?? ""}`;
10192
+ const specifier = `${toModuleSpecifier(dirname15(routingFile), stripExtension(input.pageFileAbs))}${input.def.pageImportExtension ?? ""}`;
9651
10193
  return {
9652
10194
  cssAssetKey: input.cssAssetKey,
9653
10195
  indexKey: input.indexKey,
@@ -9729,7 +10271,7 @@ var init_routeWiring = __esm(() => {
9729
10271
 
9730
10272
  // src/cli/generate/generateApi.ts
9731
10273
  import { existsSync as existsSync21, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
9732
- import { dirname as dirname15, join as join25 } from "path";
10274
+ import { dirname as dirname16, join as join26 } from "path";
9733
10275
  var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
9734
10276
 
9735
10277
  export const ${pluginName} = new Elysia()
@@ -9741,8 +10283,8 @@ export const ${pluginName} = new Elysia()
9741
10283
  const pluginName = `${camel}Plugin`;
9742
10284
  const base = `/api/${kebab}`;
9743
10285
  const outcome = { ...emptyOutcome(), route: base };
9744
- const pluginsDir = join25(dirname15(project.serverEntry), "plugins");
9745
- const fileAbs = join25(pluginsDir, `${pluginName}.ts`);
10286
+ const pluginsDir = join26(dirname16(project.serverEntry), "plugins");
10287
+ const fileAbs = join26(pluginsDir, `${pluginName}.ts`);
9746
10288
  if (existsSync21(fileAbs)) {
9747
10289
  outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
9748
10290
  return outcome;
@@ -9750,7 +10292,7 @@ export const ${pluginName} = new Elysia()
9750
10292
  mkdirSync10(pluginsDir, { recursive: true });
9751
10293
  writeFileSync10(fileAbs, apiPluginTemplate(pluginName, base), "utf-8");
9752
10294
  outcome.created.push(fileAbs);
9753
- const specifier = toModuleSpecifier(dirname15(project.serverEntry), fileAbs.replace(/\.ts$/, ""));
10295
+ const specifier = toModuleSpecifier(dirname16(project.serverEntry), fileAbs.replace(/\.ts$/, ""));
9754
10296
  const wired = wirePluginUse(project.serverEntry, pluginName, specifier);
9755
10297
  if (wired.kind === "edited")
9756
10298
  outcome.updated.push(wired.routingFile);
@@ -9817,7 +10359,7 @@ var init_componentTemplates = __esm(() => {
9817
10359
 
9818
10360
  // src/cli/generate/generateComponent.ts
9819
10361
  import { existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
9820
- import { dirname as dirname16, join as join26 } from "path";
10362
+ import { dirname as dirname17, join as join27 } from "path";
9821
10363
  var generateComponent = (project, framework, rawName) => {
9822
10364
  const def = frameworks6[framework];
9823
10365
  const pascal = toPascalCase(rawName);
@@ -9828,12 +10370,12 @@ var generateComponent = (project, framework, rawName) => {
9828
10370
  outcome.manual = { reason: "framework directory missing", snippet: "" };
9829
10371
  return outcome;
9830
10372
  }
9831
- const fileAbs = join26(frameworkDir, "components", def.componentFile({ kebab, pascal }));
10373
+ const fileAbs = join27(frameworkDir, "components", def.componentFile({ kebab, pascal }));
9832
10374
  if (existsSync22(fileAbs)) {
9833
10375
  outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
9834
10376
  return outcome;
9835
10377
  }
9836
- mkdirSync11(dirname16(fileAbs), { recursive: true });
10378
+ mkdirSync11(dirname17(fileAbs), { recursive: true });
9837
10379
  writeFileSync11(fileAbs, componentTemplates[framework]({
9838
10380
  kebab,
9839
10381
  pascal,
@@ -9850,7 +10392,7 @@ var init_generateComponent = __esm(() => {
9850
10392
  // src/cli/generate/cssStrategy.ts
9851
10393
  import ts8 from "typescript";
9852
10394
  import { existsSync as existsSync23 } from "fs";
9853
- import { join as join27 } from "path";
10395
+ import { join as join28 } from "path";
9854
10396
  var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
9855
10397
  margin: 0 auto;
9856
10398
  max-width: 64rem;
@@ -9889,7 +10431,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
9889
10431
  return null;
9890
10432
  }, fileForKey = (stylesDir, assetKey2) => {
9891
10433
  const base = assetKey2.endsWith(CSS_SUFFIX) ? assetKey2.slice(0, -CSS_SUFFIX.length) : assetKey2;
9892
- return join27(stylesDir, `${toKebabCase(base)}.css`);
10434
+ return join28(stylesDir, `${toKebabCase(base)}.css`);
9893
10435
  }, planCss = (routingText, stylesDir, pascal, kebab) => {
9894
10436
  const sharedKey = detectSharedKey(routingText);
9895
10437
  if (sharedKey) {
@@ -9902,7 +10444,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
9902
10444
  shared: true
9903
10445
  };
9904
10446
  }
9905
- const cssFileAbs = join27(stylesDir, `${kebab}.css`);
10447
+ const cssFileAbs = join28(stylesDir, `${kebab}.css`);
9906
10448
  return {
9907
10449
  assetKey: `${pascal}${CSS_SUFFIX}`,
9908
10450
  contents: DEFAULT_CSS,
@@ -9916,7 +10458,7 @@ var init_cssStrategy = () => {};
9916
10458
  // src/cli/generate/navData.ts
9917
10459
  import ts9 from "typescript";
9918
10460
  import { existsSync as existsSync24, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync12 } from "fs";
9919
- import { dirname as dirname17 } from "path";
10461
+ import { dirname as dirname18 } from "path";
9920
10462
  var NAV_DATA_TEMPLATE = `type NavItem = {
9921
10463
  href: string;
9922
10464
  label: string;
@@ -9993,7 +10535,7 @@ ${indent}${entry}`;
9993
10535
  }, upsertNavItem = (navDataPath, item) => {
9994
10536
  const created = !existsSync24(navDataPath);
9995
10537
  if (created) {
9996
- mkdirSync12(dirname17(navDataPath), { recursive: true });
10538
+ mkdirSync12(dirname18(navDataPath), { recursive: true });
9997
10539
  writeFileSync12(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
9998
10540
  }
9999
10541
  const existing = readNavItems(navDataPath);
@@ -10163,14 +10705,14 @@ import {
10163
10705
  readdirSync as readdirSync5,
10164
10706
  writeFileSync as writeFileSync13
10165
10707
  } from "fs";
10166
- import { dirname as dirname18, join as join28, relative as relative13 } from "path";
10708
+ import { dirname as dirname19, join as join29, relative as relative14 } from "path";
10167
10709
  var writeNew = (path, contents) => {
10168
- mkdirSync13(dirname18(path), { recursive: true });
10710
+ mkdirSync13(dirname19(path), { recursive: true });
10169
10711
  writeFileSync13(path, contents, "utf-8");
10170
10712
  }, toHref = (fromDir, toFile) => {
10171
- const rel = relative13(fromDir, toFile).split("\\").join("/");
10713
+ const rel = relative14(fromDir, toFile).split("\\").join("/");
10172
10714
  return rel.startsWith(".") ? rel : `./${rel}`;
10173
- }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join28(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync25(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join28(pagesDir, name))), resyncPage = (file, items) => {
10715
+ }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join29(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync25(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join29(pagesDir, name))), resyncPage = (file, items) => {
10174
10716
  const html = readFileSync22(file, "utf-8");
10175
10717
  const synced = syncStaticNav(html, items);
10176
10718
  if (synced === null || synced === html)
@@ -10198,7 +10740,7 @@ var writeNew = (path, contents) => {
10198
10740
  outcome.manual = { reason: "framework directory missing", snippet: "" };
10199
10741
  return outcome;
10200
10742
  }
10201
- const pageFileAbs = join28(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
10743
+ const pageFileAbs = join29(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
10202
10744
  if (existsSync25(pageFileAbs)) {
10203
10745
  outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
10204
10746
  return outcome;
@@ -10206,11 +10748,11 @@ var writeNew = (path, contents) => {
10206
10748
  const routingFile = findRoutingFile(project.serverEntry);
10207
10749
  const routingText = routingFile ? readFileSync22(routingFile, "utf-8") : "";
10208
10750
  const css = planCss(routingText, project.stylesDir, pascal, kebab);
10209
- const navDataPath = join28(sharedDirFor(project, framework), "navData.ts");
10751
+ const navDataPath = join29(sharedDirFor(project, framework), "navData.ts");
10210
10752
  const nav = upsertNavItem(navDataPath, { href: route, label: title });
10211
- const navImportPath = toModuleSpecifier(dirname18(pageFileAbs), navDataPath.replace(/\.ts$/, ""));
10753
+ const navImportPath = toModuleSpecifier(dirname19(pageFileAbs), navDataPath.replace(/\.ts$/, ""));
10212
10754
  writeNew(pageFileAbs, pageTemplates[framework]({
10213
- cssHref: toHref(dirname18(pageFileAbs), css.cssFileAbs),
10755
+ cssHref: toHref(dirname19(pageFileAbs), css.cssFileAbs),
10214
10756
  kebab,
10215
10757
  navImportPath,
10216
10758
  navItems: nav.items,
@@ -10260,7 +10802,7 @@ var exports_generate = {};
10260
10802
  __export(exports_generate, {
10261
10803
  runGenerate: () => runGenerate
10262
10804
  });
10263
- import { relative as relative14 } from "path";
10805
+ import { relative as relative15 } from "path";
10264
10806
  var SUBCOMMANDS, write = (text) => process.stdout.write(`${text}
10265
10807
  `), fail = (message) => {
10266
10808
  process.stdout.write(`${colors.red}${message}${colors.reset}
@@ -10292,7 +10834,7 @@ var SUBCOMMANDS, write = (text) => process.stdout.write(`${text}
10292
10834
  return;
10293
10835
  write(` ${colors.dim}${label}${colors.reset}`);
10294
10836
  for (const path of paths)
10295
- write(` ${relative14(cwd, path)}`);
10837
+ write(` ${relative15(cwd, path)}`);
10296
10838
  }, printSummary = (title, outcome, cwd) => {
10297
10839
  for (const note of outcome.notes) {
10298
10840
  write(`${colors.yellow}!${colors.reset} ${note}`);
@@ -10586,9 +11128,9 @@ var init_catalog = __esm(() => {
10586
11128
 
10587
11129
  // src/cli/integrations/addPlugin.ts
10588
11130
  import { existsSync as existsSync26, readFileSync as readFileSync24 } from "fs";
10589
- import { join as join29 } from "path";
11131
+ import { join as join30 } from "path";
10590
11132
  var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
10591
- const path = join29(cwd, "package.json");
11133
+ const path = join30(cwd, "package.json");
10592
11134
  if (!existsSync26(path))
10593
11135
  return null;
10594
11136
  try {
@@ -11190,7 +11732,7 @@ var init_resolveAuthSettings = __esm(() => {
11190
11732
  // src/cli/config/auth/resolveAuthState.ts
11191
11733
  import ts12 from "typescript";
11192
11734
  import { existsSync as existsSync28, readdirSync as readdirSync6, readFileSync as readFileSync26 } from "fs";
11193
- import { join as join30, relative as relative15, resolve as resolve27 } from "path";
11735
+ import { join as join31, relative as relative16, resolve as resolve27 } from "path";
11194
11736
  var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
11195
11737
  if (!existsSync28(path))
11196
11738
  return null;
@@ -11204,7 +11746,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
11204
11746
  const value = record?.[key];
11205
11747
  return typeof value === "string" ? value : null;
11206
11748
  }, declaredVersionFor = (cwd) => {
11207
- const pkg = readJson(join30(cwd, "package.json"));
11749
+ const pkg = readJson(join31(cwd, "package.json"));
11208
11750
  if (!pkg)
11209
11751
  return null;
11210
11752
  for (const field of ["dependencies", "devDependencies"]) {
@@ -11216,14 +11758,14 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
11216
11758
  return version2;
11217
11759
  }
11218
11760
  return null;
11219
- }, installedVersionFor = (cwd) => stringField(readJson(join30(cwd, "node_modules", AUTH_PACKAGE2, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
11761
+ }, installedVersionFor = (cwd) => stringField(readJson(join31(cwd, "node_modules", AUTH_PACKAGE2, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
11220
11762
  try {
11221
11763
  return readdirSync6(dir, { withFileTypes: true });
11222
11764
  } catch {
11223
11765
  return [];
11224
11766
  }
11225
11767
  }, sortEntry = (dir, entry, found, dirs) => {
11226
- const full = join30(dir, entry.name);
11768
+ const full = join31(dir, entry.name);
11227
11769
  if (entry.isDirectory()) {
11228
11770
  if (SKIP_DIRS.has(entry.name) || entry.name.startsWith("."))
11229
11771
  return;
@@ -11321,7 +11863,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
11321
11863
  scaffoldable: isScaffoldableFeature(feature.id)
11322
11864
  })), resolveAuthState = (cwd) => {
11323
11865
  const installedVersion = installedVersionFor(cwd);
11324
- const root = existsSync28(join30(cwd, "src")) ? join30(cwd, "src") : cwd;
11866
+ const root = existsSync28(join31(cwd, "src")) ? join31(cwd, "src") : cwd;
11325
11867
  let match = null;
11326
11868
  let setupPath = null;
11327
11869
  for (const file of candidateFiles(root)) {
@@ -11329,7 +11871,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
11329
11871
  if (found === null)
11330
11872
  continue;
11331
11873
  match = found;
11332
- setupPath = relative15(cwd, resolve27(file));
11874
+ setupPath = relative16(cwd, resolve27(file));
11333
11875
  break;
11334
11876
  }
11335
11877
  const keys = match?.keys ?? new Set;
@@ -11367,7 +11909,7 @@ var init_resolveAuthState = __esm(() => {
11367
11909
 
11368
11910
  // src/cli/config/auth/scaffoldAuthFeature.ts
11369
11911
  import { existsSync as existsSync29, writeFileSync as writeFileSync15 } from "fs";
11370
- import { dirname as dirname19, join as join31, relative as relative16, resolve as resolve28 } from "path";
11912
+ import { dirname as dirname20, join as join32, relative as relative17, resolve as resolve28 } from "path";
11371
11913
  var renderScaffold = (scaffold) => {
11372
11914
  const importNames = [...scaffold.imports, `type ${scaffold.typeName}`];
11373
11915
  const importLine = `import { ${importNames.join(", ")} } from '@absolutejs/auth';`;
@@ -11392,8 +11934,8 @@ ${body}
11392
11934
  }, targetDir = (cwd) => {
11393
11935
  const { setupPath } = resolveAuthState(cwd);
11394
11936
  if (setupPath)
11395
- return dirname19(resolve28(cwd, setupPath));
11396
- const src = join31(cwd, "src");
11937
+ return dirname20(resolve28(cwd, setupPath));
11938
+ const src = join32(cwd, "src");
11397
11939
  return existsSync29(src) ? src : cwd;
11398
11940
  }, spreadFor = (scaffold) => `import { ${scaffold.exportName} } from './${scaffold.exportName}';
11399
11941
  // add to your auth() call:
@@ -11407,8 +11949,8 @@ ${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
11407
11949
  const scaffold = AUTH_SCAFFOLDS[id];
11408
11950
  if (!scaffold)
11409
11951
  return failure2(`Unknown auth feature "${id}".`);
11410
- const filePath = join31(targetDir(cwd), `${scaffold.exportName}.ts`);
11411
- const relPath = relative16(cwd, filePath);
11952
+ const filePath = join32(targetDir(cwd), `${scaffold.exportName}.ts`);
11953
+ const relPath = relative17(cwd, filePath);
11412
11954
  if (existsSync29(filePath)) {
11413
11955
  return {
11414
11956
  created: null,
@@ -11437,11 +11979,11 @@ var init_scaffoldAuthFeature = __esm(() => {
11437
11979
 
11438
11980
  // src/cli/htmx/install.ts
11439
11981
  import { existsSync as existsSync30, mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync16 } from "fs";
11440
- import { join as join32 } from "path";
11982
+ import { join as join33 } from "path";
11441
11983
  var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
11442
- join32(import.meta.dir, "htmx.min.js"),
11443
- join32(import.meta.dir, "htmx", "htmx.min.js"),
11444
- join32(import.meta.dir, "..", "htmx", "htmx.min.js")
11984
+ join33(import.meta.dir, "htmx.min.js"),
11985
+ join33(import.meta.dir, "htmx", "htmx.min.js"),
11986
+ join33(import.meta.dir, "..", "htmx", "htmx.min.js")
11445
11987
  ].find((path) => existsSync30(path)) ?? null, detectHtmxVersion = (content) => {
11446
11988
  const match = content.match(/version:"([0-9.]+)"/);
11447
11989
  return match ? match[1] : null;
@@ -11453,7 +11995,7 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
11453
11995
  }
11454
11996
  return response.text();
11455
11997
  }, installedHtmxVersion = (htmxDir) => {
11456
- const file = join32(htmxDir, "htmx.min.js");
11998
+ const file = join33(htmxDir, "htmx.min.js");
11457
11999
  if (!existsSync30(file))
11458
12000
  return null;
11459
12001
  return detectHtmxVersion(readFileSync27(file, "utf-8"));
@@ -11462,7 +12004,7 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
11462
12004
  return file ? readFileSync27(file, "utf-8") : null;
11463
12005
  }, writeHtmx = (htmxDir, content) => {
11464
12006
  mkdirSync14(htmxDir, { recursive: true });
11465
- const file = join32(htmxDir, "htmx.min.js");
12007
+ const file = join33(htmxDir, "htmx.min.js");
11466
12008
  writeFileSync16(file, content, "utf-8");
11467
12009
  return file;
11468
12010
  };
@@ -11473,7 +12015,7 @@ var exports_add = {};
11473
12015
  __export(exports_add, {
11474
12016
  runAdd: () => runAdd
11475
12017
  });
11476
- import { dirname as dirname20, join as join33, relative as relative17 } from "path";
12018
+ import { dirname as dirname21, join as join34, relative as relative18 } from "path";
11477
12019
  var write2 = (text) => process.stdout.write(`${text}
11478
12020
  `), fail2 = (message) => {
11479
12021
  process.stdout.write(`${colors.red}${message}${colors.reset}
@@ -11484,11 +12026,11 @@ var write2 = (text) => process.stdout.write(`${text}
11484
12026
  return;
11485
12027
  write2(` ${colors.dim}${label}${colors.reset}`);
11486
12028
  for (const path of paths)
11487
- write2(` ${relative17(cwd, path)}`);
12029
+ write2(` ${relative18(cwd, path)}`);
11488
12030
  }, frontendRoot = (project, cwd) => {
11489
12031
  const [firstKey] = configuredFrameworks(project);
11490
12032
  const firstDir = firstKey ? project.frameworkDirs[firstKey] : undefined;
11491
- return firstDir ? dirname20(firstDir) : join33(cwd, "src", "frontend");
12033
+ return firstDir ? dirname21(firstDir) : join34(cwd, "src", "frontend");
11492
12034
  }, addIntegrationCli = (id, install) => {
11493
12035
  const result = addIntegration(process.cwd(), id, { install });
11494
12036
  if (!result.ok) {
@@ -11552,8 +12094,8 @@ var write2 = (text) => process.stdout.write(`${text}
11552
12094
  write2(`${colors.yellow}!${colors.reset} ${frameworks6[framework].label} is already configured \u2014 nothing to do.`);
11553
12095
  return;
11554
12096
  }
11555
- const dirAbs = join33(frontendRoot(project, cwd), framework);
11556
- const dirRel = `./${relative17(cwd, dirAbs).split("\\").join("/")}`;
12097
+ const dirAbs = join34(frontendRoot(project, cwd), framework);
12098
+ const dirRel = `./${relative18(cwd, dirAbs).split("\\").join("/")}`;
11557
12099
  let depNote = "Skipped dependency install (--no-install).";
11558
12100
  if (!noInstall) {
11559
12101
  write2(`${colors.dim}Installing ${frameworks6[framework].label} dependencies\u2026${colors.reset}`);
@@ -11623,7 +12165,7 @@ __export(exports_analyze, {
11623
12165
  runAnalyze: () => runAnalyze
11624
12166
  });
11625
12167
  import { existsSync as existsSync31, readFileSync as readFileSync28, statSync as statSync3, writeFileSync as writeFileSync17 } from "fs";
11626
- import { join as join34, resolve as resolve29 } from "path";
12168
+ import { join as join35, resolve as resolve29 } from "path";
11627
12169
  var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_WIDTH = 16, SIZE_WIDTH = 12, CHANGE_WIDTH = 10, CATEGORY_ORDER, categoryOf = (key) => {
11628
12170
  if (key.startsWith("Island"))
11629
12171
  return "Islands";
@@ -11643,17 +12185,17 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
11643
12185
  return 0;
11644
12186
  }
11645
12187
  }, readSizes = (manifestDir) => {
11646
- const manifestPath = join34(manifestDir, "manifest.json");
12188
+ const manifestPath = join35(manifestDir, "manifest.json");
11647
12189
  if (!existsSync31(manifestPath))
11648
12190
  return null;
11649
12191
  const manifest = JSON.parse(readFileSync28(manifestPath, "utf-8"));
11650
12192
  const sizes = {};
11651
12193
  for (const [key, value] of Object.entries(manifest)) {
11652
- sizes[key] = fileSize2(join34(manifestDir, value.replace(/^\//, "")));
12194
+ sizes[key] = fileSize2(join35(manifestDir, value.replace(/^\//, "")));
11653
12195
  }
11654
12196
  return sizes;
11655
12197
  }, readBaseline = (cwd) => {
11656
- const path = join34(cwd, BASELINE_FILE);
12198
+ const path = join35(cwd, BASELINE_FILE);
11657
12199
  if (!existsSync31(path))
11658
12200
  return null;
11659
12201
  try {
@@ -11742,7 +12284,7 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
11742
12284
  return;
11743
12285
  }
11744
12286
  if (args.includes("--save")) {
11745
- writeFileSync17(join34(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
12287
+ writeFileSync17(join35(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
11746
12288
  `);
11747
12289
  process.stdout.write(`${colors.green}\u2713${colors.reset} Saved size baseline (${Object.keys(sizes).length} entries) to ${BASELINE_FILE}
11748
12290
  `);
@@ -11989,7 +12531,7 @@ __export(exports_remove, {
11989
12531
  runRemove: () => runRemove
11990
12532
  });
11991
12533
  import { existsSync as existsSync32, readFileSync as readFileSync29 } from "fs";
11992
- import { relative as relative18 } from "path";
12534
+ import { relative as relative19 } from "path";
11993
12535
  var write3 = (text) => process.stdout.write(`${text}
11994
12536
  `), fail3 = (message) => {
11995
12537
  process.stdout.write(`${colors.red}${message}${colors.reset}
@@ -12038,10 +12580,10 @@ var write3 = (text) => process.stdout.write(`${text}
12038
12580
  }
12039
12581
  write3(`${colors.green}\u2713${colors.reset} Removed ${framework}Directory from absolute.config.ts
12040
12582
  `);
12041
- write3(` ${colors.dim}Kept${colors.reset} ${relative18(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
12583
+ write3(` ${colors.dim}Kept${colors.reset} ${relative19(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
12042
12584
  const refs = referencingFiles(project.serverEntry, HANDLER_NAME[framework]);
12043
12585
  for (const file of refs) {
12044
- write3(` ${colors.yellow}Still references${colors.reset} ${relative18(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
12586
+ write3(` ${colors.yellow}Still references${colors.reset} ${relative19(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
12045
12587
  }
12046
12588
  const deps = frameworkDependencyNames(framework);
12047
12589
  if (prune && deps.length > 0) {
@@ -12130,9 +12672,9 @@ __export(exports_env, {
12130
12672
  collectEnvVars: () => collectEnvVars
12131
12673
  });
12132
12674
  import { existsSync as existsSync33, readFileSync as readFileSync30 } from "fs";
12133
- import { join as join35 } from "path";
12675
+ import { join as join36 } from "path";
12134
12676
  var {env: env3, Glob: Glob3 } = globalThis.Bun;
12135
- var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync33(join35(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
12677
+ var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync33(join36(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
12136
12678
  const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
12137
12679
  const files = (await Promise.all(scans)).flat();
12138
12680
  const usage = new Map;
@@ -12199,7 +12741,7 @@ __export(exports_db, {
12199
12741
  chunkRows: () => chunkRows
12200
12742
  });
12201
12743
  import { existsSync as existsSync34, mkdirSync as mkdirSync15, readFileSync as readFileSync31, writeFileSync as writeFileSync18 } from "fs";
12202
- import { join as join36 } from "path";
12744
+ import { join as join37 } from "path";
12203
12745
  var {env: env4, spawn: spawn2, SQL } = globalThis.Bun;
12204
12746
  var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA_TYPES, SEED_CANDIDATES, VALUE_FLAGS, paint = (text, color) => `${color}${text}${colors.reset}`, chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size)), quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`, resolveUrl = (explicit) => {
12205
12747
  const found = explicit ?? URL_ENV_KEYS.map((key) => env4[key]).find((value) => typeof value === "string" && value !== "");
@@ -12309,12 +12851,12 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
12309
12851
  tables,
12310
12852
  v: BACKUP_FORMAT_VERSION
12311
12853
  };
12312
- const dir = options.out ?? join36(process.cwd(), "backups");
12854
+ const dir = options.out ?? join37(process.cwd(), "backups");
12313
12855
  mkdirSync15(dir, { recursive: true });
12314
12856
  const json = JSON.stringify(payload, (_, value) => typeof value === "bigint" ? value.toString() : value);
12315
- const file = join36(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
12857
+ const file = join37(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
12316
12858
  writeFileSync18(file, json);
12317
- writeFileSync18(join36(dir, "latest.json"), json);
12859
+ writeFileSync18(join37(dir, "latest.json"), json);
12318
12860
  const total = chosen.reduce((sum, name) => sum + (tables[name]?.length ?? 0), 0);
12319
12861
  console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
12320
12862
  console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
@@ -12343,7 +12885,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
12343
12885
  const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
12344
12886
  console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
12345
12887
  }, runSeed = async (entry) => {
12346
- const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync34(join36(process.cwd(), candidate)));
12888
+ const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync34(join37(process.cwd(), candidate)));
12347
12889
  if (target === undefined)
12348
12890
  throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
12349
12891
  console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
@@ -12378,7 +12920,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
12378
12920
  return;
12379
12921
  }
12380
12922
  if (sub === "restore") {
12381
- const file = positionalArgs(rest)[0] ?? join36(process.cwd(), "backups", "latest.json");
12923
+ const file = positionalArgs(rest)[0] ?? join37(process.cwd(), "backups", "latest.json");
12382
12924
  await runRestore(file, parseOptions(rest));
12383
12925
  return;
12384
12926
  }
@@ -12498,7 +13040,7 @@ import {
12498
13040
  writeFileSync as writeFileSync19
12499
13041
  } from "fs";
12500
13042
  import { createRequire } from "module";
12501
- import { dirname as dirname21, join as join37, resolve as resolve30, sep as sep4 } from "path";
13043
+ import { dirname as dirname22, join as join38, resolve as resolve30, sep as sep5 } from "path";
12502
13044
  var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12503
13045
  try {
12504
13046
  const parsed = JSON.parse(readFileSync32(path, "utf-8"));
@@ -12518,13 +13060,13 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12518
13060
  const version2 = Reflect.get(manifest, "version");
12519
13061
  return typeof version2 === "string" ? version2 : "unknown";
12520
13062
  }, packageJsonFromEntry = (entry, expectedName) => {
12521
- let directory = dirname21(entry);
13063
+ let directory = dirname22(entry);
12522
13064
  for (;; ) {
12523
- const candidate = join37(directory, "package.json");
13065
+ const candidate = join38(directory, "package.json");
12524
13066
  const manifest = readManifest(candidate);
12525
13067
  if (manifest && manifestName(manifest, "") === expectedName)
12526
13068
  return candidate;
12527
- const parent = dirname21(directory);
13069
+ const parent = dirname22(directory);
12528
13070
  if (parent === directory)
12529
13071
  return null;
12530
13072
  directory = parent;
@@ -12542,10 +13084,10 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12542
13084
  }, findInstallRoot = (cwd) => {
12543
13085
  let directory = resolve30(cwd);
12544
13086
  for (;; ) {
12545
- if (existsSync36(join37(directory, "bun.lock")) || existsSync36(join37(directory, "bun.lockb"))) {
13087
+ if (existsSync36(join38(directory, "bun.lock")) || existsSync36(join38(directory, "bun.lockb"))) {
12546
13088
  return directory;
12547
13089
  }
12548
- const parent = dirname21(directory);
13090
+ const parent = dirname22(directory);
12549
13091
  if (parent === directory)
12550
13092
  return resolve30(cwd);
12551
13093
  directory = parent;
@@ -12553,14 +13095,14 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12553
13095
  }, findProjectManifest = (cwd, installRoot) => {
12554
13096
  let directory = resolve30(cwd);
12555
13097
  for (;; ) {
12556
- const candidate = join37(directory, "package.json");
13098
+ const candidate = join38(directory, "package.json");
12557
13099
  if (existsSync36(candidate))
12558
13100
  return candidate;
12559
13101
  if (directory === installRoot)
12560
- return join37(installRoot, "package.json");
12561
- const parent = dirname21(directory);
13102
+ return join38(installRoot, "package.json");
13103
+ const parent = dirname22(directory);
12562
13104
  if (parent === directory)
12563
- return join37(installRoot, "package.json");
13105
+ return join38(installRoot, "package.json");
12564
13106
  directory = parent;
12565
13107
  }
12566
13108
  }, appendConsumer = (consumers, consumerPaths, path, manifest) => {
@@ -12598,7 +13140,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12598
13140
  appendConsumer(consumers, consumerPaths, inspection.consumer.path, inspection.consumer.manifest);
12599
13141
  }, inspectTypeGraph = (cwd) => {
12600
13142
  const installRoot = findInstallRoot(cwd);
12601
- const rootManifestPath = join37(installRoot, "package.json");
13143
+ const rootManifestPath = join38(installRoot, "package.json");
12602
13144
  const rootManifest = readManifest(rootManifestPath) ?? {};
12603
13145
  const consumers = [
12604
13146
  { manifest: rootManifest, path: rootManifestPath }
@@ -12634,7 +13176,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12634
13176
  const duplicates = duplicateTypeGraphPackages(report);
12635
13177
  if (duplicates.length === 0)
12636
13178
  return [];
12637
- const manifestPath = join37(report.installRoot, "package.json");
13179
+ const manifestPath = join38(report.installRoot, "package.json");
12638
13180
  const manifest = readManifest(manifestPath);
12639
13181
  if (!manifest)
12640
13182
  return [];
@@ -12656,10 +13198,10 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12656
13198
  }
12657
13199
  return changes;
12658
13200
  }, removeDuplicateTypeGraphPackages = (report) => {
12659
- const manifest = readManifest(join37(report.installRoot, "package.json")) ?? {};
13201
+ const manifest = readManifest(join38(report.installRoot, "package.json")) ?? {};
12660
13202
  const rootName = manifestName(manifest, "<workspace>");
12661
- const installPrefix = `${realpathSync2(report.installRoot)}${sep4}`;
12662
- const nodeModulesSegment = `${sep4}node_modules${sep4}`;
13203
+ const installPrefix = `${realpathSync2(report.installRoot)}${sep5}`;
13204
+ const nodeModulesSegment = `${sep5}node_modules${sep5}`;
12663
13205
  const removed = [];
12664
13206
  const stalePaths = duplicateTypeGraphPackages(report).flatMap((duplicate) => {
12665
13207
  const selected = preferredIdentity(duplicate, rootName);
@@ -12668,7 +13210,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
12668
13210
  for (const stalePath of stalePaths) {
12669
13211
  if (!stalePath.startsWith(installPrefix) || !stalePath.includes(nodeModulesSegment))
12670
13212
  continue;
12671
- rmSync6(dirname21(stalePath), { force: true, recursive: true });
13213
+ rmSync6(dirname22(stalePath), { force: true, recursive: true });
12672
13214
  removed.push(stalePath);
12673
13215
  }
12674
13216
  return removed;
@@ -12698,7 +13240,7 @@ __export(exports_doctor, {
12698
13240
  import { existsSync as existsSync37, mkdirSync as mkdirSync16, readFileSync as readFileSync33, writeFileSync as writeFileSync20 } from "fs";
12699
13241
  import { createRequire as createRequire2 } from "module";
12700
13242
  import { arch as arch4, platform as platform5 } from "os";
12701
- import { join as join38 } from "path";
13243
+ import { join as join39 } from "path";
12702
13244
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
12703
13245
  detail,
12704
13246
  label,
@@ -12733,7 +13275,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
12733
13275
  return [];
12734
13276
  const label = `${field.replace("Directory", "")} pages`;
12735
13277
  return [
12736
- existsSync37(join38(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
13278
+ existsSync37(join39(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
12737
13279
  ];
12738
13280
  }), envCheck = async () => {
12739
13281
  const vars = await collectEnvVars();
@@ -12795,9 +13337,9 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
12795
13337
  const fixes = [];
12796
13338
  for (const field of FRAMEWORK_FIELDS2) {
12797
13339
  const dir = readString2(config, field);
12798
- if (dir === undefined || existsSync37(join38(cwd, dir)))
13340
+ if (dir === undefined || existsSync37(join39(cwd, dir)))
12799
13341
  continue;
12800
- mkdirSync16(join38(cwd, dir, "pages"), { recursive: true });
13342
+ mkdirSync16(join39(cwd, dir, "pages"), { recursive: true });
12801
13343
  fixes.push(`created ${dir}/pages`);
12802
13344
  }
12803
13345
  return fixes;
@@ -12805,7 +13347,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
12805
13347
  const missing = (await collectEnvVars()).filter((entry) => !entry.set);
12806
13348
  if (missing.length === 0)
12807
13349
  return null;
12808
- const envExample = join38(cwd, ".env.example");
13350
+ const envExample = join39(cwd, ".env.example");
12809
13351
  const existing = existsSync37(envExample) ? readFileSync33(envExample, "utf-8") : "";
12810
13352
  const existingKeys = new Set(existing.split(`
12811
13353
  `).map((line) => line.split("=")[0]?.trim()));
@@ -12876,7 +13418,7 @@ var init_doctor = __esm(() => {
12876
13418
  "htmlDirectory",
12877
13419
  "htmxDirectory"
12878
13420
  ];
12879
- projectRequire = createRequire2(join38(process.cwd(), "package.json"));
13421
+ projectRequire = createRequire2(join39(process.cwd(), "package.json"));
12880
13422
  STATUS_MARK = {
12881
13423
  fail: `${colors.red}\u2717${colors.reset}`,
12882
13424
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -13266,7 +13808,7 @@ var init_sourceMetadata = __esm(() => {
13266
13808
 
13267
13809
  // src/islands/pageMetadata.ts
13268
13810
  import { readFileSync as readFileSync34 } from "fs";
13269
- import { dirname as dirname22, resolve as resolve31 } from "path";
13811
+ import { dirname as dirname23, resolve as resolve31 } from "path";
13270
13812
  var pagePatterns, getPageDirs = (config) => [
13271
13813
  { dir: config.angularDirectory, framework: "angular" },
13272
13814
  { dir: config.emberDirectory, framework: "ember" },
@@ -13286,7 +13828,7 @@ var pagePatterns, getPageDirs = (config) => [
13286
13828
  const source = definition.buildReference?.source;
13287
13829
  if (!source)
13288
13830
  continue;
13289
- const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve31(dirname22(buildInfo.resolvedRegistryPath), source);
13831
+ const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve31(dirname23(buildInfo.resolvedRegistryPath), source);
13290
13832
  lookup.set(`${definition.framework}:${definition.component}`, resolve31(resolvedSource));
13291
13833
  }
13292
13834
  return lookup;
@@ -13336,7 +13878,7 @@ __export(exports_islands, {
13336
13878
  runIslands: () => runIslands
13337
13879
  });
13338
13880
  import { existsSync as existsSync39, readFileSync as readFileSync35, statSync as statSync5 } from "fs";
13339
- import { join as join39, relative as relative19, resolve as resolve32 } from "path";
13881
+ import { join as join40, relative as relative20, resolve as resolve32 } from "path";
13340
13882
  var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
13341
13883
  `), hostFrameworkOf = (pagePath, cwd, config) => {
13342
13884
  const resolved = resolve32(cwd, pagePath);
@@ -13354,13 +13896,13 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
13354
13896
  return 0;
13355
13897
  }
13356
13898
  }, readManifestSizes2 = (manifestDir) => {
13357
- const manifestPath = join39(manifestDir, "manifest.json");
13899
+ const manifestPath = join40(manifestDir, "manifest.json");
13358
13900
  if (!existsSync39(manifestPath))
13359
13901
  return null;
13360
13902
  const manifest = JSON.parse(readFileSync35(manifestPath, "utf-8"));
13361
13903
  const sizes = new Map;
13362
13904
  for (const [key, value] of Object.entries(manifest)) {
13363
- sizes.set(key, fileSize3(join39(manifestDir, value.replace(/^\//, ""))));
13905
+ sizes.set(key, fileSize3(join40(manifestDir, value.replace(/^\//, ""))));
13364
13906
  }
13365
13907
  return sizes;
13366
13908
  }, collectIslands = async (cwd, config, sizes) => {
@@ -13377,7 +13919,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
13377
13919
  crossFramework: hostFramework !== null && hostFramework !== definition.framework,
13378
13920
  hostFramework,
13379
13921
  hydrate: usage2.hydrate ?? "load",
13380
- page: relative19(cwd, resolve32(cwd, usage2.page))
13922
+ page: relative20(cwd, resolve32(cwd, usage2.page))
13381
13923
  };
13382
13924
  });
13383
13925
  const key = getIslandManifestKey(definition.framework, definition.component);
@@ -13416,7 +13958,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
13416
13958
  ` ${color}\u2B21${colors.reset} ${colors.bold}${island.component}${colors.reset} ${meta}${sizeText}`
13417
13959
  ];
13418
13960
  if (island.source) {
13419
- lines.push(` ${colors.dim}${relative19(cwd, island.source)}${colors.reset}`);
13961
+ lines.push(` ${colors.dim}${relative20(cwd, island.source)}${colors.reset}`);
13420
13962
  }
13421
13963
  if (pages.length === 0) {
13422
13964
  lines.push(` ${colors.dim}(registered but not mounted on any page)${colors.reset}`);
@@ -13496,7 +14038,7 @@ var init_islands2 = __esm(() => {
13496
14038
 
13497
14039
  // src/build/externalAssetPlugin.ts
13498
14040
  import { copyFileSync as copyFileSync2, existsSync as existsSync40, mkdirSync as mkdirSync17, statSync as statSync6 } from "fs";
13499
- import { basename as basename10, dirname as dirname23, join as join40, resolve as resolve33 } from "path";
14041
+ import { basename as basename10, dirname as dirname24, join as join41, resolve as resolve33 } from "path";
13500
14042
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
13501
14043
  name: "absolute-external-asset",
13502
14044
  setup(bld) {
@@ -13511,7 +14053,7 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
13511
14053
  return;
13512
14054
  urlPattern.lastIndex = 0;
13513
14055
  let match;
13514
- const sourceDir = dirname23(args.path);
14056
+ const sourceDir = dirname24(args.path);
13515
14057
  while ((match = urlPattern.exec(source)) !== null) {
13516
14058
  const relPath = match[1];
13517
14059
  if (!relPath)
@@ -13521,10 +14063,10 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
13521
14063
  continue;
13522
14064
  if (!statSync6(assetPath).isFile())
13523
14065
  continue;
13524
- const targetPath = join40(outDir, basename10(assetPath));
14066
+ const targetPath = join41(outDir, basename10(assetPath));
13525
14067
  if (existsSync40(targetPath))
13526
14068
  continue;
13527
- mkdirSync17(dirname23(targetPath), { recursive: true });
14069
+ mkdirSync17(dirname24(targetPath), { recursive: true });
13528
14070
  copyFileSync2(assetPath, targetPath);
13529
14071
  }
13530
14072
  return;
@@ -13554,10 +14096,10 @@ import {
13554
14096
  import { createRequire as createRequire3 } from "module";
13555
14097
  import {
13556
14098
  basename as basename11,
13557
- dirname as dirname24,
13558
- isAbsolute as isAbsolute5,
13559
- join as join41,
13560
- relative as relative20,
14099
+ dirname as dirname25,
14100
+ isAbsolute as isAbsolute6,
14101
+ join as join42,
14102
+ relative as relative21,
13561
14103
  resolve as resolve34
13562
14104
  } from "path";
13563
14105
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
@@ -13572,7 +14114,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13572
14114
  const entry = pending.pop();
13573
14115
  if (!entry)
13574
14116
  continue;
13575
- const fullPath = join41(entry.parentPath, entry.name);
14117
+ const fullPath = join42(entry.parentPath, entry.name);
13576
14118
  if (entry.isDirectory())
13577
14119
  pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
13578
14120
  else
@@ -13591,11 +14133,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13591
14133
  if (!Array.isArray(map.sources))
13592
14134
  return;
13593
14135
  const sourceRoot = typeof map.sourceRoot === "string" ? map.sourceRoot : "";
13594
- const bundleDirectory = dirname24(filePath);
14136
+ const bundleDirectory = dirname25(filePath);
13595
14137
  map.sources = map.sources.map((entry) => {
13596
14138
  if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(entry))
13597
14139
  return entry;
13598
- if (isAbsolute5(entry))
14140
+ if (isAbsolute6(entry))
13599
14141
  return entry;
13600
14142
  if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(sourceRoot)) {
13601
14143
  return new URL(entry, sourceRoot).href;
@@ -13618,7 +14160,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13618
14160
  const entry = pending.pop();
13619
14161
  if (!entry)
13620
14162
  continue;
13621
- const fullPath = join41(entry.parentPath, entry.name);
14163
+ const fullPath = join42(entry.parentPath, entry.name);
13622
14164
  if (entry.isDirectory()) {
13623
14165
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
13624
14166
  continue;
@@ -13632,7 +14174,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13632
14174
  const copied = new Set;
13633
14175
  const normalizedOutdir = resolve34(outdir);
13634
14176
  const copyReference = (filePath, relPath) => {
13635
- const assetSource = resolve34(dirname24(filePath), relPath);
14177
+ const assetSource = resolve34(dirname25(filePath), relPath);
13636
14178
  if (!existsSync41(assetSource) || !statSync7(assetSource).isFile())
13637
14179
  return;
13638
14180
  const assetTarget = resolve34(normalizedOutdir, relPath.replace(/^\.\//, ""));
@@ -13641,7 +14183,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13641
14183
  if (copied.has(assetTarget))
13642
14184
  return;
13643
14185
  copied.add(assetTarget);
13644
- mkdirSync18(dirname24(assetTarget), { recursive: true });
14186
+ mkdirSync18(dirname25(assetTarget), { recursive: true });
13645
14187
  cpSync(assetSource, assetTarget, { force: true });
13646
14188
  };
13647
14189
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
@@ -13757,7 +14299,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13757
14299
  return nativeAssetEnv;
13758
14300
  }, tryReadNodePackageJson = (packageDir) => {
13759
14301
  try {
13760
- return JSON.parse(readFileSync36(join41(packageDir, "package.json"), "utf-8"));
14302
+ return JSON.parse(readFileSync36(join42(packageDir, "package.json"), "utf-8"));
13761
14303
  } catch {
13762
14304
  return null;
13763
14305
  }
@@ -13769,13 +14311,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13769
14311
  if (!pkg)
13770
14312
  return;
13771
14313
  seen.add(specifier);
13772
- const destDir = join41(outdir, "node_modules", ...specifier.split("/"));
14314
+ const destDir = join42(outdir, "node_modules", ...specifier.split("/"));
13773
14315
  rmSync7(destDir, { force: true, recursive: true });
13774
14316
  cpSync(srcDir, destDir, {
13775
14317
  force: true,
13776
14318
  recursive: true,
13777
14319
  filter(source) {
13778
- const rel = relative20(srcDir, source);
14320
+ const rel = relative21(srcDir, source);
13779
14321
  const [firstSegment] = rel.split(/[\\/]/);
13780
14322
  return firstSegment !== "node_modules" && firstSegment !== ".git";
13781
14323
  }
@@ -13810,7 +14352,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13810
14352
  copyAngularRuntimePackages(buildConfig, outdir);
13811
14353
  copyChunkReferencedPackages(outdir, seen);
13812
14354
  }, collectRuntimePackageSpecifiers = (distDir) => {
13813
- const nodeModulesDir = join41(distDir, "node_modules");
14355
+ const nodeModulesDir = join42(distDir, "node_modules");
13814
14356
  if (!existsSync41(nodeModulesDir))
13815
14357
  return [];
13816
14358
  const specifiers = [];
@@ -13818,7 +14360,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13818
14360
  if (!entry.isDirectory())
13819
14361
  continue;
13820
14362
  if (entry.name.startsWith("@")) {
13821
- const scopeDir = join41(nodeModulesDir, entry.name);
14363
+ const scopeDir = join42(nodeModulesDir, entry.name);
13822
14364
  for (const scopedEntry of readdirSync7(scopeDir, {
13823
14365
  withFileTypes: true
13824
14366
  })) {
@@ -13832,7 +14374,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13832
14374
  }
13833
14375
  return specifiers.sort((firstSpecifier, secondSpecifier) => secondSpecifier.length - firstSpecifier.length);
13834
14376
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
13835
- const rel = relative20(dirname24(fromFile), toFile).replace(/\\/g, "/");
14377
+ const rel = relative21(dirname25(fromFile), toFile).replace(/\\/g, "/");
13836
14378
  return rel.startsWith(".") ? rel : `./${rel}`;
13837
14379
  }, pickExportEntry = (value) => {
13838
14380
  if (typeof value === "string")
@@ -13849,18 +14391,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13849
14391
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
13850
14392
  if (!packageSpecifier)
13851
14393
  return null;
13852
- const packageDir = join41(distDir, "node_modules", ...packageSpecifier.split("/"));
14394
+ const packageDir = join42(distDir, "node_modules", ...packageSpecifier.split("/"));
13853
14395
  const subpath = specifier.slice(packageSpecifier.length);
13854
- const subPackageDir = subpath ? join41(packageDir, ...subpath.slice(1).split("/")) : null;
13855
- const resolvedPackageDir = subPackageDir && existsSync41(join41(subPackageDir, "package.json")) ? subPackageDir : packageDir;
13856
- const packageJsonPath = join41(resolvedPackageDir, "package.json");
14396
+ const subPackageDir = subpath ? join42(packageDir, ...subpath.slice(1).split("/")) : null;
14397
+ const resolvedPackageDir = subPackageDir && existsSync41(join42(subPackageDir, "package.json")) ? subPackageDir : packageDir;
14398
+ const packageJsonPath = join42(resolvedPackageDir, "package.json");
13857
14399
  if (!existsSync41(packageJsonPath))
13858
14400
  return null;
13859
14401
  const pkg = JSON.parse(readFileSync36(packageJsonPath, "utf-8"));
13860
14402
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
13861
14403
  const rootExport = pkg.exports?.[exportKey];
13862
14404
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
13863
- return join41(resolvedPackageDir, entry);
14405
+ return join42(resolvedPackageDir, entry);
13864
14406
  }, RUNTIME_JS_EXTENSIONS, MODULE_SPECIFIER_RE, isRuntimeJsFile = (filePath) => RUNTIME_JS_EXTENSIONS.some((extension) => filePath.endsWith(extension)), isNodeModulesPath = (filePath) => filePath.split(/[\\/]/).includes("node_modules"), isFile = (filePath) => {
13865
14407
  try {
13866
14408
  return statSync7(filePath).isFile();
@@ -13873,16 +14415,16 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13873
14415
  const candidates = [
13874
14416
  candidate,
13875
14417
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
13876
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join41(candidate, `index${extension}`))
14418
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join42(candidate, `index${extension}`))
13877
14419
  ];
13878
14420
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
13879
14421
  }, findContainingRuntimePackageDir = (filePath) => {
13880
- let dir = dirname24(filePath);
13881
- while (dir !== dirname24(dir)) {
13882
- if (isNodeModulesPath(dir) && existsSync41(join41(dir, "package.json"))) {
14422
+ let dir = dirname25(filePath);
14423
+ while (dir !== dirname25(dir)) {
14424
+ if (isNodeModulesPath(dir) && existsSync41(join42(dir, "package.json"))) {
13883
14425
  return dir;
13884
14426
  }
13885
- dir = dirname24(dir);
14427
+ dir = dirname25(dir);
13886
14428
  }
13887
14429
  return null;
13888
14430
  }, resolvePackageImportEntryFile = (fromFile, specifier) => {
@@ -13895,11 +14437,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13895
14437
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
13896
14438
  if (!entry)
13897
14439
  return null;
13898
- return join41(packageDir, entry);
14440
+ return join42(packageDir, entry);
13899
14441
  }, collectRuntimeRewriteRoots = (distDir) => collectFiles2(distDir).filter((filePath) => isRuntimeJsFile(filePath) && !isNodeModulesPath(filePath)), toTopLevelPackage = (specifier) => specifier.split("/").slice(0, specifier.startsWith("@") ? 2 : 1).join("/"), FRAMEWORK_PACKAGE_NAME = "@absolutejs/absolute", copyChunkReferencedPackages = (distDir, seen) => {
13900
14442
  const distRoot = resolve34(distDir);
13901
14443
  for (const filePath of collectRuntimeRewriteRoots(distDir)) {
13902
- if (resolve34(dirname24(filePath)) === distRoot)
14444
+ if (resolve34(dirname25(filePath)) === distRoot)
13903
14445
  continue;
13904
14446
  const source = readFileSync36(filePath, "utf-8");
13905
14447
  for (const match of source.matchAll(MODULE_SPECIFIER_RE)) {
@@ -13935,7 +14477,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13935
14477
  const { masked, restore } = maskLiterals(source);
13936
14478
  const rewrittenMasked = masked.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
13937
14479
  if (typeof specifier === "string" && specifier.startsWith(".")) {
13938
- enqueue(resolveRuntimeJsFile(resolve34(dirname24(filePath), specifier)));
14480
+ enqueue(resolveRuntimeJsFile(resolve34(dirname25(filePath), specifier)));
13939
14481
  return match;
13940
14482
  }
13941
14483
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -13964,12 +14506,12 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13964
14506
  "_compile_entrypoint.ts"
13965
14507
  ]);
13966
14508
  const embeddedFiles = allFiles.filter((file) => {
13967
- const rel = relative20(distDir, file);
14509
+ const rel = relative21(distDir, file);
13968
14510
  if (embeddedSkip.has(rel))
13969
14511
  return false;
13970
14512
  return true;
13971
14513
  });
13972
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative20(distDir, file), assetSkip));
14514
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative21(distDir, file), assetSkip));
13973
14515
  const imports = [];
13974
14516
  const nativeImports = [];
13975
14517
  const nativeMappings = [];
@@ -13984,14 +14526,14 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
13984
14526
  nativeMappings.push(` [${JSON.stringify(asset.env)}, resolveNativeAssetPath(${varName})],`);
13985
14527
  });
13986
14528
  embeddedFiles.forEach((filePath, idx) => {
13987
- const rel = relative20(distDir, filePath).replace(/\\/g, "/");
14529
+ const rel = relative21(distDir, filePath).replace(/\\/g, "/");
13988
14530
  const varName = `__a${idx}`;
13989
14531
  embeddedVarMap.set(rel, varName);
13990
14532
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
13991
14533
  embeddedMappings.push(` ["${rel}", ${varName}],`);
13992
14534
  });
13993
14535
  clientFiles.forEach((filePath) => {
13994
- const rel = relative20(distDir, filePath).replace(/\\/g, "/");
14536
+ const rel = relative21(distDir, filePath).replace(/\\/g, "/");
13995
14537
  const varName = embeddedVarMap.get(rel);
13996
14538
  if (!varName)
13997
14539
  return;
@@ -14005,7 +14547,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
14005
14547
  const pageVarMap = new Map;
14006
14548
  const prerenderEntries = Array.from(prerenderMap.entries());
14007
14549
  prerenderEntries.forEach(([route, filePath]) => {
14008
- const rel = relative20(distDir, filePath).replace(/\\/g, "/");
14550
+ const rel = relative21(distDir, filePath).replace(/\\/g, "/");
14009
14551
  const varName = embeddedVarMap.get(rel);
14010
14552
  if (varName)
14011
14553
  pageVarMap.set(route, varName);
@@ -14501,10 +15043,10 @@ console.log(\`
14501
15043
  ].filter((dir) => Boolean(dir));
14502
15044
  const islandRegistrySpec = buildConfig.islands?.registry;
14503
15045
  const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve34(islandRegistrySpec))) : undefined;
14504
- const serverBundleEntryDirectory = join41(resolvedOutdir, ".absolutejs-server-entry");
15046
+ const serverBundleEntryDirectory = join42(resolvedOutdir, ".absolutejs-server-entry");
14505
15047
  mkdirSync18(serverBundleEntryDirectory, { recursive: true });
14506
- const typeboxSetupEntry = join41(serverBundleEntryDirectory, "_typebox_setup.ts");
14507
- const serverBundleEntry = join41(serverBundleEntryDirectory, basename11(serverEntry));
15048
+ const typeboxSetupEntry = join42(serverBundleEntryDirectory, "_typebox_setup.ts");
15049
+ const serverBundleEntry = join42(serverBundleEntryDirectory, basename11(serverEntry));
14508
15050
  writeFileSync21(typeboxSetupEntry, `import { setupTypebox } from 'elysia';
14509
15051
  import * as compile from 'typebox/compile';
14510
15052
  import * as schema from 'typebox/schema';
@@ -14568,7 +15110,7 @@ export default server;
14568
15110
  if (scope !== "angular" || rest.length === 0)
14569
15111
  continue;
14570
15112
  const specifier = `@angular/${rest.join("/")}`;
14571
- const relPath = relative20(dirname24(outputPath), resolve34(vendorDir, file));
15113
+ const relPath = relative21(dirname25(outputPath), resolve34(vendorDir, file));
14572
15114
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
14573
15115
  }
14574
15116
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -14580,7 +15122,7 @@ export default server;
14580
15122
  copyServerRuntimeAssetReferences(resolvedOutdir);
14581
15123
  const prerenderStart = performance.now();
14582
15124
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
14583
- rmSync7(join41(resolvedOutdir, "_prerendered"), {
15125
+ rmSync7(join42(resolvedOutdir, "_prerendered"), {
14584
15126
  force: true,
14585
15127
  recursive: true
14586
15128
  });
@@ -14609,9 +15151,9 @@ export default server;
14609
15151
  const compileStart = performance.now();
14610
15152
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
14611
15153
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
14612
- const entrypointPath = join41(resolvedOutdir, "_compile_entrypoint.ts");
15154
+ const entrypointPath = join42(resolvedOutdir, "_compile_entrypoint.ts");
14613
15155
  await Bun.write(entrypointPath, entrypointCode);
14614
- mkdirSync18(dirname24(resolvedOutfile), { recursive: true });
15156
+ mkdirSync18(dirname25(resolvedOutfile), { recursive: true });
14615
15157
  const result = await Bun.build({
14616
15158
  compile: { outfile: resolvedOutfile },
14617
15159
  define: { "process.env.NODE_ENV": '"production"' },
@@ -14692,15 +15234,15 @@ var init_compile = __esm(() => {
14692
15234
  });
14693
15235
 
14694
15236
  // src/mobile/nativeDeepLinks.ts
14695
- import { readFile as readFile10, rename as rename7, writeFile as writeFile7 } from "fs/promises";
14696
- import { join as join42 } from "path";
15237
+ import { readFile as readFile11, rename as rename8, writeFile as writeFile8 } from "fs/promises";
15238
+ import { join as join43 } from "path";
14697
15239
  var START_MARKER = "<!-- absolutejs:deep-links:start -->", END_MARKER = "<!-- absolutejs:deep-links:end -->", IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements", NOT_FOUND = -1, escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;"), writeChangedFile = async (path, source) => {
14698
- const current = await readFile10(path, "utf8");
15240
+ const current = await readFile11(path, "utf8");
14699
15241
  if (current === source)
14700
15242
  return false;
14701
15243
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
14702
- await writeFile7(temporary, source, { flag: "wx" });
14703
- await rename7(temporary, path);
15244
+ await writeFile8(temporary, source, { flag: "wx" });
15245
+ await rename8(temporary, path);
14704
15246
  return true;
14705
15247
  }, replaceManagedRegion = (source, region, insertAt) => {
14706
15248
  const start2 = source.indexOf(START_MARKER);
@@ -14742,8 +15284,8 @@ ${hosts}
14742
15284
  ${END_MARKER}
14743
15285
  `;
14744
15286
  }, configureAndroid = async (config) => {
14745
- const path = join42(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
14746
- const source = await readFile10(path, "utf8");
15287
+ const path = join43(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
15288
+ const source = await readFile11(path, "utf8");
14747
15289
  const mainActivity = source.indexOf('android:name=".MainActivity"');
14748
15290
  if (mainActivity === NOT_FOUND) {
14749
15291
  throw new TypeError("Android MainActivity was not found.");
@@ -14766,8 +15308,8 @@ ${hosts}
14766
15308
  </array>
14767
15309
  ${END_MARKER}
14768
15310
  `, configureIosInfo = async (config) => {
14769
- const path = join42(config.nativeProjectDirectory, "ios/App/App/Info.plist");
14770
- const source = await readFile10(path, "utf8");
15311
+ const path = join43(config.nativeProjectDirectory, "ios/App/App/Info.plist");
15312
+ const source = await readFile11(path, "utf8");
14771
15313
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
14772
15314
  ${END_MARKER}
14773
15315
  `;
@@ -14788,10 +15330,10 @@ ${domains}
14788
15330
  </plist>
14789
15331
  `;
14790
15332
  }, configureIosEntitlements = async (config) => {
14791
- const path = join42(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
15333
+ const path = join43(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
14792
15334
  let current = "";
14793
15335
  try {
14794
- current = await readFile10(path, "utf8");
15336
+ current = await readFile11(path, "utf8");
14795
15337
  } catch (error) {
14796
15338
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
14797
15339
  throw error;
@@ -14801,12 +15343,12 @@ ${domains}
14801
15343
  if (current === source)
14802
15344
  return false;
14803
15345
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
14804
- await writeFile7(temporary, source, { flag: "wx" });
14805
- await rename7(temporary, path);
15346
+ await writeFile8(temporary, source, { flag: "wx" });
15347
+ await rename8(temporary, path);
14806
15348
  return true;
14807
15349
  }, configureIosProject = async (config) => {
14808
- const path = join42(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
14809
- const source = await readFile10(path, "utf8");
15350
+ const path = join43(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
15351
+ const source = await readFile11(path, "utf8");
14810
15352
  const declarations = [
14811
15353
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
14812
15354
  ].map((match) => match[1]);
@@ -14846,11 +15388,11 @@ var init_nativeDeepLinks = () => {};
14846
15388
  // src/mobile/associationFiles.ts
14847
15389
  import {
14848
15390
  access as access7,
14849
- mkdir as mkdir8,
14850
- readFile as readFile11,
14851
- rename as rename8,
15391
+ mkdir as mkdir9,
15392
+ readFile as readFile12,
15393
+ rename as rename9,
14852
15394
  rm as rm7,
14853
- writeFile as writeFile8
15395
+ writeFile as writeFile9
14854
15396
  } from "fs/promises";
14855
15397
  import { resolve as resolve35 } from "path";
14856
15398
  import { Elysia } from "elysia";
@@ -14905,7 +15447,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
14905
15447
  }, writeAtomic = async (path, source) => {
14906
15448
  let current;
14907
15449
  try {
14908
- current = await readFile11(path, "utf8");
15450
+ current = await readFile12(path, "utf8");
14909
15451
  } catch (error) {
14910
15452
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
14911
15453
  throw error;
@@ -14914,8 +15456,8 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
14914
15456
  if (current === source)
14915
15457
  return false;
14916
15458
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
14917
- await writeFile8(temporary, source, { flag: "wx" });
14918
- await rename8(temporary, path);
15459
+ await writeFile9(temporary, source, { flag: "wx" });
15460
+ await rename9(temporary, path);
14919
15461
  return true;
14920
15462
  }, exists2 = async (path) => {
14921
15463
  try {
@@ -14928,7 +15470,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
14928
15470
  const path = resolve35(root, OWNERSHIP_FILE);
14929
15471
  let ownership;
14930
15472
  try {
14931
- ownership = JSON.parse(await readFile11(path, "utf8"));
15473
+ ownership = JSON.parse(await readFile12(path, "utf8"));
14932
15474
  } catch {
14933
15475
  throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
14934
15476
  }
@@ -14941,19 +15483,19 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
14941
15483
  await assertOwnedOutput(root);
14942
15484
  const backup = `${root}.${crypto.randomUUID()}.previous`;
14943
15485
  if (hasCurrent)
14944
- await rename8(root, backup);
15486
+ await rename9(root, backup);
14945
15487
  try {
14946
- await rename8(temporary, root);
15488
+ await rename9(temporary, root);
14947
15489
  } catch (error) {
14948
15490
  if (hasCurrent)
14949
- await rename8(backup, root);
15491
+ await rename9(backup, root);
14950
15492
  throw error;
14951
15493
  }
14952
15494
  if (hasCurrent)
14953
15495
  await rm7(backup, { force: true, recursive: true });
14954
15496
  }, materializeHost = async (root, host, files) => {
14955
15497
  const directory = resolve35(root, host, ".well-known");
14956
- await mkdir8(directory, { recursive: true });
15498
+ await mkdir9(directory, { recursive: true });
14957
15499
  return Promise.all(files.map(async ([name, document]) => {
14958
15500
  const path = resolve35(directory, name);
14959
15501
  await writeAtomic(path, `${JSON.stringify(document, null, 2)}
@@ -14989,7 +15531,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
14989
15531
  if (documents.apple) {
14990
15532
  files.push(["apple-app-site-association", documents.apple]);
14991
15533
  }
14992
- await mkdir8(temporary, { recursive: true });
15534
+ await mkdir9(temporary, { recursive: true });
14993
15535
  try {
14994
15536
  const temporaryPaths = (await Promise.all(config.deepLinkHosts.map((host) => materializeHost(temporary, host, files)))).flat();
14995
15537
  await writeAtomic(resolve35(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
@@ -15036,8 +15578,8 @@ var init_associationFiles = __esm(() => {
15036
15578
  });
15037
15579
 
15038
15580
  // src/mobile/androidWebView.ts
15039
- import { mkdir as mkdir9, writeFile as writeFile9 } from "fs/promises";
15040
- import { dirname as dirname25, resolve as resolve36 } from "path";
15581
+ import { mkdir as mkdir10, writeFile as writeFile10 } from "fs/promises";
15582
+ import { dirname as dirname26, resolve as resolve36 } from "path";
15041
15583
 
15042
15584
  class CdpConnection {
15043
15585
  diagnostics = [];
@@ -15309,8 +15851,8 @@ var CDP_COMMAND_TIMEOUT_MS = 1e4, WEBVIEW_ATTACH_TIMEOUT_MS = 30000, WEBVIEW_POL
15309
15851
  throw new Error("Android WebView screenshot returned no image data.");
15310
15852
  }
15311
15853
  const absolutePath = resolve36(path);
15312
- await mkdir9(dirname25(absolutePath), { recursive: true });
15313
- await writeFile9(absolutePath, Buffer.from(data, "base64"));
15854
+ await mkdir10(dirname26(absolutePath), { recursive: true });
15855
+ await writeFile10(absolutePath, Buffer.from(data, "base64"));
15314
15856
  return absolutePath;
15315
15857
  }
15316
15858
  };
@@ -15428,8 +15970,8 @@ var DEFAULT_ROUTE_TIMEOUT_MS = 30000, DEFAULT_HMR_TIMEOUT_MS = 30000, routeExpre
15428
15970
  };
15429
15971
 
15430
15972
  // src/mobile/releaseDoctor.ts
15431
- import { access as access8, readFile as readFile12, readdir as readdir4 } from "fs/promises";
15432
- import { extname as extname6, join as join43, relative as relative21 } from "path";
15973
+ import { access as access8, readFile as readFile13, readdir as readdir4 } from "fs/promises";
15974
+ import { extname as extname6, join as join44, relative as relative22 } from "path";
15433
15975
  var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15434
15976
  try {
15435
15977
  await access8(path);
@@ -15442,13 +15984,13 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15442
15984
  return findHmrAsset(path);
15443
15985
  if (!isFile2 || !RELEASE_ASSET_EXTENSIONS.has(extname6(path)))
15444
15986
  return;
15445
- const source = await readFile12(path, "utf8");
15987
+ const source = await readFile13(path, "utf8");
15446
15988
  return HMR_ASSET_PATTERN.test(source) ? path : undefined;
15447
15989
  }, findHmrAsset = async (root) => {
15448
15990
  if (!await pathExists5(root))
15449
15991
  return;
15450
15992
  const entries = await readdir4(root, { withFileTypes: true });
15451
- const matches = await Promise.all(entries.map((entry) => inspectReleaseAsset(join43(root, entry.name), entry.isDirectory(), entry.isFile())));
15993
+ const matches = await Promise.all(entries.map((entry) => inspectReleaseAsset(join44(root, entry.name), entry.isDirectory(), entry.isFile())));
15452
15994
  return matches.find((match) => match !== undefined);
15453
15995
  }, pass = (id, detail, path) => ({ detail, id, path, status: "pass" }), fail5 = (id, detail, path, remediation) => ({
15454
15996
  detail,
@@ -15481,23 +16023,23 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15481
16023
  if (!await pathExists5(nativeConfigPath)) {
15482
16024
  return fail5("android.capacitor-config", "The generated Android Capacitor config is missing.", nativeConfigPath, "Run `absolute mobile sync android` before release validation.");
15483
16025
  }
15484
- const unsafe = isUnsafeCapacitorConfig(await readFile12(nativeConfigPath, "utf8"));
16026
+ const unsafe = isUnsafeCapacitorConfig(await readFile13(nativeConfigPath, "utf8"));
15485
16027
  return unsafe ? fail5("android.capacitor-config", "Android Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.", nativeConfigPath, "Run `absolute mobile sync android`; do not ship development transport overrides.") : pass("android.capacitor-config", "Android Capacitor config contains no development transport overrides.", nativeConfigPath);
15486
16028
  }, manifestReleaseCheck = async (manifestPath) => {
15487
16029
  if (!await pathExists5(manifestPath)) {
15488
16030
  return fail5("android.cleartext", "The Android manifest is missing.", manifestPath, "Run `absolute mobile sync android` before release validation.");
15489
16031
  }
15490
- const source = await readFile12(manifestPath, "utf8");
16032
+ const source = await readFile13(manifestPath, "utf8");
15491
16033
  return /android:usesCleartextTraffic=["']true["']/u.test(source) ? fail5("android.cleartext", "Android explicitly permits cleartext traffic.", manifestPath, 'Remove usesCleartextTraffic="true" from the release manifest.') : pass("android.cleartext", "Android does not explicitly permit cleartext traffic.", manifestPath);
15492
16034
  }, hmrAssetsReleaseCheck = async (publicRoot) => {
15493
16035
  const hmrAsset = await findHmrAsset(publicRoot);
15494
16036
  return hmrAsset ? fail5("android.hmr-assets", "A packaged Android asset contains the development HMR client.", hmrAsset, "Rebuild the production mobile bundle and run Capacitor sync again.") : pass("android.hmr-assets", "Packaged Android assets contain no development HMR markers.", publicRoot);
15495
16037
  }, inspectAndroidRelease = async (config, projectRoot) => {
15496
- const androidRoot = join43(config.nativeProjectDirectory, "android");
15497
- const nativeConfigPath = join43(androidRoot, "app", "src", "main", "assets", "capacitor.config.json");
15498
- const manifestPath = join43(androidRoot, "app", "src", "main", "AndroidManifest.xml");
15499
- const publicRoot = join43(androidRoot, "app", "src", "main", "assets", "public");
15500
- const journalPath = join43(projectRoot, ".absolutejs", "mobile", "dev-session", "journal.json");
16038
+ const androidRoot = join44(config.nativeProjectDirectory, "android");
16039
+ const nativeConfigPath = join44(androidRoot, "app", "src", "main", "assets", "capacitor.config.json");
16040
+ const manifestPath = join44(androidRoot, "app", "src", "main", "AndroidManifest.xml");
16041
+ const publicRoot = join44(androidRoot, "app", "src", "main", "assets", "public");
16042
+ const journalPath = join44(projectRoot, ".absolutejs", "mobile", "dev-session", "journal.json");
15501
16043
  const checks = await Promise.all([
15502
16044
  journalReleaseCheck(journalPath, "android"),
15503
16045
  capacitorConfigReleaseCheck(nativeConfigPath),
@@ -15506,14 +16048,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15506
16048
  ]);
15507
16049
  return checks.map((check2) => ({
15508
16050
  ...check2,
15509
- path: check2.path ? relative21(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
16051
+ path: check2.path ? relative22(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
15510
16052
  }));
15511
16053
  }, inspectIosRelease = async (config, projectRoot) => {
15512
- const iosAppRoot = join43(config.nativeProjectDirectory, "ios", "App", "App");
15513
- const nativeConfigPath = join43(iosAppRoot, "capacitor.config.json");
15514
- const infoPath = join43(iosAppRoot, "Info.plist");
15515
- const publicRoot = join43(iosAppRoot, "public");
15516
- const journalPath = join43(projectRoot, ".absolutejs", "mobile", "ios-dev-session", "journal.json");
16054
+ const iosAppRoot = join44(config.nativeProjectDirectory, "ios", "App", "App");
16055
+ const nativeConfigPath = join44(iosAppRoot, "capacitor.config.json");
16056
+ const infoPath = join44(iosAppRoot, "Info.plist");
16057
+ const publicRoot = join44(iosAppRoot, "public");
16058
+ const journalPath = join44(projectRoot, ".absolutejs", "mobile", "ios-dev-session", "journal.json");
15517
16059
  const checks = [
15518
16060
  await journalReleaseCheck(journalPath, "ios")
15519
16061
  ];
@@ -15524,7 +16066,7 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15524
16066
  }
15525
16067
  if (!await pathExists5(nativeConfigPath)) {
15526
16068
  checks.push(fail5("ios.capacitor-config", "The generated iOS Capacitor config is missing.", nativeConfigPath, "Run `absolute mobile sync ios` before release validation."));
15527
- } else if (isUnsafeCapacitorConfig(await readFile12(nativeConfigPath, "utf8"))) {
16069
+ } else if (isUnsafeCapacitorConfig(await readFile13(nativeConfigPath, "utf8"))) {
15528
16070
  checks.push(fail5("ios.capacitor-config", "iOS Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.", nativeConfigPath, "Run `absolute mobile sync ios`; do not ship development transport overrides."));
15529
16071
  } else {
15530
16072
  checks.push(pass("ios.capacitor-config", "iOS Capacitor config contains no development transport overrides.", nativeConfigPath));
@@ -15532,14 +16074,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
15532
16074
  if (!await pathExists5(infoPath)) {
15533
16075
  checks.push(fail5("ios.transport-security", "The iOS Info.plist is missing.", infoPath, "Run `absolute mobile sync ios` before release validation."));
15534
16076
  } else {
15535
- const info2 = await readFile12(infoPath, "utf8");
16077
+ const info2 = await readFile13(infoPath, "utf8");
15536
16078
  checks.push(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(info2) ? fail5("ios.transport-security", "iOS App Transport Security permits arbitrary network loads.", infoPath, "Remove NSAllowsArbitraryLoads from the release Info.plist.") : pass("ios.transport-security", "iOS App Transport Security does not permit arbitrary loads.", infoPath));
15537
16079
  }
15538
16080
  const hmrAsset = await findHmrAsset(publicRoot);
15539
16081
  checks.push(hmrAsset ? fail5("ios.hmr-assets", "A packaged iOS asset contains the development HMR client.", hmrAsset, "Rebuild the production mobile bundle and run Capacitor sync again.") : pass("ios.hmr-assets", "Packaged iOS assets contain no development HMR markers.", publicRoot));
15540
16082
  return checks.map((check2) => ({
15541
16083
  ...check2,
15542
- path: check2.path ? relative21(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
16084
+ path: check2.path ? relative22(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
15543
16085
  }));
15544
16086
  }, inspectAbsoluteMobileRelease = async (config, projectRoot) => {
15545
16087
  const checks = config.platforms.includes("android") ? await inspectAndroidRelease(config, projectRoot) : [];
@@ -15557,19 +16099,19 @@ var init_releaseDoctor = __esm(() => {
15557
16099
  });
15558
16100
 
15559
16101
  // src/mobile/androidRelease.ts
15560
- import { createHash as createHash11 } from "crypto";
16102
+ import { createHash as createHash12 } from "crypto";
15561
16103
  import {
15562
16104
  access as access9,
15563
16105
  copyFile as copyFile5,
15564
- mkdir as mkdir10,
16106
+ mkdir as mkdir11,
15565
16107
  mkdtemp as mkdtemp5,
15566
- readFile as readFile13,
15567
- rename as rename9,
16108
+ readFile as readFile14,
16109
+ rename as rename10,
15568
16110
  rm as rm8,
15569
16111
  stat as stat2,
15570
- writeFile as writeFile10
16112
+ writeFile as writeFile11
15571
16113
  } from "fs/promises";
15572
- import { dirname as dirname26, isAbsolute as isAbsolute6, join as join44, relative as relative22, resolve as resolve37, sep as sep5 } from "path";
16114
+ import { dirname as dirname27, isAbsolute as isAbsolute7, join as join45, relative as relative23, resolve as resolve37, sep as sep6 } from "path";
15573
16115
  var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifest2 = (value) => {
15574
16116
  if (!isRecord13(value) || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.runtime !== "string") {
15575
16117
  throw new TypeError("Invalid embedded AbsoluteJS mobile manifest.");
@@ -15619,20 +16161,20 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
15619
16161
  artifactPath
15620
16162
  ]);
15621
16163
  return result.exitCode === 0 && /jar verified/iu.test(result.stdout);
15622
- }, sha256File2 = async (path) => createHash11("sha256").update(await readFile13(path)).digest("hex"), safeOutputDirectory2 = (projectRoot, requested) => {
16164
+ }, sha256File2 = async (path) => createHash12("sha256").update(await readFile14(path)).digest("hex"), safeOutputDirectory2 = (projectRoot, requested) => {
15623
16165
  const root = resolve37(projectRoot);
15624
16166
  const output = resolve37(root, requested ?? ".absolutejs/mobile/releases/android");
15625
- const projectRelative = relative22(root, output);
15626
- if (projectRelative === ".." || projectRelative.startsWith(`..${sep5}`) || isAbsolute6(projectRelative)) {
16167
+ const projectRelative = relative23(root, output);
16168
+ if (projectRelative === ".." || projectRelative.startsWith(`..${sep6}`) || isAbsolute7(projectRelative)) {
15627
16169
  throw new TypeError("mobile build --outdir must remain inside the project.");
15628
16170
  }
15629
16171
  return output;
15630
16172
  }, installRelease2 = async (artifactPath, metadata, outputRoot) => {
15631
- const releaseRoot = join44(outputRoot, metadata.releaseId);
16173
+ const releaseRoot = join45(outputRoot, metadata.releaseId);
15632
16174
  const artifactName = "app-release.aab";
15633
- const destination = join44(releaseRoot, artifactName);
16175
+ const destination = join45(releaseRoot, artifactName);
15634
16176
  if (await pathExists6(releaseRoot)) {
15635
- const existing = requireManifestIdentity(JSON.parse(await readFile13(join44(releaseRoot, "release.json"), "utf8")), metadata);
16177
+ const existing = requireManifestIdentity(JSON.parse(await readFile14(join45(releaseRoot, "release.json"), "utf8")), metadata);
15636
16178
  const [installedBytes, installedSha256] = await Promise.all([
15637
16179
  stat2(destination).then(({ size }) => size),
15638
16180
  sha256File2(destination)
@@ -15642,17 +16184,17 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
15642
16184
  }
15643
16185
  return { artifactPath: destination, metadata: existing, releaseRoot };
15644
16186
  }
15645
- await mkdir10(dirname26(releaseRoot), { recursive: true });
15646
- const staging = await mkdtemp5(join44(dirname26(releaseRoot), ".android-stage-"));
16187
+ await mkdir11(dirname27(releaseRoot), { recursive: true });
16188
+ const staging = await mkdtemp5(join45(dirname27(releaseRoot), ".android-stage-"));
15647
16189
  try {
15648
- await copyFile5(artifactPath, join44(staging, artifactName));
16190
+ await copyFile5(artifactPath, join45(staging, artifactName));
15649
16191
  const complete = {
15650
16192
  ...metadata,
15651
16193
  artifact: artifactName
15652
16194
  };
15653
- await writeFile10(join44(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
16195
+ await writeFile11(join45(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
15654
16196
  `, { flag: "wx" });
15655
- await rename9(staging, releaseRoot);
16197
+ await rename10(staging, releaseRoot);
15656
16198
  return { artifactPath: destination, metadata: complete, releaseRoot };
15657
16199
  } finally {
15658
16200
  await rm8(staging, { force: true, recursive: true }).catch(() => {
@@ -15678,15 +16220,15 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
15678
16220
  const projectRoot = resolve37(options.projectRoot);
15679
16221
  const host = options.host ?? detectAbsoluteMobileHost();
15680
16222
  const androidRoot = options.androidRoot ?? process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host);
15681
- const nativeDirectory = join44(options.config.nativeProjectDirectory, "android");
15682
- const manifest = requireManifest2(JSON.parse(await readFile13(join44(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
16223
+ const nativeDirectory = join45(options.config.nativeProjectDirectory, "android");
16224
+ const manifest = requireManifest2(JSON.parse(await readFile14(join45(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
15683
16225
  if (manifest.appId !== options.config.appId) {
15684
16226
  throw new TypeError("Embedded mobile manifest appId does not match mobile.appId.");
15685
16227
  }
15686
16228
  let { versionCode } = options;
15687
16229
  if (options.prepareVersionCode) {
15688
16230
  const nativeFingerprint = await fingerprintAbsoluteAndroidNativeProject({ nativeDirectory });
15689
- const buildIdentity = createHash11("sha256").update(`${manifest.appBuild}\x00${nativeFingerprint}`).digest("hex");
16231
+ const buildIdentity = createHash12("sha256").update(`${manifest.appBuild}\x00${nativeFingerprint}`).digest("hex");
15690
16232
  versionCode = await options.prepareVersionCode(buildIdentity);
15691
16233
  }
15692
16234
  if (versionCode !== undefined && (!Number.isSafeInteger(versionCode) || versionCode < 1 || versionCode > 2100000000)) {
@@ -15743,7 +16285,7 @@ var init_androidRelease = __esm(() => {
15743
16285
  });
15744
16286
 
15745
16287
  // src/mobile/iosConformance.ts
15746
- import { readFile as readFile14, stat as stat3 } from "fs/promises";
16288
+ import { readFile as readFile15, stat as stat3 } from "fs/promises";
15747
16289
  var HMR_LINE, parseAbsoluteIosHmrLog = (line) => {
15748
16290
  const match = HMR_LINE.exec(line);
15749
16291
  if (!match)
@@ -15778,7 +16320,7 @@ var HMR_LINE, parseAbsoluteIosHmrLog = (line) => {
15778
16320
  if (Date.now() > deadline)
15779
16321
  throw new Error(`No iOS native HMR acknowledgement was observed within ${timeoutMs}ms.`);
15780
16322
  options.signal?.throwIfAborted();
15781
- const contents = await readFile14(options.logPath).catch(() => Buffer.alloc(0));
16323
+ const contents = await readFile15(options.logPath).catch(() => Buffer.alloc(0));
15782
16324
  if (contents.byteLength < offset) {
15783
16325
  offset = 0;
15784
16326
  buffered = "";
@@ -15803,7 +16345,7 @@ var init_iosConformance = __esm(() => {
15803
16345
 
15804
16346
  // src/mobile/releasePublisher.ts
15805
16347
  import { access as access10 } from "fs/promises";
15806
- import { isAbsolute as isAbsolute7, relative as relative23, resolve as resolve38, sep as sep6 } from "path";
16348
+ import { isAbsolute as isAbsolute8, relative as relative24, resolve as resolve38, sep as sep7 } from "path";
15807
16349
  import { pathToFileURL as pathToFileURL2 } from "url";
15808
16350
  var prepareAbsoluteIosRelease = async (publisher, options) => {
15809
16351
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -15827,8 +16369,8 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
15827
16369
  }, isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isPublisher = (value) => isRecord14(value) && typeof value.publish === "function", publisherModulePath = (projectRoot, requested) => {
15828
16370
  const root = resolve38(projectRoot);
15829
16371
  const path = resolve38(root, requested);
15830
- const projectRelative = relative23(root, path);
15831
- if (projectRelative === ".." || projectRelative.startsWith(`..${sep6}`) || isAbsolute7(projectRelative)) {
16372
+ const projectRelative = relative24(root, path);
16373
+ if (projectRelative === ".." || projectRelative.startsWith(`..${sep7}`) || isAbsolute8(projectRelative)) {
15832
16374
  throw new TypeError("mobile publish --registry must remain inside the project.");
15833
16375
  }
15834
16376
  return path;
@@ -15899,8 +16441,8 @@ var exports_mobile = {};
15899
16441
  __export(exports_mobile, {
15900
16442
  runMobile: () => runMobile
15901
16443
  });
15902
- import { access as access11, mkdir as mkdir11, writeFile as writeFile11 } from "fs/promises";
15903
- import { join as join45, resolve as resolve39 } from "path";
16444
+ import { access as access11, mkdir as mkdir12, writeFile as writeFile12 } from "fs/promises";
16445
+ import { join as join46, resolve as resolve39 } from "path";
15904
16446
  import { createInterface } from "readline/promises";
15905
16447
  var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, valueAfter = (args, flag) => {
15906
16448
  const index = args.indexOf(flag);
@@ -15914,7 +16456,7 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
15914
16456
  }
15915
16457
  return value;
15916
16458
  }, capacitorExecutable = async (projectRoot) => {
15917
- const executable = join45(projectRoot, "node_modules", ".bin", "cap");
16459
+ const executable = join46(projectRoot, "node_modules", ".bin", "cap");
15918
16460
  try {
15919
16461
  await access11(executable);
15920
16462
  return executable;
@@ -15938,6 +16480,41 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
15938
16480
  const config = await loadConfig(configPath2);
15939
16481
  const mobile = normalizeAbsoluteMobileConfig(requireMobileConfig(config.mobile), projectRoot);
15940
16482
  return { mobile, projectRoot };
16483
+ }, remoteProfilePath = () => process.env.ABSOLUTE_REMOTE_MAC_PROFILE_PATH || undefined, pairRemoteMac = async (args) => {
16484
+ if (args[0] !== "mac" || !args[1] || !args[2])
16485
+ throw new TypeError("Usage: absolute mobile pair mac <name> <user@host> [--port n] [--workspace path]");
16486
+ const portValue = valueAfter(args, "--port");
16487
+ const port = portValue === undefined ? undefined : Number(portValue);
16488
+ const profile = await pairAbsoluteRemoteMac({
16489
+ destination: args[2],
16490
+ name: args[1],
16491
+ ...port === undefined ? {} : { port },
16492
+ profilePath: remoteProfilePath(),
16493
+ workspaceRoot: valueAfter(args, "--workspace")
16494
+ });
16495
+ sendTelemetryEvent("mobile:remote-mac-paired", {
16496
+ platform: "ios",
16497
+ provider: "ssh"
16498
+ });
16499
+ console.log(`Paired remote Mac ${profile.name} (${profile.xcodeVersion}) and selected it as the default iOS development host.`);
16500
+ }, listRemoteMacs = async (args) => {
16501
+ const result = await listAbsoluteRemoteMacProfiles(remoteProfilePath());
16502
+ if (args.includes("--json")) {
16503
+ console.log(JSON.stringify(result, null, 2));
16504
+ return;
16505
+ }
16506
+ if (result.profiles.length === 0) {
16507
+ console.log("No remote Macs are paired. Run `absolute mobile pair mac <name> <user@host>`.");
16508
+ return;
16509
+ }
16510
+ for (const profile of result.profiles) {
16511
+ console.log(`${profile.name === result.defaultProfile ? "* " : " "}${profile.name} ${profile.destination} ${profile.xcodeVersion}`);
16512
+ }
16513
+ }, unpairRemoteMac = async (args) => {
16514
+ if (args[0] !== "mac" || !args[1])
16515
+ throw new TypeError("Usage: absolute mobile unpair mac <name>");
16516
+ const removed = await removeAbsoluteRemoteMacProfile(args[1], remoteProfilePath());
16517
+ console.log(removed ? `Removed remote Mac profile ${args[1]}.` : `Remote Mac profile ${args[1]} was not found.`);
15941
16518
  }, initialize = async (args) => {
15942
16519
  const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
15943
16520
  const generated = await writeAbsoluteCapacitorConfig(mobile, {
@@ -16188,7 +16765,7 @@ Mobile release transport checks failed.`);
16188
16765
  const durationMs = Math.round(performance.now() - startedAt);
16189
16766
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} Android App Bundle in ${getDurationString(durationMs)}.`);
16190
16767
  console.log(`Artifact: ${release.artifactPath}`);
16191
- console.log(`Metadata: ${join45(release.releaseRoot, "release.json")}`);
16768
+ console.log(`Metadata: ${join46(release.releaseRoot, "release.json")}`);
16192
16769
  return release;
16193
16770
  } finally {
16194
16771
  sendTelemetryEvent("mobile:android-release-build", {
@@ -16287,7 +16864,7 @@ Mobile release transport checks failed.`);
16287
16864
  const durationMs = Math.round(performance.now() - startedAt);
16288
16865
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} iOS IPA ${release.metadata.marketingVersion}${release.metadata.buildNumber ? ` (${release.metadata.buildNumber})` : ""} in ${getDurationString(durationMs)}.`);
16289
16866
  console.log(`Artifact: ${release.artifactPath}`);
16290
- console.log(`Metadata: ${join45(release.releaseRoot, "release.json")}`);
16867
+ console.log(`Metadata: ${join46(release.releaseRoot, "release.json")}`);
16291
16868
  return release;
16292
16869
  } finally {
16293
16870
  sendTelemetryEvent("mobile:ios-release-build", {
@@ -16349,13 +16926,62 @@ Mobile release transport checks failed.`);
16349
16926
  unsignedAllowed: args.includes("--unsigned")
16350
16927
  });
16351
16928
  }
16929
+ }, inspectRemoteMacForDoctor = async (profile) => {
16930
+ try {
16931
+ const inspection = await inspectAbsoluteRemoteMac(profile.destination, {
16932
+ port: profile.port
16933
+ });
16934
+ return [
16935
+ {
16936
+ id: "ios.remote-ssh",
16937
+ label: `Remote Mac ${profile.name} is reachable`,
16938
+ platform: "ios",
16939
+ status: "pass"
16940
+ },
16941
+ {
16942
+ id: "ios.remote-bun",
16943
+ label: `Remote Bun ${inspection.bunPath}`,
16944
+ path: inspection.bunPath,
16945
+ platform: "ios",
16946
+ status: "pass"
16947
+ },
16948
+ {
16949
+ id: "ios.remote-xcode",
16950
+ label: inspection.xcodeVersion,
16951
+ platform: "ios",
16952
+ status: "pass"
16953
+ }
16954
+ ];
16955
+ } catch (error) {
16956
+ return [
16957
+ {
16958
+ id: "ios.remote-ssh",
16959
+ label: `Remote Mac ${profile.name} is unavailable`,
16960
+ platform: "ios",
16961
+ remediation: error instanceof Error ? error.message : String(error),
16962
+ status: "fail"
16963
+ }
16964
+ ];
16965
+ }
16352
16966
  }, doctor = async (args) => {
16353
16967
  if (args.includes("release")) {
16354
16968
  await runReleaseDoctor(args);
16355
16969
  return;
16356
16970
  }
16357
- const checks = await inspectAbsoluteMobileToolchain();
16358
16971
  const platform6 = args.find((value) => value === "android" || value === "ios");
16972
+ const requestedRemote = valueAfter(args, "--remote");
16973
+ const remoteProfile = platform6 === "ios" && (requestedRemote !== undefined || process.platform !== "darwin") ? await getAbsoluteRemoteMacProfile(requestedRemote, remoteProfilePath()) : undefined;
16974
+ if (remoteProfile) {
16975
+ if (args.includes("--fix"))
16976
+ throw new TypeError("Remote Mac doctor is read-only. Configure Xcode or Bun on the Mac, then rerun doctor.");
16977
+ const selected2 = await inspectRemoteMacForDoctor(remoteProfile);
16978
+ if (args.includes("--json"))
16979
+ console.log(JSON.stringify({ checks: selected2 }, null, 2));
16980
+ else
16981
+ printDoctorChecks(selected2);
16982
+ return;
16983
+ }
16984
+ const checks = await inspectAbsoluteMobileToolchain();
16359
16985
  const selected = platform6 ? checks.filter((check2) => check2.platform === "host" || check2.platform === platform6) : checks;
16360
16986
  if (args.includes("--json")) {
16361
16987
  if (args.includes("--fix")) {
@@ -16483,12 +17109,12 @@ Emulator setup verification:`);
16483
17109
  timeoutMs
16484
17110
  });
16485
17111
  }, writeAndroidFailureArtifacts = async (options) => {
16486
- await mkdir11(options.artifactRoot, { recursive: true });
16487
- const screenshot = options.session ? await options.session.screenshot(join45(options.artifactRoot, "android-failure.png")).catch(() => {
17112
+ await mkdir12(options.artifactRoot, { recursive: true });
17113
+ const screenshot = options.session ? await options.session.screenshot(join46(options.artifactRoot, "android-failure.png")).catch(() => {
16488
17114
  return;
16489
17115
  }) : undefined;
16490
- const diagnosticPath = join45(options.artifactRoot, "android-failure.json");
16491
- await writeFile11(diagnosticPath, `${JSON.stringify({
17116
+ const diagnosticPath = join46(options.artifactRoot, "android-failure.json");
17117
+ await writeFile12(diagnosticPath, `${JSON.stringify({
16492
17118
  diagnostics: options.session?.diagnostics ?? [],
16493
17119
  error: options.error instanceof Error ? options.error.message : String(options.error),
16494
17120
  platform: "android",
@@ -16664,8 +17290,8 @@ Emulator setup verification:`);
16664
17290
  throw new Error(`${label} failed: ${result.stderr.trim() || result.stdout.trim() || `status ${result.exitCode}`}`);
16665
17291
  return result;
16666
17292
  }, writeIosFailureArtifacts = async (options) => {
16667
- await mkdir11(options.artifactRoot, { recursive: true });
16668
- const screenshot = join45(options.artifactRoot, "ios-failure.png");
17293
+ await mkdir12(options.artifactRoot, { recursive: true });
17294
+ const screenshot = join46(options.artifactRoot, "ios-failure.png");
16669
17295
  const screenshotResult = captureCommand4([
16670
17296
  options.xcrun,
16671
17297
  "simctl",
@@ -16674,8 +17300,8 @@ Emulator setup verification:`);
16674
17300
  "screenshot",
16675
17301
  screenshot
16676
17302
  ]);
16677
- const diagnosticPath = join45(options.artifactRoot, "ios-failure.json");
16678
- await writeFile11(diagnosticPath, `${JSON.stringify({
17303
+ const diagnosticPath = join46(options.artifactRoot, "ios-failure.json");
17304
+ await writeFile12(diagnosticPath, `${JSON.stringify({
16679
17305
  appId: options.appId,
16680
17306
  error: options.error instanceof Error ? options.error.message : String(options.error),
16681
17307
  platform: "ios",
@@ -16719,8 +17345,8 @@ Emulator setup verification:`);
16719
17345
  mobile.appId
16720
17346
  ], "iOS app launch");
16721
17347
  await waitForIosHmrClient({ https, port, timeoutMs });
16722
- await mkdir11(artifactRoot, { recursive: true });
16723
- const screenshot = join45(artifactRoot, "ios-simulator.png");
17348
+ await mkdir12(artifactRoot, { recursive: true });
17349
+ const screenshot = join46(artifactRoot, "ios-simulator.png");
16724
17350
  requireCapturedIosCommand([xcrun, "simctl", "io", simulator.udid, "screenshot", screenshot], "iOS simulator screenshot");
16725
17351
  const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
16726
17352
  const report = {
@@ -16765,6 +17391,18 @@ Emulator setup verification:`);
16765
17391
  }
16766
17392
  }, runMobile = async (args) => {
16767
17393
  const [command] = args;
17394
+ if (command === "pair") {
17395
+ await pairRemoteMac(args.slice(1));
17396
+ return;
17397
+ }
17398
+ if (command === "remotes") {
17399
+ await listRemoteMacs(args.slice(1));
17400
+ return;
17401
+ }
17402
+ if (command === "unpair") {
17403
+ await unpairRemoteMac(args.slice(1));
17404
+ return;
17405
+ }
16768
17406
  if (command === "init") {
16769
17407
  await initialize(args.slice(1));
16770
17408
  return;
@@ -16805,7 +17443,7 @@ Emulator setup verification:`);
16805
17443
  await publishIos(args.slice(2));
16806
17444
  return;
16807
17445
  }
16808
- throw new TypeError("Usage: absolute mobile <init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--wait-for-hmr] [--timeout ms] [--port n] [--udid id] [--artifacts dir] [--json]> [--config path]");
17446
+ throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--wait-for-hmr] [--timeout ms] [--port n] [--udid id] [--artifacts dir] [--json]> [--config path]");
16809
17447
  };
16810
17448
  var init_mobile = __esm(() => {
16811
17449
  init_capacitorProject();
@@ -16828,6 +17466,7 @@ var init_mobile = __esm(() => {
16828
17466
  init_start();
16829
17467
  init_utils();
16830
17468
  init_getDurationString();
17469
+ init_remoteMacProtocol();
16831
17470
  CAPACITOR_PACKAGES = [
16832
17471
  "@capacitor/core",
16833
17472
  "@capacitor/app",
@@ -16842,9 +17481,9 @@ var exports_typecheck = {};
16842
17481
  __export(exports_typecheck, {
16843
17482
  typecheck: () => typecheck
16844
17483
  });
16845
- import { resolve as resolve40, join as join46 } from "path";
17484
+ import { resolve as resolve40, join as join47 } from "path";
16846
17485
  import { existsSync as existsSync42, readFileSync as readFileSync37 } from "fs";
16847
- import { mkdir as mkdir12, writeFile as writeFile12 } from "fs/promises";
17486
+ import { mkdir as mkdir13, writeFile as writeFile13 } from "fs/promises";
16848
17487
  var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve40(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
16849
17488
  if (!existsSync42(resolveConfigPath(configPath2))) {
16850
17489
  const defaultService = {};
@@ -16951,8 +17590,8 @@ Found ${errorCount} error${suffix}.`;
16951
17590
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
16952
17591
  process.exit(1);
16953
17592
  }
16954
- const vueTsconfigPath = join46(cacheDir, "tsconfig.vue-check.json");
16955
- return writeFile12(vueTsconfigPath, JSON.stringify({
17593
+ const vueTsconfigPath = join47(cacheDir, "tsconfig.vue-check.json");
17594
+ return writeFile13(vueTsconfigPath, JSON.stringify({
16956
17595
  compilerOptions: {
16957
17596
  rootDir: ".."
16958
17597
  },
@@ -16966,7 +17605,7 @@ Found ${errorCount} error${suffix}.`;
16966
17605
  resolve40(vueTsconfigPath),
16967
17606
  "--incremental",
16968
17607
  "--tsBuildInfoFile",
16969
- join46(cacheDir, "vue-tsc.tsbuildinfo"),
17608
+ join47(cacheDir, "vue-tsc.tsbuildinfo"),
16970
17609
  "--pretty"
16971
17610
  ]));
16972
17611
  }, buildAngularCheck = async (cacheDir, angularDir) => {
@@ -16975,8 +17614,8 @@ Found ${errorCount} error${suffix}.`;
16975
17614
  console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
16976
17615
  process.exit(1);
16977
17616
  }
16978
- const angularTsconfigPath = join46(cacheDir, "tsconfig.angular-check.json");
16979
- await writeFile12(angularTsconfigPath, JSON.stringify({
17617
+ const angularTsconfigPath = join47(cacheDir, "tsconfig.angular-check.json");
17618
+ await writeFile13(angularTsconfigPath, JSON.stringify({
16980
17619
  angularCompilerOptions: {
16981
17620
  strictTemplates: true
16982
17621
  },
@@ -16995,8 +17634,8 @@ Found ${errorCount} error${suffix}.`;
16995
17634
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
16996
17635
  process.exit(1);
16997
17636
  }
16998
- const tscConfigPath = join46(cacheDir, "tsconfig.typecheck.json");
16999
- return writeFile12(tscConfigPath, JSON.stringify({
17637
+ const tscConfigPath = join47(cacheDir, "tsconfig.typecheck.json");
17638
+ return writeFile13(tscConfigPath, JSON.stringify({
17000
17639
  compilerOptions: {
17001
17640
  rootDir: ".."
17002
17641
  },
@@ -17010,7 +17649,7 @@ Found ${errorCount} error${suffix}.`;
17010
17649
  resolve40(tscConfigPath),
17011
17650
  "--incremental",
17012
17651
  "--tsBuildInfoFile",
17013
- join46(cacheDir, "tsc.tsbuildinfo"),
17652
+ join47(cacheDir, "tsc.tsbuildinfo"),
17014
17653
  "--pretty"
17015
17654
  ]));
17016
17655
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -17019,8 +17658,8 @@ Found ${errorCount} error${suffix}.`;
17019
17658
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
17020
17659
  process.exit(1);
17021
17660
  }
17022
- const svelteTsconfigPath = join46(cacheDir, "tsconfig.svelte-check.json");
17023
- await writeFile12(svelteTsconfigPath, JSON.stringify({
17661
+ const svelteTsconfigPath = join47(cacheDir, "tsconfig.svelte-check.json");
17662
+ await writeFile13(svelteTsconfigPath, JSON.stringify({
17024
17663
  extends: resolve40("tsconfig.json"),
17025
17664
  files: ABSOLUTE_TYPECHECK_FILES,
17026
17665
  include: [`../${svelteDir}/**/*`]
@@ -17049,7 +17688,7 @@ Found ${errorCount} error${suffix}.`;
17049
17688
  ...new Set(targets.map((config) => config.angularDirectory).filter((dir) => typeof dir === "string" && dir.length > 0))
17050
17689
  ];
17051
17690
  const cacheDir = ".absolutejs";
17052
- await mkdir12(cacheDir, { recursive: true });
17691
+ await mkdir13(cacheDir, { recursive: true });
17053
17692
  const checks = [];
17054
17693
  checks.push(hasVue ? buildVueTscCheck(cacheDir) : buildTscCheck(cacheDir));
17055
17694
  for (const svelteDir of hasSvelte ? svelteDirs : []) {
@@ -17278,7 +17917,7 @@ import {
17278
17917
  writeFileSync as writeFileSync4
17279
17918
  } from "fs";
17280
17919
  import { tmpdir as tmpdir2 } from "os";
17281
- import { join as join11, resolve as resolve8 } from "path";
17920
+ import { join as join12, resolve as resolve8 } from "path";
17282
17921
 
17283
17922
  // src/dev/tunnel/client.ts
17284
17923
  var RECONNECT_DELAY_MS = 2000;
@@ -17867,6 +18506,7 @@ var isAbsoluteAndroidNativeRootInput = (path) => ROOT_NATIVE_INPUTS.has(basename
17867
18506
 
17868
18507
  // src/cli/scripts/dev.ts
17869
18508
  init_iosSimulatorController();
18509
+ init_remoteMacProtocol();
17870
18510
 
17871
18511
  // src/mobile/iosNativeWatcher.ts
17872
18512
  init_iosSimulatorController();
@@ -18135,7 +18775,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18135
18775
  }
18136
18776
  }
18137
18777
  if (ready) {
18138
- const nativeDirectory = join11(normalized.nativeProjectDirectory, "android");
18778
+ const nativeDirectory = join12(normalized.nativeProjectDirectory, "android");
18139
18779
  let createNativeProject = false;
18140
18780
  if (!existsSync5(nativeDirectory)) {
18141
18781
  createNativeProject = await confirmPrompt("Create the managed Capacitor Android project now?");
@@ -18150,7 +18790,18 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18150
18790
  }
18151
18791
  if (normalized.platforms.includes("ios")) {
18152
18792
  if (detectAbsoluteMobileHost() !== "macos") {
18153
- console.log(cliTag("\x1B[33m", "iOS simulator skipped because it requires macOS and Xcode."));
18793
+ const remote = await getAbsoluteRemoteMacProfile();
18794
+ if (!remote) {
18795
+ console.log(cliTag("\x1B[33m", "iOS simulator skipped. Pair a Mac with `absolute mobile pair mac <name> <user@host>`."));
18796
+ } else {
18797
+ const nativeDirectory = join12(normalized.nativeProjectDirectory, "ios");
18798
+ if (!existsSync5(nativeDirectory)) {
18799
+ console.log(cliTag("\x1B[33m", "The iOS project is missing. Run `absolute mobile init` before remote development."));
18800
+ } else {
18801
+ iosDevProject = createAbsoluteRemoteIosDevProject(normalized, process.cwd(), remote);
18802
+ console.log(cliTag("\x1B[35m", `Using remote Mac ${remote.name} for iOS development.`));
18803
+ }
18804
+ }
18154
18805
  } else {
18155
18806
  let ready = iosToolchainReady(await inspectAbsoluteMobileToolchain());
18156
18807
  if (!ready) {
@@ -18163,7 +18814,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18163
18814
  }
18164
18815
  }
18165
18816
  if (ready) {
18166
- const nativeDirectory = join11(normalized.nativeProjectDirectory, "ios");
18817
+ const nativeDirectory = join12(normalized.nativeProjectDirectory, "ios");
18167
18818
  let createNativeProject = false;
18168
18819
  if (!existsSync5(nativeDirectory)) {
18169
18820
  createNativeProject = await confirmPrompt("Create the managed Capacitor iOS project now?");
@@ -18374,10 +19025,11 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18374
19025
  const iosPhaseTimings = {};
18375
19026
  let iosDevState = "waiting-for-server";
18376
19027
  const iosDevAbort = new AbortController;
18377
- const publishIosReady = (session) => {
19028
+ const iosTelemetryHost = (project) => project.remote ? "remote-macos" : "macos";
19029
+ const publishIosReady = (session, project) => {
18378
19030
  sendTelemetryEvent("mobile:ios-dev-ready", {
18379
19031
  cacheHit: session.nativeCacheHit,
18380
- host: "macos",
19032
+ host: iosTelemetryHost(project),
18381
19033
  platform: "ios",
18382
19034
  provider: "capacitor",
18383
19035
  startedSimulator: session.startedSimulator,
@@ -18387,30 +19039,43 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18387
19039
  return;
18388
19040
  sendTelemetryEvent("mobile:native-build", {
18389
19041
  buildMs: session.timings.building,
18390
- host: "macos",
19042
+ host: iosTelemetryHost(project),
18391
19043
  installMs: session.timings.installing,
18392
19044
  platform: "ios",
18393
19045
  provider: "capacitor",
18394
19046
  success: true
18395
19047
  });
18396
19048
  };
18397
- const openIosDevSession = (iosProject) => startAbsoluteIosDevSession({
18398
- https: httpsEnabled,
18399
- port,
18400
- project: iosProject,
18401
- signal: iosDevAbort.signal,
18402
- log: (message) => printNativeOutput(cliTag("\x1B[35m", message)),
18403
- nativeLog: (entry) => printNativeOutput(iosLogTag(entry)),
18404
- onPhaseTiming: ({ durationMs, phase }) => {
18405
- iosPhaseTimings[phase] = (iosPhaseTimings[phase] ?? 0) + durationMs;
18406
- },
18407
- onStateChange: (state) => {
18408
- iosDevState = state;
18409
- if (state === "ready" || state === "closed")
18410
- return;
18411
- printNativeOutput(cliTag("\x1B[35m", `iOS simulator: ${state}.`));
18412
- }
18413
- });
19049
+ const openIosDevSession = (iosProject) => {
19050
+ const sessionOptions = {
19051
+ https: httpsEnabled,
19052
+ port,
19053
+ signal: iosDevAbort.signal,
19054
+ log: (message) => printNativeOutput(cliTag("\x1B[35m", message)),
19055
+ nativeLog: (entry) => printNativeOutput(iosLogTag(entry)),
19056
+ onPhaseTiming: ({
19057
+ durationMs,
19058
+ phase
19059
+ }) => {
19060
+ iosPhaseTimings[phase] = (iosPhaseTimings[phase] ?? 0) + durationMs;
19061
+ },
19062
+ onStateChange: (state) => {
19063
+ iosDevState = state;
19064
+ if (state === "ready" || state === "closed")
19065
+ return;
19066
+ printNativeOutput(cliTag("\x1B[35m", `iOS simulator: ${state}.`));
19067
+ }
19068
+ };
19069
+ if (iosProject.remote)
19070
+ return startAbsoluteRemoteIosDevSession({
19071
+ ...sessionOptions,
19072
+ project: iosProject
19073
+ });
19074
+ return startAbsoluteIosDevSession({
19075
+ ...sessionOptions,
19076
+ project: iosProject
19077
+ });
19078
+ };
18414
19079
  const ensureIosNativeWatcher = async (iosProject) => {
18415
19080
  if (iosNativeWatcher)
18416
19081
  return;
@@ -18429,10 +19094,10 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18429
19094
  return;
18430
19095
  }
18431
19096
  iosDevSession = replacement;
18432
- publishIosReady(replacement);
19097
+ publishIosReady(replacement, iosProject);
18433
19098
  sendTelemetryEvent("mobile:native-rebuild", {
18434
19099
  cacheHit: replacement.nativeCacheHit,
18435
- host: "macos",
19100
+ host: iosTelemetryHost(iosProject),
18436
19101
  platform: "ios",
18437
19102
  provider: "capacitor",
18438
19103
  rootInputChanged: change.rootInputChanged,
@@ -18444,7 +19109,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18444
19109
  iosDevState = "failed";
18445
19110
  printNativeOutput(cliTag("\x1B[31m", `iOS native rebuild failed: ${error instanceof Error ? error.message : String(error)}`));
18446
19111
  sendTelemetryEvent("mobile:native-rebuild", {
18447
- host: "macos",
19112
+ host: iosTelemetryHost(iosProject),
18448
19113
  platform: "ios",
18449
19114
  provider: "capacitor",
18450
19115
  success: false
@@ -18462,7 +19127,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18462
19127
  return;
18463
19128
  }
18464
19129
  iosDevSession = session;
18465
- publishIosReady(session);
19130
+ publishIosReady(session, iosProject);
18466
19131
  await ensureIosNativeWatcher(iosProject);
18467
19132
  return;
18468
19133
  }).catch((error) => {
@@ -18470,7 +19135,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18470
19135
  if (cleaning && error instanceof Error && error.name === "AbortError")
18471
19136
  return;
18472
19137
  sendTelemetryEvent("mobile:ios-dev-failed", {
18473
- host: "macos",
19138
+ host: iosTelemetryHost(iosProject),
18474
19139
  phase: iosDevState,
18475
19140
  platform: "ios",
18476
19141
  provider: "capacitor",
@@ -18597,7 +19262,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18597
19262
  }
18598
19263
  return merged;
18599
19264
  };
18600
- const heapPreloadPath = join11(tmpdir2(), `absolute-heap-${process.pid}.ts`);
19265
+ const heapPreloadPath = join12(tmpdir2(), `absolute-heap-${process.pid}.ts`);
18601
19266
  let heapSnapshotEnabled = false;
18602
19267
  try {
18603
19268
  writeFileSync4(heapPreloadPath, DEV_CHILD_PRELOAD);
@@ -18694,9 +19359,9 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18694
19359
  };
18695
19360
  try {
18696
19361
  const { watch: watch3 } = await import("fs");
18697
- const { dirname: dirname6 } = await import("path");
19362
+ const { dirname: dirname7 } = await import("path");
18698
19363
  const absServerEntry = resolve8(serverEntry);
18699
- const serverEntryDir = dirname6(absServerEntry);
19364
+ const serverEntryDir = dirname7(absServerEntry);
18700
19365
  const ROOT_RESTART_DENY = new Set([
18701
19366
  "build",
18702
19367
  "dist",
@@ -18727,7 +19392,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18727
19392
  if (now - last < 100)
18728
19393
  return;
18729
19394
  recentlyHandled.set(filename, now);
18730
- scheduleServerRestart(join11(serverEntryDir, filename));
19395
+ scheduleServerRestart(join12(serverEntryDir, filename));
18731
19396
  };
18732
19397
  const recoveryScan = async () => {
18733
19398
  let entries;
@@ -18746,7 +19411,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18746
19411
  continue;
18747
19412
  let fileStat;
18748
19413
  try {
18749
- fileStat = statSync(join11(serverEntryDir, entry.name));
19414
+ fileStat = statSync(join12(serverEntryDir, entry.name));
18750
19415
  } catch {
18751
19416
  continue;
18752
19417
  }
@@ -18850,9 +19515,10 @@ var dev = async (serverEntry, configPath2, options = {}) => {
18850
19515
  if (iosDevSession) {
18851
19516
  await iosDevSession.close();
18852
19517
  } else if (iosDevProject) {
18853
- await repairAbsoluteIosDevSession(iosDevProject.projectRoot).catch(() => {
18854
- return;
18855
- });
19518
+ if (!iosDevProject.remote)
19519
+ await repairAbsoluteIosDevSession(iosDevProject.projectRoot).catch(() => {
19520
+ return;
19521
+ });
18856
19522
  }
18857
19523
  if (paused)
18858
19524
  sendSignal("SIGCONT");
@@ -19252,8 +19918,8 @@ var info = () => {
19252
19918
 
19253
19919
  // src/cli/cache.ts
19254
19920
  init_constants();
19255
- import { mkdir as mkdir5 } from "fs/promises";
19256
- import { join as join12 } from "path";
19921
+ import { mkdir as mkdir6 } from "fs/promises";
19922
+ import { join as join13 } from "path";
19257
19923
  var {Glob } = globalThis.Bun;
19258
19924
  var CACHE_DIR = ".absolutejs";
19259
19925
  var MAX_FILES_PER_BATCH = 200;
@@ -19305,7 +19971,7 @@ var hashFiles = async (paths) => {
19305
19971
  };
19306
19972
  var loadCache = async (tool) => {
19307
19973
  try {
19308
- const path = join12(CACHE_DIR, `${tool}.cache.json`);
19974
+ const path = join13(CACHE_DIR, `${tool}.cache.json`);
19309
19975
  const data = await Bun.file(path).json();
19310
19976
  const result = data;
19311
19977
  return result;
@@ -19351,8 +20017,8 @@ var runTool = async (adapter, args) => {
19351
20017
  console.log("\x1B[32m\u2713\x1B[0m Passed");
19352
20018
  };
19353
20019
  var saveCache = async (tool, data) => {
19354
- await mkdir5(CACHE_DIR, { recursive: true });
19355
- const path = join12(CACHE_DIR, `${tool}.cache.json`);
20020
+ await mkdir6(CACHE_DIR, { recursive: true });
20021
+ const path = join13(CACHE_DIR, `${tool}.cache.json`);
19356
20022
  await Bun.write(path, JSON.stringify(data, null, "\t"));
19357
20023
  };
19358
20024
 
@@ -20986,7 +21652,7 @@ if (command === "dev") {
20986
21652
  console.error(" prepare [entry] [--outdir dir] Build production assets and server without launching");
20987
21653
  console.error(" start [entry] [--outdir dir] [--prebuilt] Start production server");
20988
21654
  console.error(" compile [entry] [--outdir dir] [--outfile path] Compile standalone executable");
20989
- console.error(" mobile <init|sync|associations|doctor|test> Manage Capacitor projects, emulator conformance, guided setup, and deep links");
21655
+ console.error(" mobile <init|sync|pair|remotes|doctor|test> Manage Capacitor projects, local or remote simulators, guided setup, and deep links");
20990
21656
  console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
20991
21657
  console.error(" db <backup|restore|seed> Backup/restore any Postgres DB (ORM-agnostic, upsert by PK) or run the seed script");
20992
21658
  console.error(" doctor [--fix] [--json] Diagnose the project (bun, type graph, config, framework dirs, env, port)");