@better-update/cli 0.12.1 → 0.13.0
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/index.mjs +81 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -28,7 +28,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
28
28
|
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region package.json
|
|
31
|
-
var version = "0.
|
|
31
|
+
var version = "0.13.0";
|
|
32
32
|
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region src/lib/interactive-mode.ts
|
|
@@ -5278,17 +5278,30 @@ const DISTRIBUTION_TO_CERTIFICATE_TYPE = {
|
|
|
5278
5278
|
DEVELOPMENT: AppleUtils.CertificateType.IOS_DEVELOPMENT
|
|
5279
5279
|
};
|
|
5280
5280
|
var AppleIdGenerateFailedError = class extends Data.TaggedError("AppleIdGenerateFailedError") {};
|
|
5281
|
+
const CERT_LIMIT_PATTERN = /already have a current.*certificate|pending certificate request/iu;
|
|
5282
|
+
const messageOf = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
5281
5283
|
const wrap = (step, run) => Effect.tryPromise({
|
|
5282
5284
|
try: run,
|
|
5283
5285
|
catch: (cause) => new AppleIdGenerateFailedError({
|
|
5284
5286
|
step,
|
|
5285
|
-
message:
|
|
5287
|
+
message: messageOf(cause)
|
|
5286
5288
|
})
|
|
5287
5289
|
});
|
|
5290
|
+
const wrapCertificateCreate = (run) => Effect.tryPromise({
|
|
5291
|
+
try: run,
|
|
5292
|
+
catch: (cause) => {
|
|
5293
|
+
const message = messageOf(cause);
|
|
5294
|
+
if (CERT_LIMIT_PATTERN.test(message)) return new CertificateLimitError({ message });
|
|
5295
|
+
return new AppleIdGenerateFailedError({
|
|
5296
|
+
step: "apple-create-certificate",
|
|
5297
|
+
message
|
|
5298
|
+
});
|
|
5299
|
+
}
|
|
5300
|
+
});
|
|
5288
5301
|
const generateAndUploadDistributionCertificateViaAppleId = (api, input) => Effect.gen(function* () {
|
|
5289
5302
|
const ctx = input.context;
|
|
5290
5303
|
const certificateType = input.certificateType === "IOS_DEVELOPMENT" ? AppleUtils.CertificateType.IOS_DEVELOPMENT : AppleUtils.CertificateType.IOS_DISTRIBUTION;
|
|
5291
|
-
const result = yield*
|
|
5304
|
+
const result = yield* wrapCertificateCreate(async () => AppleUtils.createCertificateAndP12Async(ctx, { certificateType }));
|
|
5292
5305
|
const metadata = yield* extractMetadataFromP12({
|
|
5293
5306
|
p12Base64: result.certificateP12,
|
|
5294
5307
|
password: result.password
|
|
@@ -5312,6 +5325,16 @@ const generateAndUploadDistributionCertificateViaAppleId = (api, input) => Effec
|
|
|
5312
5325
|
developerPortalIdentifier: result.certificate.id
|
|
5313
5326
|
};
|
|
5314
5327
|
});
|
|
5328
|
+
const listDistributionCertsViaAppleId = (ctx, certificateType = "IOS_DISTRIBUTION") => Effect.gen(function* () {
|
|
5329
|
+
const filter = certificateType === "IOS_DEVELOPMENT" ? AppleUtils.CertificateType.IOS_DEVELOPMENT : AppleUtils.CertificateType.IOS_DISTRIBUTION;
|
|
5330
|
+
return (yield* wrap("apple-list-certificates", async () => AppleUtils.Certificate.getAsync(ctx, { query: { filter: { certificateType: filter } } }))).map((entry) => ({
|
|
5331
|
+
developerPortalIdentifier: entry.id,
|
|
5332
|
+
serialNumber: entry.attributes.serialNumber,
|
|
5333
|
+
displayName: entry.attributes.displayName,
|
|
5334
|
+
expirationDate: entry.attributes.expirationDate
|
|
5335
|
+
}));
|
|
5336
|
+
});
|
|
5337
|
+
const revokeDistributionCertViaAppleId = (ctx, developerPortalIdentifier) => wrap("apple-revoke-certificate", async () => AppleUtils.Certificate.deleteAsync(ctx, { id: developerPortalIdentifier }));
|
|
5315
5338
|
const findOrCreateBundleId = (ctx, bundleIdentifier) => Effect.gen(function* () {
|
|
5316
5339
|
const existing = yield* wrap("apple-find-bundle-id", async () => AppleUtils.BundleId.findAsync(ctx, { identifier: bundleIdentifier }));
|
|
5317
5340
|
if (existing !== null) return existing.id;
|
|
@@ -5393,13 +5416,66 @@ const chooseIosSetupPath = (api) => Effect.gen(function* () {
|
|
|
5393
5416
|
label: "Use an App Store Connect API key"
|
|
5394
5417
|
}]);
|
|
5395
5418
|
});
|
|
5419
|
+
const interactiveAppleIdCertLimitRecover = (ctx) => Effect.gen(function* () {
|
|
5420
|
+
yield* Console.log("");
|
|
5421
|
+
yield* Console.log("Apple reports the certificate limit was hit (max 3 distribution certs per team).");
|
|
5422
|
+
const certs = yield* listDistributionCertsViaAppleId(ctx, "IOS_DISTRIBUTION");
|
|
5423
|
+
if (certs.length === 0) return yield* new AppleIdGenerateFailedError({
|
|
5424
|
+
step: "limit-recover",
|
|
5425
|
+
message: "Apple says the certificate limit is hit but no existing certificates were returned."
|
|
5426
|
+
});
|
|
5427
|
+
const toRevoke = yield* promptMultiSelect("Select one or more certificates to revoke before retrying", certs.map((entry) => ({
|
|
5428
|
+
value: entry.developerPortalIdentifier,
|
|
5429
|
+
label: `${entry.serialNumber.slice(0, 12)}… (${entry.displayName}, exp ${entry.expirationDate.slice(0, 10)})`
|
|
5430
|
+
})), { required: true });
|
|
5431
|
+
yield* Effect.forEach(toRevoke, (id) => revokeDistributionCertViaAppleId(ctx, id), { concurrency: "inherit" });
|
|
5432
|
+
yield* Console.log(`Revoked ${toRevoke.length} certificate(s); retrying generation...`);
|
|
5433
|
+
});
|
|
5434
|
+
const generateDistributionCertViaAppleIdInteractive = (api, ctx) => Effect.gen(function* () {
|
|
5435
|
+
yield* Console.log("Generating distribution certificate via Apple ID...");
|
|
5436
|
+
const generate = generateAndUploadDistributionCertificateViaAppleId(api, { context: ctx });
|
|
5437
|
+
return yield* generate.pipe(Effect.catchTag("CertificateLimitError", () => interactiveAppleIdCertLimitRecover(ctx).pipe(Effect.flatMap(() => generate))));
|
|
5438
|
+
});
|
|
5439
|
+
const GENERATE_NEW = "__generate__";
|
|
5440
|
+
const chooseDistributionCertViaAppleId = (api, ctx, appleTeamId) => Effect.gen(function* () {
|
|
5441
|
+
const items = (yield* api.appleDistributionCertificates.list()).items.filter((cert) => cert.appleTeamId === appleTeamId);
|
|
5442
|
+
if (items.length === 0) {
|
|
5443
|
+
const created = yield* generateDistributionCertViaAppleIdInteractive(api, ctx);
|
|
5444
|
+
return {
|
|
5445
|
+
id: created.id,
|
|
5446
|
+
appleTeamId: created.appleTeamId
|
|
5447
|
+
};
|
|
5448
|
+
}
|
|
5449
|
+
const choice = yield* promptSelect("Select a distribution certificate (or 'generate' for a fresh one)", [{
|
|
5450
|
+
value: GENERATE_NEW,
|
|
5451
|
+
label: "Generate a new distribution certificate"
|
|
5452
|
+
}, ...items.map((cert) => ({
|
|
5453
|
+
value: cert.id,
|
|
5454
|
+
label: `${cert.serialNumber.slice(0, 12)}… (team ${cert.appleTeamId})`
|
|
5455
|
+
}))]);
|
|
5456
|
+
if (choice === GENERATE_NEW) {
|
|
5457
|
+
const created = yield* generateDistributionCertViaAppleIdInteractive(api, ctx);
|
|
5458
|
+
return {
|
|
5459
|
+
id: created.id,
|
|
5460
|
+
appleTeamId: created.appleTeamId
|
|
5461
|
+
};
|
|
5462
|
+
}
|
|
5463
|
+
const cert = items.find((entry) => entry.id === choice);
|
|
5464
|
+
if (cert === void 0) return yield* new AppleIdGenerateFailedError({
|
|
5465
|
+
step: "pick-certificate",
|
|
5466
|
+
message: `Selected certificate ${choice} not found after listing`
|
|
5467
|
+
});
|
|
5468
|
+
return {
|
|
5469
|
+
id: cert.id,
|
|
5470
|
+
appleTeamId: cert.appleTeamId
|
|
5471
|
+
};
|
|
5472
|
+
});
|
|
5396
5473
|
const setupIosViaAppleId = (api, input) => Effect.gen(function* () {
|
|
5397
5474
|
const auth = yield* AppleAuth;
|
|
5398
5475
|
const session = yield* auth.ensureLoggedIn();
|
|
5399
5476
|
const ctx = auth.buildRequestContext(session);
|
|
5400
5477
|
yield* Console.log(`Logged in as ${session.username}. Team: ${session.teamName ?? session.teamId} (${session.teamId}).`);
|
|
5401
|
-
yield*
|
|
5402
|
-
const cert = yield* generateAndUploadDistributionCertificateViaAppleId(api, { context: ctx });
|
|
5478
|
+
const cert = yield* chooseDistributionCertViaAppleId(api, ctx, session.teamId);
|
|
5403
5479
|
const distributionType = IOS_DISTRIBUTION_TO_TYPE[input.distribution];
|
|
5404
5480
|
yield* Console.log("Generating provisioning profile via Apple ID...");
|
|
5405
5481
|
const profile = yield* generateAndUploadProvisioningProfileViaAppleId(api, {
|