@better-update/cli 0.36.1 → 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.1";
38
+ var version = "0.37.0";
39
39
 
40
40
  //#endregion
41
41
  //#region src/lib/interactive-mode.ts
@@ -2375,12 +2375,13 @@ const DeleteSubmissionResult = DeletedResult;
2375
2375
  //#region ../../packages/api/src/groups/submissions.ts
2376
2376
  const projectIdParam$1 = HttpApiSchema.param("projectId", Schema.String);
2377
2377
  const ListParams = Schema.Struct({
2378
+ ...PaginationParams.fields,
2378
2379
  status: Schema.optional(SubmissionStatus),
2379
2380
  platform: Schema.optional(Platform),
2380
2381
  profile: Schema.optional(Schema.String),
2381
2382
  buildId: Schema.optional(Schema.String)
2382
2383
  });
2383
- var SubmissionsGroup = class extends HttpApiGroup.make("submissions").add(HttpApiEndpoint.get("list")`/api/projects/${projectIdParam$1}/submissions`.setUrlParams(ListParams).addSuccess(Schema.Struct({ items: Schema.Array(Submission) })).annotateContext(OpenApi.annotations({
2384
+ var SubmissionsGroup = class extends HttpApiGroup.make("submissions").add(HttpApiEndpoint.get("list")`/api/projects/${projectIdParam$1}/submissions`.setUrlParams(ListParams).addSuccess(pageResult(Submission)).annotateContext(OpenApi.annotations({
2384
2385
  title: "List submissions",
2385
2386
  description: "List store submissions for a project with optional filters"
2386
2387
  }))).add(HttpApiEndpoint.post("create")`/api/projects/${projectIdParam$1}/submissions`.setPayload(CreateSubmissionBody).addSuccess(Submission, { status: 201 }).annotateContext(OpenApi.annotations({
@@ -22075,6 +22076,51 @@ const runAndroidBuild = (input) => Effect.gen(function* () {
22075
22076
  return input.strategy === "custom" ? yield* runAndroidCustom(input, commandEnv) : yield* runGradleBuild(input, commandEnv);
22076
22077
  });
22077
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
+
22078
22124
  //#endregion
22079
22125
  //#region src/lib/credentials-generator-apple-id.ts
22080
22126
  const DISTRIBUTION_TO_PROFILE_TYPE = {
@@ -22442,10 +22488,7 @@ const chooseDistributionCertViaAppleId = (api, ctx, appleTeamIdentifier) => Effe
22442
22488
  const choice = yield* promptSelect("Select a distribution certificate (or 'generate' for a fresh one)", [{
22443
22489
  value: GENERATE_NEW,
22444
22490
  label: "Generate a new distribution certificate"
22445
- }, ...items.map((cert) => ({
22446
- value: cert.id,
22447
- label: `${cert.serialNumber.slice(0, 12)}… (team ${appleTeamIdentifier})`
22448
- }))]);
22491
+ }, ...items.map((cert) => distributionCertChoice(cert, team?.name ?? appleTeamIdentifier))]);
22449
22492
  if (choice === GENERATE_NEW) {
22450
22493
  const created = yield* generateDistributionCertViaAppleIdInteractive(api, ctx);
22451
22494
  return {
@@ -22556,13 +22599,11 @@ const chooseIosCertificateId = (api) => Effect.gen(function* () {
22556
22599
  });
22557
22600
  return (yield* generateDistributionCertInteractive(api)).id;
22558
22601
  }
22602
+ const teamLabel = makeAppleTeamLabeler((yield* api.appleTeams.list()).items);
22559
22603
  const choice = yield* promptSelect("Select a distribution certificate (or 'generate' for a fresh one)", [{
22560
22604
  value: "__generate__",
22561
22605
  label: "Generate a new distribution certificate"
22562
- }, ...certs.items.map((cert) => ({
22563
- value: cert.id,
22564
- label: `${cert.serialNumber.slice(0, 12)}… (team ${cert.appleTeamId})`
22565
- }))]);
22606
+ }, ...certs.items.map((cert) => distributionCertChoice(cert, teamLabel(cert.appleTeamId)))]);
22566
22607
  if (choice === "__generate__") return (yield* generateDistributionCertInteractive(api)).id;
22567
22608
  return choice;
22568
22609
  });
@@ -22664,10 +22705,7 @@ const pickExistingKeystore = (api) => Effect.gen(function* () {
22664
22705
  message: "No existing keystores in this organization.",
22665
22706
  hint: "Re-run and choose 'Generate new keystore'."
22666
22707
  });
22667
- return yield* promptSelect("Select a keystore", keystores.items.map((item) => ({
22668
- value: item.id,
22669
- label: item.keyAlias
22670
- })));
22708
+ return yield* promptSelect("Select a keystore", keystores.items.map(keystoreChoice));
22671
22709
  });
