@better-update/cli 0.36.2 → 0.37.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 CHANGED
@@ -35,7 +35,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
35
35
 
36
36
  //#endregion
37
37
  //#region package.json
38
- var version = "0.36.2";
38
+ var version = "0.37.0";
39
39
 
40
40
  //#endregion
41
41
  //#region src/lib/interactive-mode.ts
@@ -22076,6 +22076,51 @@ const runAndroidBuild = (input) => Effect.gen(function* () {
22076
22076
  return input.strategy === "custom" ? yield* runAndroidCustom(input, commandEnv) : yield* runGradleBuild(input, commandEnv);
22077
22077
  });
22078
22078
 
22079
+ //#endregion
22080
+ //#region src/lib/credential-choices.ts
22081
+ /** ISO timestamp → `YYYY-MM-DD` for compact, scannable labels. */
22082
+ const isoDate = (value) => value.slice(0, 10);
22083
+ /**
22084
+ * Credentials store the internal team UUID, which is meaningless to read. Build a
22085
+ * resolver from `appleTeams.list()` that maps it to the team name (falling back to
22086
+ * the 10-char portal identifier, then the raw id if the team isn't in the list).
22087
+ */
22088
+ const makeAppleTeamLabeler = (teams) => {
22089
+ const byId = new Map(teams.map((team) => [team.id, team.name ?? team.appleTeamId]));
22090
+ return (internalTeamId) => byId.get(internalTeamId) ?? internalTeamId;
22091
+ };
22092
+ /**
22093
+ * Keystore aliases are often cryptic, so surface the type + creation date in the
22094
+ * label and the SHA-1 fingerprint (which matches the Play Console upload key) on
22095
+ * the active-row hint.
22096
+ */
22097
+ const keystoreChoice = (item) => {
22098
+ const details = [item.keystoreType, `created ${isoDate(item.createdAt)}`].filter((part) => part !== null);
22099
+ return {
22100
+ value: item.id,
22101
+ label: `${item.keyAlias} (${details.join(", ")})`,
22102
+ hint: item.sha1Fingerprint ? `SHA-1 ${item.sha1Fingerprint}` : `id ${item.id.slice(0, 8)}…`
22103
+ };
22104
+ };
22105
+ /**
22106
+ * Push keys share a team, so include the creation date to tell siblings apart.
22107
+ * Pass a `teamLabel` (see {@link makeAppleTeamLabeler}) to show the team name
22108
+ * instead of the internal UUID.
22109
+ */
22110
+ const pushKeyChoice = (key, teamLabel = key.appleTeamId) => ({
22111
+ value: key.id,
22112
+ label: `${key.keyId} (team ${teamLabel}, added ${isoDate(key.createdAt)})`
22113
+ });
22114
+ /**
22115
+ * Surface the expiry so an expired certificate is obvious before it's picked.
22116
+ * Pass a `teamLabel` (see {@link makeAppleTeamLabeler}) to show the team name
22117
+ * instead of the internal UUID.
22118
+ */
22119
+ const distributionCertChoice = (cert, teamLabel = cert.appleTeamId) => ({
22120
+ value: cert.id,
22121
+ label: `${cert.serialNumber.slice(0, 12)}… (team ${teamLabel}, exp ${isoDate(cert.validUntil)})`
22122
+ });
22123
+
22079
22124
  //#endregion
22080
22125
  //#region src/lib/credentials-generator-apple-id.ts
