@absolutejs/absolute 0.20.0-beta.50 → 0.20.0-beta.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +327 -36
- package/dist/mobile/index.js +301 -30
- package/dist/mobile/index.js.map +5 -5
- package/dist/mobile/remoteMacAgentEntry.js +361 -190
- package/dist/src/mobile/iosRelease.d.ts +47 -0
- package/dist/src/mobile/remoteMacProtocol.d.ts +52 -0
- package/dist/src/mobile/remoteMacWire.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-K4oNvN/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-K4oNvN/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-K4oNvN/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/cli/index.js
CHANGED
|
@@ -4693,7 +4693,7 @@ import {
|
|
|
4693
4693
|
writeFile as writeFile4
|
|
4694
4694
|
} from "fs/promises";
|
|
4695
4695
|
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join13, relative as relative5, resolve as resolve9, sep as sep3 } from "path";
|
|
4696
|
-
var developmentTeamArgument = (value) => {
|
|
4696
|
+
var ABSOLUTE_IOS_RELEASE_FORMAT = 1, developmentTeamArgument = (value) => {
|
|
4697
4697
|
if (value === undefined)
|
|
4698
4698
|
return;
|
|
4699
4699
|
const team = value.trim().toUpperCase();
|
|
@@ -4844,6 +4844,26 @@ var developmentTeamArgument = (value) => {
|
|
|
4844
4844
|
if (value !== undefined && (!Number.isSafeInteger(value) || value < 1))
|
|
4845
4845
|
throw new TypeError("iOS build number must be a positive integer.");
|
|
4846
4846
|
return value;
|
|
4847
|
+
}, requireAbsoluteIosReleaseMetadata = (value) => {
|
|
4848
|
+
if (!isRecord3(value) || value.artifact !== "App.ipa" || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 1 || value.engine !== "capacitor" && value.engine !== "expo" || value.format !== ABSOLUTE_IOS_RELEASE_FORMAT || typeof value.marketingVersion !== "string" || value.platform !== "ios" || typeof value.releaseId !== "string" || typeof value.runtime !== "string" || typeof value.sha256 !== "string" || typeof value.signed !== "boolean" || value.type !== "ipa" || value.buildNumber !== undefined && (typeof value.buildNumber !== "number" || !Number.isSafeInteger(value.buildNumber) || value.buildNumber < 1) || !/^amobile_ios_[a-f0-9]{64}$/u.test(value.releaseId) || !/^[a-f0-9]{64}$/u.test(value.sha256) || value.releaseId !== `amobile_ios_${value.sha256}`) {
|
|
4849
|
+
throw new TypeError("Invalid AbsoluteJS iOS release metadata.");
|
|
4850
|
+
}
|
|
4851
|
+
return {
|
|
4852
|
+
appBuild: value.appBuild,
|
|
4853
|
+
appId: value.appId,
|
|
4854
|
+
artifact: value.artifact,
|
|
4855
|
+
...typeof value.buildNumber === "number" ? { buildNumber: value.buildNumber } : {},
|
|
4856
|
+
bytes: value.bytes,
|
|
4857
|
+
engine: value.engine,
|
|
4858
|
+
format: value.format,
|
|
4859
|
+
marketingVersion: value.marketingVersion,
|
|
4860
|
+
platform: value.platform,
|
|
4861
|
+
releaseId: value.releaseId,
|
|
4862
|
+
runtime: value.runtime,
|
|
4863
|
+
sha256: value.sha256,
|
|
4864
|
+
signed: value.signed,
|
|
4865
|
+
type: value.type
|
|
4866
|
+
};
|
|
4847
4867
|
}, installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
4848
4868
|
const releaseRoot = join13(outputRoot, metadata.releaseId);
|
|
4849
4869
|
const destination = join13(releaseRoot, "App.ipa");
|
|
@@ -4990,6 +5010,16 @@ var developmentTeamArgument = (value) => {
|
|
|
4990
5010
|
return;
|
|
4991
5011
|
});
|
|
4992
5012
|
}
|
|
5013
|
+
}, installAbsoluteIosRelease = async (options) => {
|
|
5014
|
+
const metadata = requireAbsoluteIosReleaseMetadata(options.metadata);
|
|
5015
|
+
const [bytes, sha256] = await Promise.all([
|
|
5016
|
+
stat(options.artifactPath).then(({ size }) => size),
|
|
5017
|
+
sha256File(options.artifactPath)
|
|
5018
|
+
]);
|
|
5019
|
+
if (bytes !== metadata.bytes || sha256 !== metadata.sha256)
|
|
5020
|
+
throw new TypeError("Remote iOS release artifact does not match its signed metadata.");
|
|
5021
|
+
const { artifact: _artifact, ...releaseMetadata } = metadata;
|
|
5022
|
+
return installRelease(options.artifactPath, releaseMetadata, safeOutputDirectory(options.projectRoot, options.outputDirectory));
|
|
4993
5023
|
};
|
|
4994
5024
|
var init_iosRelease = __esm(() => {
|
|
4995
5025
|
init_emulatorDoctor();
|
|
@@ -5903,11 +5933,19 @@ var init_iosSimulatorController = __esm(() => {
|
|
|
5903
5933
|
});
|
|
5904
5934
|
|
|
5905
5935
|
// src/mobile/remoteMacWire.ts
|
|
5906
|
-
var ABSOLUTE_REMOTE_MAC_EVENT_PREFIX = "ABSOLUTE_REMOTE_MAC\t", ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION =
|
|
5936
|
+
var ABSOLUTE_REMOTE_MAC_EVENT_PREFIX = "ABSOLUTE_REMOTE_MAC\t", ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION = 3;
|
|
5907
5937
|
|
|
5908
5938
|
// src/mobile/remoteMacProtocol.ts
|
|
5909
5939
|
import { createHash as createHash6, randomUUID as randomUUID4 } from "crypto";
|
|
5910
|
-
import {
|
|
5940
|
+
import {
|
|
5941
|
+
chmod,
|
|
5942
|
+
mkdir as mkdir6,
|
|
5943
|
+
mkdtemp as mkdtemp4,
|
|
5944
|
+
readFile as readFile8,
|
|
5945
|
+
rename as rename6,
|
|
5946
|
+
rm as rm6,
|
|
5947
|
+
writeFile as writeFile6
|
|
5948
|
+
} from "fs/promises";
|
|
5911
5949
|
import { homedir as homedir4 } from "os";
|
|
5912
5950
|
import { isIP as isIP3 } from "net";
|
|
5913
5951
|
import {
|
|
@@ -6236,6 +6274,13 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6236
6274
|
tar: [
|
|
6237
6275
|
"tar",
|
|
6238
6276
|
"--exclude=.git",
|
|
6277
|
+
"--exclude=.env",
|
|
6278
|
+
"--exclude=.env.*",
|
|
6279
|
+
"--exclude=*.jks",
|
|
6280
|
+
"--exclude=*.keystore",
|
|
6281
|
+
"--exclude=*.mobileprovision",
|
|
6282
|
+
"--exclude=*.p12",
|
|
6283
|
+
"--exclude=*.p8",
|
|
6239
6284
|
"--exclude=node_modules",
|
|
6240
6285
|
"--exclude=build",
|
|
6241
6286
|
"--exclude=.absolutejs",
|
|
@@ -6271,6 +6316,108 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6271
6316
|
shellQuote(`cd ${shellQuote(project.remoteProjectRoot)} && ${shellQuote(project.profile.bunPath)} install --frozen-lockfile`)
|
|
6272
6317
|
]);
|
|
6273
6318
|
requireRemoteSuccess(install, "Remote Mac dependency installation");
|
|
6319
|
+
}, requireRemoteProjectRelativePath = (project, path) => {
|
|
6320
|
+
const value = portableRelativePath(project.projectRoot, path);
|
|
6321
|
+
if (!value || value === ".." || value.startsWith("../") || posix.isAbsolute(value))
|
|
6322
|
+
throw new TypeError("Remote iOS release inputs must remain inside the project.");
|
|
6323
|
+
return value;
|
|
6324
|
+
}, absoluteRemoteReleaseInputSyncCommands = (project) => {
|
|
6325
|
+
const relativeBundle = requireRemoteProjectRelativePath(project, project.config.bundleDirectory);
|
|
6326
|
+
const destination = posix.join(project.remoteProjectRoot, relativeBundle);
|
|
6327
|
+
const staging = `${destination}.incoming-${randomUUID4()}`;
|
|
6328
|
+
const script = [
|
|
6329
|
+
"set -eu",
|
|
6330
|
+
`rm -rf ${shellQuote(staging)}`,
|
|
6331
|
+
`mkdir -p ${shellQuote(staging)}`,
|
|
6332
|
+
`tar -xf - -C ${shellQuote(staging)}`,
|
|
6333
|
+
`rm -rf ${shellQuote(destination)}`,
|
|
6334
|
+
`mkdir -p ${shellQuote(posix.dirname(destination))}`,
|
|
6335
|
+
`mv ${shellQuote(staging)} ${shellQuote(destination)}`
|
|
6336
|
+
].join("; ");
|
|
6337
|
+
return {
|
|
6338
|
+
remote: [
|
|
6339
|
+
...absoluteRemoteMacSshBase(project.profile),
|
|
6340
|
+
"/bin/sh -lc",
|
|
6341
|
+
shellQuote(script)
|
|
6342
|
+
],
|
|
6343
|
+
tar: ["tar", "-cf", "-", "-C", project.config.bundleDirectory, "."]
|
|
6344
|
+
};
|
|
6345
|
+
}, syncAbsoluteRemoteMacReleaseInputs = async (project) => {
|
|
6346
|
+
const commands = absoluteRemoteReleaseInputSyncCommands(project);
|
|
6347
|
+
const archive = Bun.spawn(commands.tar, {
|
|
6348
|
+
stderr: "pipe",
|
|
6349
|
+
stdout: "pipe"
|
|
6350
|
+
});
|
|
6351
|
+
const upload = Bun.spawn(commands.remote, {
|
|
6352
|
+
stderr: "pipe",
|
|
6353
|
+
stdin: archive.stdout,
|
|
6354
|
+
stdout: "pipe"
|
|
6355
|
+
});
|
|
6356
|
+
const [archiveExit, uploadExit, archiveError, uploadError] = await Promise.all([
|
|
6357
|
+
archive.exited,
|
|
6358
|
+
upload.exited,
|
|
6359
|
+
new Response(archive.stderr).text(),
|
|
6360
|
+
new Response(upload.stderr).text()
|
|
6361
|
+
]);
|
|
6362
|
+
if (archiveExit !== 0 || uploadExit !== 0)
|
|
6363
|
+
throw new Error(`Remote iOS release input synchronization failed: ${(archiveError || uploadError).trim()}`);
|
|
6364
|
+
}, writeRemoteArtifact = async (path, stream) => {
|
|
6365
|
+
const sink = Bun.file(path).writer();
|
|
6366
|
+
const reader = stream.getReader();
|
|
6367
|
+
try {
|
|
6368
|
+
while (true) {
|
|
6369
|
+
const { done, value } = await reader.read();
|
|
6370
|
+
if (done)
|
|
6371
|
+
break;
|
|
6372
|
+
sink.write(value);
|
|
6373
|
+
}
|
|
6374
|
+
await sink.end();
|
|
6375
|
+
} catch (error) {
|
|
6376
|
+
await Promise.resolve(sink.end()).catch(() => {
|
|
6377
|
+
return;
|
|
6378
|
+
});
|
|
6379
|
+
throw error;
|
|
6380
|
+
} finally {
|
|
6381
|
+
reader.releaseLock();
|
|
6382
|
+
}
|
|
6383
|
+
}, retrieveAbsoluteRemoteIosRelease = async (project, metadata, outputDirectory) => {
|
|
6384
|
+
const releaseRoot = posix.join(project.remoteProjectRoot, ".absolutejs", "mobile", "releases", "ios", metadata.releaseId);
|
|
6385
|
+
const stagingParent = join15(project.projectRoot, ".absolutejs", "mobile");
|
|
6386
|
+
await mkdir6(stagingParent, { recursive: true });
|
|
6387
|
+
const staging = await mkdtemp4(join15(stagingParent, ".remote-ios-"));
|
|
6388
|
+
try {
|
|
6389
|
+
const remoteMetadata = requireRemoteSuccess(await defaultTransport.capture([
|
|
6390
|
+
...absoluteRemoteMacSshBase(project.profile),
|
|
6391
|
+
"/bin/sh -lc",
|
|
6392
|
+
shellQuote(`cat ${shellQuote(posix.join(releaseRoot, "release.json"))}`)
|
|
6393
|
+
]), "Remote iOS release metadata retrieval");
|
|
6394
|
+
const downloadedMetadata = JSON.parse(remoteMetadata);
|
|
6395
|
+
if (JSON.stringify(requireAbsoluteIosReleaseMetadata(downloadedMetadata)) !== JSON.stringify(metadata))
|
|
6396
|
+
throw new TypeError("Remote iOS release metadata changed during retrieval.");
|
|
6397
|
+
const artifactPath = join15(staging, "App.ipa");
|
|
6398
|
+
const download = Bun.spawn([
|
|
6399
|
+
...absoluteRemoteMacSshBase(project.profile),
|
|
6400
|
+
"/bin/sh -lc",
|
|
6401
|
+
shellQuote(`cat ${shellQuote(posix.join(releaseRoot, "App.ipa"))}`)
|
|
6402
|
+
], { stderr: "pipe", stdout: "pipe" });
|
|
6403
|
+
const [downloadExit, downloadError] = await Promise.all([
|
|
6404
|
+
download.exited,
|
|
6405
|
+
new Response(download.stderr).text(),
|
|
6406
|
+
writeRemoteArtifact(artifactPath, download.stdout)
|
|
6407
|
+
]);
|
|
6408
|
+
if (downloadExit !== 0)
|
|
6409
|
+
throw new Error(`Remote iOS release retrieval failed: ${downloadError.trim()}`);
|
|
6410
|
+
return await installAbsoluteIosRelease({
|
|
6411
|
+
artifactPath,
|
|
6412
|
+
metadata,
|
|
6413
|
+
outputDirectory,
|
|
6414
|
+
projectRoot: project.projectRoot
|
|
6415
|
+
});
|
|
6416
|
+
} finally {
|
|
6417
|
+
await rm6(staging, { force: true, recursive: true }).catch(() => {
|
|
6418
|
+
return;
|
|
6419
|
+
});
|
|
6420
|
+
}
|
|
6274
6421
|
}, consumeLines2 = async (stream, onLine) => {
|
|
6275
6422
|
const reader = stream.getReader();
|
|
6276
6423
|
const decoder = new TextDecoder;
|
|
@@ -6291,6 +6438,116 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6291
6438
|
} finally {
|
|
6292
6439
|
reader.releaseLock();
|
|
6293
6440
|
}
|
|
6441
|
+
}, buildAbsoluteRemoteIosRelease = async (options) => {
|
|
6442
|
+
const startedAt = performance.now();
|
|
6443
|
+
const syncStartedAt = performance.now();
|
|
6444
|
+
await (options.syncProject ?? syncAbsoluteRemoteMacProject)(options.project);
|
|
6445
|
+
await (options.syncReleaseInputs ?? syncAbsoluteRemoteMacReleaseInputs)(options.project);
|
|
6446
|
+
const syncDuration = performance.now() - syncStartedAt;
|
|
6447
|
+
options.onPhaseTiming?.({
|
|
6448
|
+
durationMs: syncDuration,
|
|
6449
|
+
phase: "remote-release-sync"
|
|
6450
|
+
});
|
|
6451
|
+
const agentStartedAt = performance.now();
|
|
6452
|
+
const agent = await (options.installAgent ?? installAbsoluteRemoteMacAgent)(options.project);
|
|
6453
|
+
const agentDuration = performance.now() - agentStartedAt;
|
|
6454
|
+
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
6455
|
+
const remoteCommand = [
|
|
6456
|
+
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
6457
|
+
"&&",
|
|
6458
|
+
"exec",
|
|
6459
|
+
shellQuote(options.project.profile.bunPath),
|
|
6460
|
+
shellQuote(agent.remotePath),
|
|
6461
|
+
"--release-ios",
|
|
6462
|
+
"--mobile-config",
|
|
6463
|
+
shellQuote(encodedConfig),
|
|
6464
|
+
...options.allowUnsigned ? ["--unsigned"] : [],
|
|
6465
|
+
...options.prepareBuildNumber ? ["--request-build-number"] : [],
|
|
6466
|
+
...options.developmentTeam ? ["--development-team", shellQuote(options.developmentTeam)] : []
|
|
6467
|
+
].join(" ");
|
|
6468
|
+
const process2 = (options.transport?.spawn ?? defaultTransport.spawn)([
|
|
6469
|
+
...absoluteRemoteMacSshBase(options.project.profile),
|
|
6470
|
+
"/bin/sh -lc",
|
|
6471
|
+
shellQuote(remoteCommand)
|
|
6472
|
+
], {});
|
|
6473
|
+
let failure;
|
|
6474
|
+
let metadata;
|
|
6475
|
+
const responses = [];
|
|
6476
|
+
const stdoutDone = consumeLines2(process2.stdout, (line) => {
|
|
6477
|
+
if (!line.startsWith(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX))
|
|
6478
|
+
return;
|
|
6479
|
+
try {
|
|
6480
|
+
const event = JSON.parse(line.slice(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX.length));
|
|
6481
|
+
if (event.v !== ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION)
|
|
6482
|
+
throw new Error("Remote Mac protocol version mismatch.");
|
|
6483
|
+
if (event.type === "log")
|
|
6484
|
+
options.log?.(event.message);
|
|
6485
|
+
if (event.type === "timing") {
|
|
6486
|
+
const durationMs = Reflect.get(event, "durationMs");
|
|
6487
|
+
const phase = Reflect.get(event, "phase");
|
|
6488
|
+
if (typeof durationMs === "number" && typeof phase === "string")
|
|
6489
|
+
options.onPhaseTiming?.({ durationMs, phase });
|
|
6490
|
+
}
|
|
6491
|
+
if (event.type === "fatal")
|
|
6492
|
+
failure = new Error(event.error);
|
|
6493
|
+
if (event.type === "release")
|
|
6494
|
+
metadata = requireAbsoluteIosReleaseMetadata(event.metadata);
|
|
6495
|
+
if (event.type === "build-number-request") {
|
|
6496
|
+
if (!options.prepareBuildNumber || !/^[a-f0-9]{64}$/u.test(event.buildIdentity) || !event.id)
|
|
6497
|
+
throw new TypeError("Remote Mac requested an invalid iOS build number.");
|
|
6498
|
+
responses.push(options.prepareBuildNumber(event.buildIdentity).then(async (buildNumber) => {
|
|
6499
|
+
if (!Number.isSafeInteger(buildNumber) || buildNumber < 1)
|
|
6500
|
+
throw new TypeError("iOS release publisher returned an invalid build number.");
|
|
6501
|
+
process2.stdin.write(`${JSON.stringify({ buildNumber, command: "build-number", id: event.id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
6502
|
+
`);
|
|
6503
|
+
for (let attempt = 0;attempt < REMOTE_STDIN_FLUSH_ATTEMPTS; attempt++) {
|
|
6504
|
+
try {
|
|
6505
|
+
await process2.stdin.flush();
|
|
6506
|
+
break;
|
|
6507
|
+
} catch {
|
|
6508
|
+
await Promise.resolve();
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
6511
|
+
}).catch((error) => {
|
|
6512
|
+
failure = error instanceof Error ? error : new Error("Failed to allocate an iOS build number.");
|
|
6513
|
+
process2.kill();
|
|
6514
|
+
return;
|
|
6515
|
+
}));
|
|
6516
|
+
}
|
|
6517
|
+
} catch (error) {
|
|
6518
|
+
failure = error instanceof Error ? error : new Error("Remote Mac emitted an invalid release event.");
|
|
6519
|
+
process2.kill();
|
|
6520
|
+
}
|
|
6521
|
+
});
|
|
6522
|
+
const stderrDone = consumeLines2(process2.stderr, (line) => options.log?.(`[remote] ${line}`));
|
|
6523
|
+
const exitCode = await process2.exited;
|
|
6524
|
+
try {
|
|
6525
|
+
process2.stdin.end();
|
|
6526
|
+
} catch {}
|
|
6527
|
+
await Promise.all([stdoutDone, stderrDone, ...responses]);
|
|
6528
|
+
if (failure)
|
|
6529
|
+
throw failure;
|
|
6530
|
+
if (exitCode !== 0)
|
|
6531
|
+
throw new Error(`Remote iOS release agent exited with status ${exitCode}.`);
|
|
6532
|
+
if (!metadata)
|
|
6533
|
+
throw new Error("Remote iOS release agent did not return an IPA.");
|
|
6534
|
+
const downloadStartedAt = performance.now();
|
|
6535
|
+
const release = await (options.retrieveRelease ?? retrieveAbsoluteRemoteIosRelease)(options.project, metadata, options.outputDirectory);
|
|
6536
|
+
const downloadDuration = performance.now() - downloadStartedAt;
|
|
6537
|
+
options.onPhaseTiming?.({
|
|
6538
|
+
durationMs: downloadDuration,
|
|
6539
|
+
phase: "remote-release-download"
|
|
6540
|
+
});
|
|
6541
|
+
options.log?.(`Remote Mac ${options.project.profile.name} built and verified iOS release ${metadata.releaseId} in ${(performance.now() - startedAt).toFixed(2)}ms (agent ${agent.uploaded ? "uploaded" : "cache hit"}).`);
|
|
6542
|
+
return {
|
|
6543
|
+
...release,
|
|
6544
|
+
timings: {
|
|
6545
|
+
"remote-agent": agentDuration,
|
|
6546
|
+
"remote-release-download": downloadDuration,
|
|
6547
|
+
"remote-release-sync": syncDuration,
|
|
6548
|
+
total: performance.now() - startedAt
|
|
6549
|
+
}
|
|
6550
|
+
};
|
|
6294
6551
|
}, startAbsoluteRemoteExpoIosDevSession = async (options) => {
|
|
6295
6552
|
const session = await startAbsoluteRemoteDevSession({
|
|
6296
6553
|
certificateAuthorityPath: options.certificateAuthorityPath,
|
|
@@ -6464,7 +6721,9 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6464
6721
|
try {
|
|
6465
6722
|
await readyPromise;
|
|
6466
6723
|
} catch (error) {
|
|
6467
|
-
|
|
6724
|
+
try {
|
|
6725
|
+
process2.stdin.end();
|
|
6726
|
+
} catch {}
|
|
6468
6727
|
process2.kill();
|
|
6469
6728
|
await process2.exited.catch(() => {
|
|
6470
6729
|
return;
|
|
@@ -6516,13 +6775,12 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6516
6775
|
return;
|
|
6517
6776
|
closed = true;
|
|
6518
6777
|
const timeout = () => new Promise((resolve11) => setTimeout(() => resolve11("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
process2.stdin.end();
|
|
6778
|
+
const id = randomUUID4();
|
|
6779
|
+
process2.stdin.write(`${JSON.stringify({ command: "close", id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
6780
|
+
`);
|
|
6781
|
+
try {
|
|
6782
|
+
process2.stdin.end();
|
|
6783
|
+
} catch {}
|
|
6526
6784
|
const exit = await Promise.race([
|
|
6527
6785
|
process2.exited.then(() => "exited").catch(() => "exited"),
|
|
6528
6786
|
timeout()
|
|
@@ -6577,6 +6835,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6577
6835
|
return makeSession();
|
|
6578
6836
|
};
|
|
6579
6837
|
var init_remoteMacProtocol = __esm(() => {
|
|
6838
|
+
init_iosRelease();
|
|
6580
6839
|
PROFILE_NAME = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/u;
|
|
6581
6840
|
SSH_DESTINATION = /^(?:[A-Za-z0-9._-]+@)?[A-Za-z0-9._:-]+$/u;
|
|
6582
6841
|
defaultTransport = {
|
|
@@ -8541,10 +8800,10 @@ import {
|
|
|
8541
8800
|
cp as cp3,
|
|
8542
8801
|
copyFile as copyFile4,
|
|
8543
8802
|
mkdir as mkdir9,
|
|
8544
|
-
mkdtemp as
|
|
8803
|
+
mkdtemp as mkdtemp5,
|
|
8545
8804
|
readFile as readFile10,
|
|
8546
8805
|
rename as rename7,
|
|
8547
|
-
rm as
|
|
8806
|
+
rm as rm7,
|
|
8548
8807
|
writeFile as writeFile8
|
|
8549
8808
|
} from "fs/promises";
|
|
8550
8809
|
import { existsSync as existsSync10 } from "fs";
|
|
@@ -8690,11 +8949,11 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8690
8949
|
throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
|
|
8691
8950
|
}
|
|
8692
8951
|
await rename7(build.outputs[0]?.path ?? "", join21(staging, BOOTSTRAP_FILE));
|
|
8693
|
-
await
|
|
8952
|
+
await rm7(entryPath, { force: true });
|
|
8694
8953
|
}, removePreviousBundle = async (backup, moved) => {
|
|
8695
8954
|
if (!moved)
|
|
8696
8955
|
return;
|
|
8697
|
-
await
|
|
8956
|
+
await rm7(backup, { force: true, recursive: true });
|
|
8698
8957
|
}, restorePreviousBundle = async (backup, destination, moved) => {
|
|
8699
8958
|
if (!moved)
|
|
8700
8959
|
return;
|
|
@@ -8791,7 +9050,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8791
9050
|
}
|
|
8792
9051
|
const destination = options.config.bundleDirectory;
|
|
8793
9052
|
await mkdir9(dirname12(destination), { recursive: true });
|
|
8794
|
-
const staging = await
|
|
9053
|
+
const staging = await mkdtemp5(join21(dirname12(destination), `.${basename8(destination)}.stage-`));
|
|
8795
9054
|
try {
|
|
8796
9055
|
const pageDirectory = join21(staging, "pages");
|
|
8797
9056
|
await mkdir9(pageDirectory, { recursive: true });
|
|
@@ -8839,7 +9098,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8839
9098
|
await installBundle(staging, destination);
|
|
8840
9099
|
return manifest;
|
|
8841
9100
|
} catch (error) {
|
|
8842
|
-
await
|
|
9101
|
+
await rm7(staging, { force: true, recursive: true });
|
|
8843
9102
|
throw error;
|
|
8844
9103
|
}
|
|
8845
9104
|
};
|
|
@@ -8883,10 +9142,10 @@ import { createHash as createHash11 } from "crypto";
|
|
|
8883
9142
|
import {
|
|
8884
9143
|
access as access8,
|
|
8885
9144
|
mkdir as mkdir10,
|
|
8886
|
-
mkdtemp as
|
|
9145
|
+
mkdtemp as mkdtemp6,
|
|
8887
9146
|
readFile as readFile11,
|
|
8888
9147
|
rename as rename8,
|
|
8889
|
-
rm as
|
|
9148
|
+
rm as rm8,
|
|
8890
9149
|
writeFile as writeFile9
|
|
8891
9150
|
} from "fs/promises";
|
|
8892
9151
|
import { dirname as dirname13, join as join22, resolve as resolvePath3 } from "path";
|
|
@@ -8936,12 +9195,12 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8936
9195
|
if (!errorHasCode2(error, "ENOENT"))
|
|
8937
9196
|
throw error;
|
|
8938
9197
|
}
|
|
8939
|
-
const staging = await
|
|
9198
|
+
const staging = await mkdtemp6(join22(bundlesRoot, ".stage-"));
|
|
8940
9199
|
try {
|
|
8941
9200
|
await Promise.all(releases.map((release) => writeRelease(staging, release)));
|
|
8942
9201
|
await rename8(staging, destination);
|
|
8943
9202
|
} catch (error) {
|
|
8944
|
-
await
|
|
9203
|
+
await rm8(staging, { force: true, recursive: true });
|
|
8945
9204
|
if (errorHasCode2(error, "EEXIST") || errorHasCode2(error, "ENOTEMPTY")) {
|
|
8946
9205
|
return destination;
|
|
8947
9206
|
}
|
|
@@ -18987,7 +19246,7 @@ import {
|
|
|
18987
19246
|
mkdir as mkdir11,
|
|
18988
19247
|
readFile as readFile16,
|
|
18989
19248
|
rename as rename12,
|
|
18990
|
-
rm as
|
|
19249
|
+
rm as rm9,
|
|
18991
19250
|
writeFile as writeFile13
|
|
18992
19251
|
} from "fs/promises";
|
|
18993
19252
|
import { resolve as resolve37 } from "path";
|
|
@@ -19088,7 +19347,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
|
|
|
19088
19347
|
throw error;
|
|
19089
19348
|
}
|
|
19090
19349
|
if (hasCurrent)
|
|
19091
|
-
await
|
|
19350
|
+
await rm9(backup, { force: true, recursive: true });
|
|
19092
19351
|
}, materializeHost = async (root, host2, files) => {
|
|
19093
19352
|
const directory = resolve37(root, host2, ".well-known");
|
|
19094
19353
|
await mkdir11(directory, { recursive: true });
|
|
@@ -19136,7 +19395,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
|
|
|
19136
19395
|
const written = temporaryPaths.map((path) => resolve37(root, path.slice(temporary.length + 1)));
|
|
19137
19396
|
return { root, written };
|
|
19138
19397
|
} catch (error) {
|
|
19139
|
-
await
|
|
19398
|
+
await rm9(temporary, { force: true, recursive: true });
|
|
19140
19399
|
throw error;
|
|
19141
19400
|
}
|
|
19142
19401
|
}, verifyAbsoluteMobileAssociationFiles = async (config, request = globalThis.fetch) => {
|
|
@@ -20398,11 +20657,11 @@ import {
|
|
|
20398
20657
|
access as access12,
|
|
20399
20658
|
copyFile as copyFile5,
|
|
20400
20659
|
mkdir as mkdir13,
|
|
20401
|
-
mkdtemp as
|
|
20660
|
+
mkdtemp as mkdtemp7,
|
|
20402
20661
|
readFile as readFile19,
|
|
20403
20662
|
realpath as realpath2,
|
|
20404
20663
|
rename as rename13,
|
|
20405
|
-
rm as
|
|
20664
|
+
rm as rm10,
|
|
20406
20665
|
stat as stat3,
|
|
20407
20666
|
writeFile as writeFile15
|
|
20408
20667
|
} from "fs/promises";
|
|
@@ -20505,7 +20764,7 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord15 = (value) => typeof value ==
|
|
|
20505
20764
|
return { artifactPath: destination, metadata: existing, releaseRoot };
|
|
20506
20765
|
}
|
|
20507
20766
|
await mkdir13(dirname31(releaseRoot), { recursive: true });
|
|
20508
|
-
const staging = await
|
|
20767
|
+
const staging = await mkdtemp7(join53(dirname31(releaseRoot), ".android-stage-"));
|
|
20509
20768
|
try {
|
|
20510
20769
|
await copyFile5(artifactPath, join53(staging, artifactName));
|
|
20511
20770
|
const complete = {
|
|
@@ -20517,7 +20776,7 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord15 = (value) => typeof value ==
|
|
|
20517
20776
|
await rename13(staging, releaseRoot);
|
|
20518
20777
|
return { artifactPath: destination, metadata: complete, releaseRoot };
|
|
20519
20778
|
} finally {
|
|
20520
|
-
await
|
|
20779
|
+
await rm10(staging, { force: true, recursive: true }).catch(() => {
|
|
20521
20780
|
return;
|
|
20522
20781
|
});
|
|
20523
20782
|
}
|
|
@@ -22197,6 +22456,7 @@ Mobile release security and compliance checks failed.`);
|
|
|
22197
22456
|
"--play-track",
|
|
22198
22457
|
"--play-update-priority",
|
|
22199
22458
|
"--registry",
|
|
22459
|
+
"--remote",
|
|
22200
22460
|
"--testflight-group",
|
|
22201
22461
|
"--testflight-notes",
|
|
22202
22462
|
"--web-outdir"
|
|
@@ -22357,7 +22617,7 @@ Mobile release security and compliance checks failed.`);
|
|
|
22357
22617
|
await writeAbsoluteExpoProject(mobile, { projectRoot });
|
|
22358
22618
|
await ensureExpoPackages(mobile.nativeProjectDirectory, [...args, "--yes"]);
|
|
22359
22619
|
await syncAbsoluteExpoWebAssets(mobile);
|
|
22360
|
-
await runExpo(mobile.nativeProjectDirectory, ["prebuild", "--clean", "--
|
|
22620
|
+
await runExpo(mobile.nativeProjectDirectory, ["prebuild", "--clean", "--platform", "ios"], { production: true });
|
|
22361
22621
|
}, prepareCapacitorIosReleaseProject = async (mobile, projectRoot) => {
|
|
22362
22622
|
await writeAbsoluteCapacitorConfig(mobile, { projectRoot });
|
|
22363
22623
|
await runCapacitorForPlatforms(projectRoot, "sync", ["ios"]);
|
|
@@ -22472,6 +22732,18 @@ Mobile release security and compliance checks failed.`);
|
|
|
22472
22732
|
status: check2.status
|
|
22473
22733
|
})));
|
|
22474
22734
|
throw new TypeError("iOS release validation failed before Xcode signing.");
|
|
22735
|
+
}, buildLocalIosRelease = async (options) => {
|
|
22736
|
+
await prepareIosReleaseProject(options.mobile, options.projectRoot, options.args);
|
|
22737
|
+
await requireIosReleaseReady(options.mobile, options.projectRoot);
|
|
22738
|
+
return buildAbsoluteIosRelease({
|
|
22739
|
+
allowUnsigned: options.args.includes("--unsigned"),
|
|
22740
|
+
config: options.mobile,
|
|
22741
|
+
developmentTeam: process.env.ABSOLUTE_IOS_DEVELOPMENT_TEAM,
|
|
22742
|
+
...options.mobile.engine === "expo" ? { env: expoProductionEnvironment() } : {},
|
|
22743
|
+
outputDirectory: valueAfter(options.args, "--outdir"),
|
|
22744
|
+
...options.prepareBuildNumber === undefined ? {} : { prepareBuildNumber: options.prepareBuildNumber },
|
|
22745
|
+
projectRoot: options.projectRoot
|
|
22746
|
+
});
|
|
22475
22747
|
}, buildIos = async (args, prepareBuildNumber) => {
|
|
22476
22748
|
const configPath2 = valueAfter(args, "--config");
|
|
22477
22749
|
const { mobile, projectRoot } = await loadMobile(configPath2);
|
|
@@ -22479,19 +22751,37 @@ Mobile release security and compliance checks failed.`);
|
|
|
22479
22751
|
throw new TypeError("mobile build ios requires ios in mobile.platforms.");
|
|
22480
22752
|
}
|
|
22481
22753
|
const startedAt = performance.now();
|
|
22754
|
+
const requestedRemote = valueAfter(args, "--remote");
|
|
22755
|
+
if (args.includes("--remote") && (!requestedRemote || requestedRemote.startsWith("-")))
|
|
22756
|
+
throw new TypeError("mobile build ios requires --remote <name>.");
|
|
22757
|
+
const remoteProfile = requestedRemote !== undefined || process.platform !== "darwin" ? await getAbsoluteRemoteMacProfile(requestedRemote, remoteProfilePath()) : undefined;
|
|
22758
|
+
if (process.platform !== "darwin" && !remoteProfile)
|
|
22759
|
+
throw new TypeError("iOS release builds require macOS or a paired Remote Mac. Run `absolute mobile pair mac <name> <user@host>`.");
|
|
22482
22760
|
let success = false;
|
|
22483
22761
|
try {
|
|
22484
|
-
if (mobile.engine === "capacitor")
|
|
22762
|
+
if (!remoteProfile && mobile.engine === "capacitor")
|
|
22485
22763
|
await repairAbsoluteIosDevSession(projectRoot);
|
|
22486
22764
|
await start(mobileBuildServerEntry(args), valueAfter(args, "--web-outdir"), configPath2, { prepareOnly: true });
|
|
22487
|
-
await
|
|
22488
|
-
await requireIosReleaseReady(mobile, projectRoot);
|
|
22489
|
-
const release = await buildAbsoluteIosRelease({
|
|
22765
|
+
const release = remoteProfile ? await buildAbsoluteRemoteIosRelease({
|
|
22490
22766
|
allowUnsigned: args.includes("--unsigned"),
|
|
22491
|
-
config: mobile,
|
|
22492
22767
|
developmentTeam: process.env.ABSOLUTE_IOS_DEVELOPMENT_TEAM,
|
|
22493
|
-
...mobile.engine === "expo" ? { env: expoProductionEnvironment() } : {},
|
|
22494
22768
|
outputDirectory: valueAfter(args, "--outdir"),
|
|
22769
|
+
log: (message) => console.log(`[remote] ${message}`),
|
|
22770
|
+
onPhaseTiming: ({ durationMs: durationMs2, phase }) => {
|
|
22771
|
+
console.log(`[mobile:ios-release] ${phase} ${getDurationString(durationMs2)}`);
|
|
22772
|
+
sendTelemetryEvent("mobile:ios-release-phase", {
|
|
22773
|
+
durationMs: Math.round(durationMs2),
|
|
22774
|
+
engine: mobile.engine,
|
|
22775
|
+
phase,
|
|
22776
|
+
platform: "ios",
|
|
22777
|
+
provider: "remote-mac"
|
|
22778
|
+
});
|
|
22779
|
+
},
|
|
22780
|
+
...prepareBuildNumber === undefined ? {} : { prepareBuildNumber },
|
|
22781
|
+
project: createAbsoluteRemoteIosDevProject(mobile, projectRoot, remoteProfile)
|
|
22782
|
+
}) : await buildLocalIosRelease({
|
|
22783
|
+
args,
|
|
22784
|
+
mobile,
|
|
22495
22785
|
...prepareBuildNumber === undefined ? {} : { prepareBuildNumber },
|
|
22496
22786
|
projectRoot
|
|
22497
22787
|
});
|
|
@@ -22506,6 +22796,7 @@ Mobile release security and compliance checks failed.`);
|
|
|
22506
22796
|
durationMs: Math.round(performance.now() - startedAt),
|
|
22507
22797
|
engine: mobile.engine,
|
|
22508
22798
|
platform: "ios",
|
|
22799
|
+
remote: remoteProfile !== undefined,
|
|
22509
22800
|
success,
|
|
22510
22801
|
type: "ipa",
|
|
22511
22802
|
unsignedAllowed: args.includes("--unsigned")
|
|
@@ -23427,7 +23718,7 @@ Emulator setup verification:`);
|
|
|
23427
23718
|
await publishIos(args.slice(2));
|
|
23428
23719
|
return;
|
|
23429
23720
|
}
|
|
23430
|
-
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] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
23721
|
+
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] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--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] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
23431
23722
|
};
|
|
23432
23723
|
var init_mobile = __esm(() => {
|
|
23433
23724
|
init_dependencies();
|