22672
22710
  const resolveAndroidAppId = (api, input) => Effect.gen(function* () {
22673
22711
  const existing = (yield* api.androidApplicationIdentifiers.list({ path: { projectId: input.projectId } })).items.find((item) => item.packageName === input.applicationIdentifier);
@@ -26364,10 +26402,7 @@ const changeDefaultKeystore = (ctx) => Effect.gen(function* () {
26364
26402
  const downloadAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
26365
26403
  const list = yield* ctx.api.androidUploadKeystores.list();
26366
26404
  if (list.items.length === 0) return yield* Console.log("No keystores to download.");
26367
- const id = yield* promptSelect("Select a keystore to download", list.items.map((item) => ({
26368
- value: item.id,
26369
- label: `${item.keyAlias} (${item.id.slice(0, 8)}…)`
26370
- })));
26405
+ const id = yield* promptSelect("Select a keystore to download", list.items.map(keystoreChoice));
26371
26406
  const data = yield* ctx.api.androidUploadKeystores.download({ path: { id } });
26372
26407
  const secret = yield* openFromDownload({
26373
26408
  session: yield* openVaultSessionInteractive(ctx.api),
@@ -26691,10 +26726,8 @@ const revokeIosDistributionCert = (ctx) => Effect.gen(function* () {
26691
26726
  message: "No ASC API key linked to an Apple team.",
26692
26727
  hint: "Upload an ASC API key first so the CLI can call Apple to revoke."
26693
26728
  });
26694
- const localId = yield* promptSelect("Select a distribution certificate to revoke", certs.items.map((cert) => ({
26695
- value: cert.id,
26696
- label: `${cert.serialNumber.slice(0, 12)}… (team ${cert.appleTeamId})`
26697
- })));
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))));
26698
26731
  const target = certs.items.find((entry) => entry.id === localId);
26699
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) => ({
26700
26733
  value: key.id,
@@ -26721,10 +26754,8 @@ const revokeIosPushKey = (ctx) => Effect.gen(function* () {
26721
26754
  message: "No APNs push keys in this account.",
26722
26755
  hint: "Run 'Add a new push key' to create one first."
26723
26756
  });
26724
- const localId = yield* promptSelect("Select a push key to revoke", items.map((key) => ({
26725
- value: key.id,
26726
- label: `${key.keyId} (team ${key.appleTeamId})`
26727
- })));
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))));
26728
26759
  const target = items.find((entry) => entry.id === localId);
26729
26760
  if (target === void 0) return yield* new MissingCredentialsError({
26730
26761
  message: `Selected push key ${localId} not found.`,
@@ -26862,10 +26893,8 @@ const bindIosPushKey = (ctx) => Effect.gen(function* () {
26862
26893
  hint: "Run 'Add a new push key' first."
26863
26894
  });
26864
26895
  const config = yield* promptForBundleConfig(ctx);
26865
- const pushKeyId = yield* promptSelect("Select a push key to bind", keys.items.map((key) => ({
26866
- value: key.id,
26867
- label: `${key.keyId} (team ${key.appleTeamId})`
26868
- })));
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))));
26869
26898
  yield* ctx.api.iosBundleConfigurations.update({
26870
26899
  path: { id: config.id },
26871
26900
  payload: { applePushKeyId: pushKeyId }
@@ -26882,10 +26911,8 @@ const setupProjectPushNotifications = (ctx) => Effect.gen(function* () {
26882
26911
  label: "Add a new push key"
26883
26912
  }]);
26884
26913
  const config = yield* promptForBundleConfig(ctx);
26885
- const pushKeyId = choice === "add" ? yield* createNewPushKeyForBundle(ctx, config.appleTeamId) : yield* promptSelect("Select a push key to bind", keys.items.map((key) => ({
26886
- value: key.id,
26887
- label: `${key.keyId} (team ${key.appleTeamId})`
26888
- })));
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))));
26889
26916
  yield* ctx.api.iosBundleConfigurations.update({
26890
26917
  path: { id: config.id },
26891
26918
  payload: { applePushKeyId: pushKeyId }
@@ -28855,10 +28882,8 @@ const resolvePushKeyTarget = (api, idArg) => Effect.gen(function* () {
28855
28882
  const [only] = items;
28856
28883
  if (only !== void 0) return only;
28857
28884
  }
28858
- const chosen = yield* promptSelect("Select a push key to revoke", items.map((entry) => ({
28859
- value: entry.id,
28860
- label: `${entry.keyId} (team ${entry.appleTeamId})`
28861
- })));
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))));
28862
28887
  const match = items.find((entry) => entry.id === chosen);
28863
28888
  if (match === void 0) return yield* new CredentialValidationError({ message: `Selected push key ${chosen} not found after listing.` });
28864
28889
  return match;