22081
22126
  const DISTRIBUTION_TO_PROFILE_TYPE = {
@@ -22443,10 +22488,7 @@ const chooseDistributionCertViaAppleId = (api, ctx, appleTeamIdentifier) => Effe
22443
22488
  const choice = yield* promptSelect("Select a distribution certificate (or 'generate' for a fresh one)", [{
22444
22489
  value: GENERATE_NEW,
22445
22490
  label: "Generate a new distribution certificate"
22446
- }, ...items.map((cert) => ({
22447
- value: cert.id,
22448
- label: `${cert.serialNumber.slice(0, 12)}… (team ${appleTeamIdentifier})`
22449
- }))]);
22491
+ }, ...items.map((cert) => distributionCertChoice(cert, team?.name ?? appleTeamIdentifier))]);
22450
22492
  if (choice === GENERATE_NEW) {
22451
22493
  const created = yield* generateDistributionCertViaAppleIdInteractive(api, ctx);
22452
22494
  return {
@@ -22557,13 +22599,11 @@ const chooseIosCertificateId = (api) => Effect.gen(function* () {
22557
22599
  });
22558
22600
  return (yield* generateDistributionCertInteractive(api)).id;
22559
22601
  }
22602
+ const teamLabel = makeAppleTeamLabeler((yield* api.appleTeams.list()).items);
22560
22603
  const choice = yield* promptSelect("Select a distribution certificate (or 'generate' for a fresh one)", [{
22561
22604
  value: "__generate__",
22562
22605
  label: "Generate a new distribution certificate"
22563
- }, ...certs.items.map((cert) => ({
22564
- value: cert.id,
22565
- label: `${cert.serialNumber.slice(0, 12)}… (team ${cert.appleTeamId})`
22566
- }))]);
22606
+ }, ...certs.items.map((cert) => distributionCertChoice(cert, teamLabel(cert.appleTeamId)))]);
22567
22607
  if (choice === "__generate__") return (yield* generateDistributionCertInteractive(api)).id;
22568
22608
  return choice;
22569
22609
  });
@@ -22665,10 +22705,7 @@ const pickExistingKeystore = (api) => Effect.gen(function* () {
22665
22705
  message: "No existing keystores in this organization.",
22666
22706
  hint: "Re-run and choose 'Generate new keystore'."
22667
22707
  });
22668
- return yield* promptSelect("Select a keystore", keystores.items.map((item) => ({
22669
- value: item.id,
22670
- label: item.keyAlias
22671
- })));
22708
+ return yield* promptSelect("Select a keystore", keystores.items.map(keystoreChoice));
22672
22709
  });
