@limrun/api 0.31.0 → 0.31.1
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/CHANGELOG.md +4 -0
- package/index.d.mts +2 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +2 -1
- package/index.d.ts.map +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/index.mjs +1 -0
- package/index.mjs.map +1 -1
- package/package.json +11 -1
- package/rbe-bep.d.mts +27 -0
- package/rbe-bep.d.mts.map +1 -0
- package/rbe-bep.d.ts +27 -0
- package/rbe-bep.d.ts.map +1 -0
- package/rbe-bep.js +130 -0
- package/rbe-bep.js.map +1 -0
- package/rbe-bep.mjs +127 -0
- package/rbe-bep.mjs.map +1 -0
- package/resources/index.d.mts +1 -1
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +1 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js.map +1 -1
- package/resources/index.mjs.map +1 -1
- package/resources/xcode-instances-helpers.d.mts +44 -1
- package/resources/xcode-instances-helpers.d.mts.map +1 -1
- package/resources/xcode-instances-helpers.d.ts +44 -1
- package/resources/xcode-instances-helpers.d.ts.map +1 -1
- package/resources/xcode-instances-helpers.js +70 -24
- package/resources/xcode-instances-helpers.js.map +1 -1
- package/resources/xcode-instances-helpers.mjs +70 -24
- package/resources/xcode-instances-helpers.mjs.map +1 -1
- package/src/index.ts +2 -0
- package/src/rbe-bep.ts +155 -0
- package/src/resources/index.ts +1 -0
- package/src/resources/xcode-instances-helpers.ts +136 -27
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -4,6 +4,7 @@ import crypto from 'crypto';
|
|
|
4
4
|
|
|
5
5
|
import { XcodeInstances as GeneratedXcodeInstances, type XcodeInstance } from './xcode-instances';
|
|
6
6
|
import { type IosInstance } from './ios-instances';
|
|
7
|
+
import { parseTopLevelIpaDigest } from '../rbe-bep';
|
|
7
8
|
import { exec, type ExecChildProcess, type ExecRequest } from '../exec-client';
|
|
8
9
|
import {
|
|
9
10
|
syncFolder as syncFolderImpl,
|
|
@@ -179,6 +180,27 @@ export type RbeTunnelOptions = {
|
|
|
179
180
|
logLevel?: LogLevel;
|
|
180
181
|
};
|
|
181
182
|
|
|
183
|
+
/** Content-addressed digest of a build artifact in the instance's RBE cache. */
|
|
184
|
+
type RbeArtifactDigest = {
|
|
185
|
+
/** Lowercase hex SHA-256 of the blob (matches --digest_function=sha256). */
|
|
186
|
+
hash: string;
|
|
187
|
+
/** Size of the blob in bytes. */
|
|
188
|
+
sizeBytes: number;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export type RbeInstallResult = {
|
|
192
|
+
/** True when the app was synced and installed on the attached simulator. */
|
|
193
|
+
installed: boolean;
|
|
194
|
+
/** CFBundleIdentifier of the installed app, as reported by the simulator. */
|
|
195
|
+
bundleId?: string;
|
|
196
|
+
/** The .app bundle name discovered inside the .ipa (Payload/<appName>.app). */
|
|
197
|
+
appName?: string;
|
|
198
|
+
/** Differential-sync duration in milliseconds. */
|
|
199
|
+
syncDurationMs?: number;
|
|
200
|
+
/** Simulator install duration in milliseconds. */
|
|
201
|
+
installDurationMs?: number;
|
|
202
|
+
};
|
|
203
|
+
|
|
182
204
|
export type XcodeClient = {
|
|
183
205
|
/**
|
|
184
206
|
* Sync source code to the xcode instance. In watch mode, keeps syncing on changes.
|
|
@@ -198,7 +220,9 @@ export type XcodeClient = {
|
|
|
198
220
|
|
|
199
221
|
/**
|
|
200
222
|
* Attach a simulator to this xcode instance.
|
|
201
|
-
* After attaching,
|
|
223
|
+
* After attaching, the latest xcodebuild build (if any) is installed on the
|
|
224
|
+
* simulator. RBE builds are not auto-installed on attach — install them
|
|
225
|
+
* explicitly with `installRbeBuildFromBep` while a simulator is attached.
|
|
202
226
|
*/
|
|
203
227
|
attachSimulator: (
|
|
204
228
|
simulator: IosInstance | { apiUrl: string; token: string },
|
|
@@ -221,12 +245,39 @@ export type XcodeClient = {
|
|
|
221
245
|
/** Stop the RBE stack. */
|
|
222
246
|
stopRbe: () => Promise<RbeStatus>;
|
|
223
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Install a Bazel RBE build on the attached simulator, server-side, from its
|
|
250
|
+
* build event log (BEP). Parses the top-level `.ipa`'s CAS digest for `target`
|
|
251
|
+
* out of `bep` (the contents of `--build_event_json_file`); the instance fetches
|
|
252
|
+
* the blob from its embedded cache, unpacks the .app, and pushes it to the
|
|
253
|
+
* attached simulator via the differential-sync path — no client round-trip.
|
|
254
|
+
* Requires a running RBE stack and an attached simulator (installed=false when
|
|
255
|
+
* none is attached — attach one and call again). Throws a descriptive error if
|
|
256
|
+
* the target/.ipa is absent, was downloaded locally, or was built with a
|
|
257
|
+
* non-SHA256 digest (e.g. BLAKE3) the instance cache can't resolve. `ipaName` is
|
|
258
|
+
* the `.ipa` file name Bazel reported.
|
|
259
|
+
*/
|
|
260
|
+
installRbeBuildFromBep: (opts: {
|
|
261
|
+
bep: string;
|
|
262
|
+
target: string;
|
|
263
|
+
}) => Promise<RbeInstallResult & { ipaName: string }>;
|
|
264
|
+
|
|
224
265
|
/**
|
|
225
266
|
* Open a local TCP listener bridged to the instance's RBE gRPC frontend
|
|
226
267
|
* over a multiplexed websocket. Point bazel at it with
|
|
227
268
|
* --remote_executor=grpc://127.0.0.1:<port>.
|
|
228
269
|
*/
|
|
229
270
|
startRbeTunnel: (opts?: RbeTunnelOptions) => Promise<Tunnel>;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Create a new iOS simulator instance and attach it to this xcode instance.
|
|
274
|
+
* Deletes the simulator if attach fails so it is never leaked. Returns the new
|
|
275
|
+
* simulator's instance id (record it for teardown) and the instance itself.
|
|
276
|
+
*/
|
|
277
|
+
attachNewSimulator: () => Promise<{ iosInstanceId: string; simulator: IosInstance }>;
|
|
278
|
+
|
|
279
|
+
/** Best-effort delete of a simulator instance. Never throws; returns success. */
|
|
280
|
+
deleteSimulator: (iosInstanceId: string) => Promise<boolean>;
|
|
230
281
|
};
|
|
231
282
|
|
|
232
283
|
export type XcodeCreateClientParams =
|
|
@@ -366,6 +417,84 @@ export class XcodeInstances extends GeneratedXcodeInstances {
|
|
|
366
417
|
return sandboxInfoPromise;
|
|
367
418
|
};
|
|
368
419
|
|
|
420
|
+
// Shared local closures. The methods below live in an object literal over
|
|
421
|
+
// these closures (not `this`), so anything reused across methods is defined
|
|
422
|
+
// here once and called from each method.
|
|
423
|
+
const postRbeInstall = async (
|
|
424
|
+
ipaDigest: RbeArtifactDigest,
|
|
425
|
+
target?: string,
|
|
426
|
+
): Promise<RbeInstallResult> => {
|
|
427
|
+
const res = await nodeProxyTransport.fetch(`${apiUrl}/rbe/install`, {
|
|
428
|
+
method: 'POST',
|
|
429
|
+
headers: {
|
|
430
|
+
'Content-Type': 'application/json',
|
|
431
|
+
Authorization: `Bearer ${token}`,
|
|
432
|
+
},
|
|
433
|
+
body: JSON.stringify({ ipaDigest, ...(target ? { target } : {}) }),
|
|
434
|
+
});
|
|
435
|
+
return readRbeResponse<RbeInstallResult>(res, 'POST /rbe/install');
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
const installFromBep = async (
|
|
439
|
+
bep: string,
|
|
440
|
+
target: string,
|
|
441
|
+
): Promise<RbeInstallResult & { ipaName: string }> => {
|
|
442
|
+
const digest = parseTopLevelIpaDigest(bep, target); // throws BLAKE3 / no-ipa errors
|
|
443
|
+
const result = await postRbeInstall({ hash: digest.hash, sizeBytes: digest.sizeBytes }, target);
|
|
444
|
+
return { ...result, ipaName: digest.ipaName };
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
const attachSimulatorImpl = async (
|
|
448
|
+
simulator: IosInstance | { apiUrl: string; token: string },
|
|
449
|
+
): Promise<SimulatorAttachResult> => {
|
|
450
|
+
let simApiUrl: string;
|
|
451
|
+
let simToken: string;
|
|
452
|
+
if ('status' in simulator) {
|
|
453
|
+
if (!simulator.status.apiUrl) {
|
|
454
|
+
throw new Error('Simulator instance not ready: apiUrl is not available');
|
|
455
|
+
}
|
|
456
|
+
simApiUrl = simulator.status.apiUrl;
|
|
457
|
+
simToken = simulator.status.token;
|
|
458
|
+
} else {
|
|
459
|
+
simApiUrl = simulator.apiUrl;
|
|
460
|
+
simToken = simulator.token;
|
|
461
|
+
}
|
|
462
|
+
const res = await nodeProxyTransport.fetch(`${apiUrl}/simulator`, {
|
|
463
|
+
method: 'POST',
|
|
464
|
+
headers: {
|
|
465
|
+
'Content-Type': 'application/json',
|
|
466
|
+
Authorization: `Bearer ${token}`,
|
|
467
|
+
},
|
|
468
|
+
body: JSON.stringify({ apiUrl: simApiUrl, token: simToken }),
|
|
469
|
+
});
|
|
470
|
+
return readJsonResponse<SimulatorAttachResult>(res, 'POST /simulator');
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
const deleteSimulatorImpl = async (iosInstanceId: string): Promise<boolean> => {
|
|
474
|
+
try {
|
|
475
|
+
await client.iosInstances.delete(iosInstanceId);
|
|
476
|
+
return true;
|
|
477
|
+
} catch {
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
const attachNewSimulatorImpl = async (): Promise<{
|
|
483
|
+
iosInstanceId: string;
|
|
484
|
+
simulator: IosInstance;
|
|
485
|
+
}> => {
|
|
486
|
+
const simulator = await client.iosInstances.create({ wait: true });
|
|
487
|
+
// The sim exists from here; if attach fails, delete it so we never leak an
|
|
488
|
+
// orphan the caller can't reap.
|
|
489
|
+
try {
|
|
490
|
+
await attachSimulatorImpl(simulator);
|
|
491
|
+
} catch (err) {
|
|
492
|
+
await deleteSimulatorImpl(simulator.metadata.id);
|
|
493
|
+
throw err;
|
|
494
|
+
}
|
|
495
|
+
return { iosInstanceId: simulator.metadata.id, simulator };
|
|
496
|
+
};
|
|
497
|
+
|
|
369
498
|
return {
|
|
370
499
|
async sync(localCodePath: string, opts?: SyncOptions): Promise<SyncResult> {
|
|
371
500
|
const resolvedPath = path.resolve(localCodePath);
|
|
@@ -486,32 +615,9 @@ export class XcodeInstances extends GeneratedXcodeInstances {
|
|
|
486
615
|
return readJsonResponse<SimulatorStatus>(res, 'GET /simulator');
|
|
487
616
|
},
|
|
488
617
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
let simApiUrl: string;
|
|
493
|
-
let simToken: string;
|
|
494
|
-
if ('status' in simulator) {
|
|
495
|
-
if (!simulator.status.apiUrl) {
|
|
496
|
-
throw new Error('Simulator instance not ready: apiUrl is not available');
|
|
497
|
-
}
|
|
498
|
-
simApiUrl = simulator.status.apiUrl;
|
|
499
|
-
simToken = simulator.status.token;
|
|
500
|
-
} else {
|
|
501
|
-
simApiUrl = simulator.apiUrl;
|
|
502
|
-
simToken = simulator.token;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
const res = await nodeProxyTransport.fetch(`${apiUrl}/simulator`, {
|
|
506
|
-
method: 'POST',
|
|
507
|
-
headers: {
|
|
508
|
-
'Content-Type': 'application/json',
|
|
509
|
-
Authorization: `Bearer ${token}`,
|
|
510
|
-
},
|
|
511
|
-
body: JSON.stringify({ apiUrl: simApiUrl, token: simToken }),
|
|
512
|
-
});
|
|
513
|
-
return readJsonResponse<SimulatorAttachResult>(res, 'POST /simulator');
|
|
514
|
-
},
|
|
618
|
+
attachSimulator: attachSimulatorImpl,
|
|
619
|
+
attachNewSimulator: attachNewSimulatorImpl,
|
|
620
|
+
deleteSimulator: deleteSimulatorImpl,
|
|
515
621
|
|
|
516
622
|
async startRbe(opts?: RbeStartOptions): Promise<RbeStatus> {
|
|
517
623
|
const res = await nodeProxyTransport.fetch(`${apiUrl}/rbe`, {
|
|
@@ -545,6 +651,9 @@ export class XcodeInstances extends GeneratedXcodeInstances {
|
|
|
545
651
|
return readRbeResponse<RbeStatus>(res, 'DELETE /rbe');
|
|
546
652
|
},
|
|
547
653
|
|
|
654
|
+
installRbeBuildFromBep: (opts: { bep: string; target: string }) =>
|
|
655
|
+
installFromBep(opts.bep, opts.target),
|
|
656
|
+
|
|
548
657
|
async startRbeTunnel(opts?: RbeTunnelOptions): Promise<Tunnel> {
|
|
549
658
|
return startTcpTunnel(
|
|
550
659
|
deriveRbeTunnelUrl(apiUrl),
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.31.
|
|
1
|
+
export const VERSION = '0.31.1'; // x-release-please-version
|
package/version.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.31.
|
|
1
|
+
export declare const VERSION = "0.31.1";
|
|
2
2
|
//# sourceMappingURL=version.d.mts.map
|
package/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.31.
|
|
1
|
+
export declare const VERSION = "0.31.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/version.js
CHANGED
package/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.31.
|
|
1
|
+
export const VERSION = '0.31.1'; // x-release-please-version
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|