22673
22710
  const resolveAndroidAppId = (api, input) => Effect.gen(function* () {
22674
22711
  const existing = (yield* api.androidApplicationIdentifiers.list({ path: { projectId: input.projectId } })).items.find((item) => item.packageName === input.applicationIdentifier);
@@ -26365,10 +26402,7 @@ const changeDefaultKeystore = (ctx) => Effect.gen(function* () {
26365
26402
  const downloadAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
26366
26403
  const list = yield* ctx.api.androidUploadKeystores.list();
26367
26404
  if (list.items.length === 0) return yield* Console.log("No keystores to download.");
26368
- const id = yield* promptSelect("Select a keystore to download", list.items.map((item) => ({
26369
- value: item.id,
26370
- label: `${item.keyAlias} (${item.id.slice(0, 8)}…)`
26371
- })));
26405
+ const id = yield* promptSelect("Select a keystore to download", list.items.map(keystoreChoice));
26372
26406
  const data = yield* ctx.api.androidUploadKeystores.download({ path: { id } });
26373
26407
  const secret = yield* openFromDownload({
26374
26408
  session: yield* openVaultSessionInteractive(ctx.api),
@@ -26692,10 +26726,8 @@ const revokeIosDistributionCert = (ctx) => Effect.gen(function* () {
26692
26726
  message: "No ASC API key linked to an Apple team.",
26693
26727
  hint: "Upload an ASC API key first so the CLI can call Apple to revoke."
26694
26728
  });
26695
- const localId = yield* promptSelect("Select a distribution certificate to revoke", certs.items.map((cert) => ({
26696
- value: cert.id,
26697
- label: `${cert.serialNumber.slice(0, 12)}… (team ${cert.appleTeamId})`
26698
- })));
26729
+ const teamLabel = makeAppleTeamLabeler((yield* ctx.api.appleTeams.list()).items);
26730
+ const localId = yield* promptSelect("Select a distribution certificate to revoke", certs.items.map((cert) => distributionCertChoice(cert, teamLabel(cert.appleTeamId))));
26699
26731
  const target = certs.items.find((entry) => entry.id === localId);
26700
26732
  const ascApiKeyId = teamKeys.find((key) => key.appleTeamId === target?.appleTeamId)?.id ?? (yield* promptSelect("Select an ASC API key to call Apple with", teamKeys.map((key) => ({
26701
26733
  value: key.id,
@@ -26722,10 +26754,8 @@ const revokeIosPushKey = (ctx) => Effect.gen(function* () {
26722
26754
  message: "No APNs push keys in this account.",
26723
26755
  hint: "Run 'Add a new push key' to create one first."
26724
26756
  });
26725
- const localId = yield* promptSelect("Select a push key to revoke", items.map((key) => ({
26726
- value: key.id,
26727
- label: `${key.keyId} (team ${key.appleTeamId})`
26728
- })));
26757
+ const teamLabel = makeAppleTeamLabeler((yield* ctx.api.appleTeams.list()).items);
26758
+ const localId = yield* promptSelect("Select a push key to revoke", items.map((key) => pushKeyChoice(key, teamLabel(key.appleTeamId))));
26729
26759
  const target = items.find((entry) => entry.id === localId);
26730
26760
  if (target === void 0) return yield* new MissingCredentialsError({
26731
26761
  message: `Selected push key ${localId} not found.`,
@@ -26863,10 +26893,8 @@ const bindIosPushKey = (ctx) => Effect.gen(function* () {
26863
26893
  hint: "Run 'Add a new push key' first."
26864
26894
  });
26865
26895
  const config = yield* promptForBundleConfig(ctx);
26866
- const pushKeyId = yield* promptSelect("Select a push key to bind", keys.items.map((key) => ({
26867
- value: key.id,
26868
- label: `${key.keyId} (team ${key.appleTeamId})`
26869
- })));
26896
+ const teamLabel = makeAppleTeamLabeler((yield* ctx.api.appleTeams.list()).items);
26897
+ const pushKeyId = yield* promptSelect("Select a push key to bind", keys.items.map((key) => pushKeyChoice(key, teamLabel(key.appleTeamId))));
26870
26898
  yield* ctx.api.iosBundleConfigurations.update({
26871
26899
  path: { id: config.id },
26872
26900
  payload: { applePushKeyId: pushKeyId }
@@ -26883,10 +26911,8 @@ const setupProjectPushNotifications = (ctx) => Effect.gen(function* () {
26883
26911
  label: "Add a new push key"
26884
26912
  }]);
26885
26913
  const config = yield* promptForBundleConfig(ctx);
26886
- const pushKeyId = choice === "add" ? yield* createNewPushKeyForBundle(ctx, config.appleTeamId) : yield* promptSelect("Select a push key to bind", keys.items.map((key) => ({
26887
- value: key.id,
26888
- label: `${key.keyId} (team ${key.appleTeamId})`
26889
- })));
26914
+ const teamLabel = makeAppleTeamLabeler(keys.items.length === 0 ? [] : (yield* ctx.api.appleTeams.list()).items);
26915
+ const pushKeyId = choice === "add" ? yield* createNewPushKeyForBundle(ctx, config.appleTeamId) : yield* promptSelect("Select a push key to bind", keys.items.map((key) => pushKeyChoice(key, teamLabel(key.appleTeamId))));
26890
26916
  yield* ctx.api.iosBundleConfigurations.update({
26891
26917
  path: { id: config.id },
26892
26918
  payload: { applePushKeyId: pushKeyId }
@@ -28856,10 +28882,8 @@ const resolvePushKeyTarget = (api, idArg) => Effect.gen(function* () {
28856
28882
  const [only] = items;
28857
28883
  if (only !== void 0) return only;
28858
28884
  }
28859
- const chosen = yield* promptSelect("Select a push key to revoke", items.map((entry) => ({
28860
- value: entry.id,
28861
- label: `${entry.keyId} (team ${entry.appleTeamId})`
28862
- })));
28885
+ const teamLabel = makeAppleTeamLabeler((yield* api.appleTeams.list()).items);
28886
+ const chosen = yield* promptSelect("Select a push key to revoke", items.map((key) => pushKeyChoice(key, teamLabel(key.appleTeamId))));
28863
28887
  const match = items.find((entry) => entry.id === chosen);
28864
28888
  if (match === void 0) return yield* new CredentialValidationError({ message: `Selected push key ${chosen} not found after listing.` });
28865
28889
  return match;