@better-update/cli 0.41.2 → 0.42.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.41.2";
38
+ var version = "0.42.0";
39
39
 
40
40
  //#endregion
41
41
  //#region src/lib/interactive-mode.ts
@@ -489,6 +489,8 @@ const RotateVaultBody = Schema.Struct({
489
489
  var AndroidUploadKeystore = class extends Schema.Class("AndroidUploadKeystore")({
490
490
  id: Id,
491
491
  organizationId: Id,
492
+ /** User-supplied label from `credentials upload --name`; null for keystores uploaded before names were stored or generated via keytool. */
493
+ name: Schema.NullOr(Schema.String),
492
494
  keyAlias: Schema.String,
493
495
  md5Fingerprint: Schema.NullOr(Schema.String),
494
496
  sha1Fingerprint: Schema.NullOr(Schema.String),
@@ -505,6 +507,7 @@ var AndroidUploadKeystore = class extends Schema.Class("AndroidUploadKeystore")(
505
507
  const UploadAndroidUploadKeystoreBody = Schema.Struct({
506
508
  id: Id,
507
509
  ...encryptedEnvelopeFields,
510
+ name: Schema.optional(Schema.String.pipe(Schema.maxLength(200))),
508
511
  keyAlias: Schema.String.pipe(Schema.minLength(1), Schema.maxLength(200)),
509
512
  md5Fingerprint: Schema.optional(Schema.String.pipe(Schema.maxLength(200))),
510
513
  sha1Fingerprint: Schema.optional(Schema.String.pipe(Schema.maxLength(200))),
@@ -21978,6 +21981,7 @@ const generateAndUploadKeystore = (api, input) => Effect.scoped(Effect.gen(funct
21978
21981
  });
21979
21982
  const session = yield* openVaultSessionInteractive(api);
21980
21983
  const metadata = compact({
21984
+ name: input.name,
21981
21985
  keyAlias: input.keyAlias,
21982
21986
  md5Fingerprint: fingerprints.md5,
21983
21987
  sha1Fingerprint: fingerprints.sha1,
@@ -22954,15 +22958,17 @@ const makeAppleTeamLabeler = (teams) => {
22954
22958
  return (internalTeamId) => byId.get(internalTeamId) ?? internalTeamId;
22955
22959
  };
22956
22960
  /**
22957
- * Keystore aliases are often cryptic, so surface the type + creation date in the
22958
- * label and the SHA-1 fingerprint (which matches the Play Console upload key) on
22959
- * the active-row hint.
22961
+ * Aliases collide across white-label apps (many keystores share `jmango`), so
22962
+ * lead with the user-supplied name when present and keep the alias alongside it;
22963
+ * surface the type + creation date in the label and the SHA-1 fingerprint (which
22964
+ * matches the Play Console upload key) on the active-row hint.
22960
22965
  */
22961
22966
  const keystoreChoice = (item) => {
22962
22967
  const details = [item.keystoreType, `created ${isoDate(item.createdAt)}`].filter((part) => part !== null);
22968
+ const title = item.name ? `${item.name} (alias ${item.keyAlias})` : item.keyAlias;
22963
22969
  return {
22964
22970
  value: item.id,
22965
- label: `${item.keyAlias} (${details.join(", ")})`,
22971
+ label: `${title} (${details.join(", ")})`,
22966
22972
  hint: item.sha1Fingerprint ? `SHA-1 ${item.sha1Fingerprint}` : `id ${item.id.slice(0, 8)}…`
22967
22973
  };
22968
22974
  };
@@ -26854,6 +26860,13 @@ const uploadIosPushCertificate = (api, input, bytes) => Effect.gen(function* ()
26854
26860
 
26855
26861
  //#endregion
26856
26862
  //#region src/lib/credentials-manager.ts
26863
+ /** Build a list row, defaulting the optional columns most credential types lack. */
26864
+ const makeRow = (fields) => ({
26865
+ name: null,
26866
+ distribution: null,
26867
+ sha1Fingerprint: null,
26868
+ ...fields
26869
+ });
26857
26870
  const formatDistribution = (value) => value.toLowerCase().replaceAll("_", "-");
26858
26871
  const listAllCredentials = (api) => Effect.gen(function* () {
26859
26872
  const [certs, pushKeys, pushCerts, payCerts, passCerts, ascKeys, profiles, keystores, googleKeys] = yield* Effect.all([
@@ -26868,68 +26881,72 @@ const listAllCredentials = (api) => Effect.gen(function* () {
26868
26881
  api.googleServiceAccountKeys.list()
26869
26882
  ], { concurrency: "unbounded" });
26870
26883
  return [
26871
- ...certs.items.map((cert) => ({
26884
+ ...certs.items.map((cert) => makeRow({
26872
26885
  id: cert.id,
26873
- name: cert.serialNumber,
26886
+ identifier: cert.serialNumber,
26874
26887
  platform: "ios",
26875
26888
  type: "distribution-certificate",
26876
- distribution: null
26889
+ createdAt: cert.createdAt
26877
26890
  })),
26878
- ...pushKeys.items.map((key) => ({
26891
+ ...pushKeys.items.map((key) => makeRow({
26879
26892
  id: key.id,
26880
- name: key.keyId,
26893
+ identifier: key.keyId,
26881
26894
  platform: "ios",
26882
26895
  type: "push-key",
26883
- distribution: null
26896
+ createdAt: key.createdAt
26884
26897
  })),
26885
- ...pushCerts.items.map((cert) => ({
26898
+ ...pushCerts.items.map((cert) => makeRow({
26886
26899
  id: cert.id,
26887
- name: cert.bundleIdentifier,
26900
+ identifier: cert.bundleIdentifier,
26888
26901
  platform: "ios",
26889
26902
  type: "push-certificate",
26890
- distribution: null
26903
+ createdAt: cert.createdAt
26891
26904
  })),
26892
- ...payCerts.items.map((cert) => ({
26905
+ ...payCerts.items.map((cert) => makeRow({
26893
26906
  id: cert.id,
26894
- name: cert.merchantIdentifier,
26907
+ identifier: cert.merchantIdentifier,
26895
26908
  platform: "ios",
26896
26909
  type: "apple-pay-certificate",
26897
- distribution: null
26910
+ createdAt: cert.createdAt
26898
26911
  })),
26899
- ...passCerts.items.map((cert) => ({
26912
+ ...passCerts.items.map((cert) => makeRow({
26900
26913
  id: cert.id,
26901
- name: cert.passTypeIdentifier,
26914
+ identifier: cert.passTypeIdentifier,
26902
26915
  platform: "ios",
26903
26916
  type: "pass-type-certificate",
26904
- distribution: null
26917
+ createdAt: cert.createdAt
26905
26918
  })),
26906
- ...ascKeys.items.map((key) => ({
26919
+ ...ascKeys.items.map((key) => makeRow({
26907
26920
  id: key.id,
26908
26921
  name: key.name,
26922
+ identifier: key.keyId,
26909
26923
  platform: "ios",
26910
26924
  type: "asc-api-key",
26911
- distribution: null
26925
+ createdAt: key.createdAt
26912
26926
  })),
26913
- ...profiles.items.map((profile) => ({
26927
+ ...profiles.items.map((profile) => makeRow({
26914
26928
  id: profile.id,
26915
- name: profile.profileName ?? profile.bundleIdentifier,
26929
+ identifier: profile.profileName ?? profile.bundleIdentifier,
26916
26930
  platform: "ios",
26917
26931
  type: "provisioning-profile",
26918
- distribution: formatDistribution(profile.distributionType)
26932
+ distribution: formatDistribution(profile.distributionType),
26933
+ createdAt: profile.createdAt
26919
26934
  })),
26920
- ...keystores.items.map((ks) => ({
26935
+ ...keystores.items.map((ks) => makeRow({
26921
26936
  id: ks.id,
26922
- name: ks.keyAlias,
26937
+ name: ks.name,
26938
+ identifier: ks.keyAlias,
26923
26939
  platform: "android",
26924
26940
  type: "keystore",
26925
- distribution: null
26941
+ sha1Fingerprint: ks.sha1Fingerprint,
26942
+ createdAt: ks.createdAt
26926
26943
  })),
26927
- ...googleKeys.items.map((key) => ({
26944
+ ...googleKeys.items.map((key) => makeRow({
26928
26945
  id: key.id,
26929
- name: key.clientEmail,
26946
+ identifier: key.clientEmail,
26930
26947
  platform: "android",
26931
26948
  type: "google-service-account-key",
26932
- distribution: null
26949
+ createdAt: key.createdAt
26933
26950
  }))
26934
26951
  ];
26935
26952
  });
@@ -27046,6 +27063,7 @@ const uploadAndroidKeystore = (api, input, bytes) => Effect.gen(function* () {
27046
27063
  storePassword: input.password
27047
27064
  });
27048
27065
  const metadata = compact({
27066
+ name: input.name,
27049
27067
  keyAlias: parsed.keyAlias,
27050
27068
  md5Fingerprint: fingerprints.md5,
27051
27069
  sha1Fingerprint: fingerprints.sha1,
@@ -27224,7 +27242,7 @@ const TYPE_LABELS = {
27224
27242
  keystore: "Android keystore",
27225
27243
  "google-service-account-key": "Google service account key"
27226
27244
  };
27227
- const formatRowLabel$1 = (row) => `${row.name} (${row.id.slice(0, 8)}…)`;
27245
+ const formatRowLabel$1 = (row) => `${row.name ?? row.identifier} (${row.id.slice(0, 8)}…)`;
27228
27246
  const pickAndDelete = (ctx, type, humanLabel) => Effect.gen(function* () {
27229
27247
  const matches = filterCredentials(yield* listAllCredentials(ctx.api), { type });
27230
27248
  if (matches.length === 0) return yield* Console.log(`No ${humanLabel} entries found.`);
@@ -27389,6 +27407,7 @@ const setupAndroidProjectCredentials = (ctx) => Effect.gen(function* () {
27389
27407
  });
27390
27408
  const generateAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
27391
27409
  const alias = yield* promptText("Key alias", { placeholder: "upload-key" });
27410
+ const name = yield* promptText("Display name (label shown in lists)", { placeholder: alias });
27392
27411
  const storePassword = yield* promptPassword("Keystore password");
27393
27412
  const keyPassword = yield* promptPassword("Key password");
27394
27413
  const commonName = yield* promptText("Common name (CN)", { placeholder: "Your App" });
@@ -27396,6 +27415,7 @@ const generateAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
27396
27415
  yield* Console.log("Generating keystore with keytool...");
27397
27416
  const created = yield* generateAndUploadKeystore(ctx.api, {
27398
27417
  keyAlias: alias,
27418
+ name: name.trim().length > 0 ? name : alias,
27399
27419
  storePassword,
27400
27420
  keyPassword,
27401
27421
  commonName,
@@ -27407,12 +27427,13 @@ const generateAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
27407
27427
  const uploadAndroidKeystoreInteractive = (ctx) => Effect.gen(function* () {
27408
27428
  const filePath = yield* promptText("Path to the keystore (.jks/.keystore) file");
27409
27429
  const keyAlias = yield* promptText("Key alias");
27430
+ const name = yield* promptText("Display name (label shown in lists)", { placeholder: keyAlias });
27410
27431
  const storePassword = yield* promptPassword("Keystore password");
27411
27432
  const keyPassword = yield* promptPassword("Key password");
27412
27433
  const created = yield* uploadCredential(ctx.api, {
27413
27434
  platform: "android",
27414
27435
  type: "keystore",
27415
- name: keyAlias,
27436
+ name: name.trim().length > 0 ? name : keyAlias,
27416
27437
  filePath,
27417
27438
  keyAlias,
27418
27439
  keyPassword,
@@ -29448,13 +29469,17 @@ const resolveKeystoreInput = (args) => Effect.gen(function* () {
29448
29469
  const commonName = args["common-name"] !== void 0 && args["common-name"].trim().length > 0 ? args["common-name"] : yield* promptText("Common name (CN)", { placeholder: "Your App" });
29449
29470
  const organization = args.organization !== void 0 && args.organization.trim().length > 0 ? args.organization : yield* promptText("Organization (O)", { placeholder: "Your Company" });
29450
29471
  const validityDays = yield* parseValidityDays(args["validity-days"]);
29472
+ const name = args.name !== void 0 && args.name.trim().length > 0 ? args.name : void 0;
29451
29473
  return {
29452
29474
  alias: yield* ensureNonEmpty(alias, "alias"),
29453
29475
  storePassword: yield* ensureNonEmpty(storePassword, "store-password"),
29454
29476
  keyPassword: yield* ensureNonEmpty(keyPassword, "key-password"),
29455
29477
  commonName: yield* ensureNonEmpty(commonName, "common-name"),
29456
29478
  organization: yield* ensureNonEmpty(organization, "organization"),
29457
- ...compact({ validityDays })
29479
+ ...compact({
29480
+ validityDays,
29481
+ name
29482
+ })
29458
29483
  };
29459
29484
  });
29460
29485
  const keystoreCommand = defineCommand({
@@ -29463,6 +29488,10 @@ const keystoreCommand = defineCommand({
29463
29488
  description: "Generate a new Android upload keystore via keytool and store it server-side"
29464
29489
  },
29465
29490
  args: {
29491
+ name: {
29492
+ type: "string",
29493
+ description: "Display name (label shown in `credentials list`)"
29494
+ },
29466
29495
  alias: {
29467
29496
  type: "string",
29468
29497
  description: "Key alias"
@@ -29498,7 +29527,10 @@ const keystoreCommand = defineCommand({
29498
29527
  keyPassword: resolved.keyPassword,
29499
29528
  commonName: resolved.commonName,
29500
29529
  organization: resolved.organization,
29501
- ...compact({ validityDays: resolved.validityDays })
29530
+ ...compact({
29531
+ validityDays: resolved.validityDays,
29532
+ name: resolved.name
29533
+ })
29502
29534
  });
29503
29535
  yield* printHuman("");
29504
29536
  yield* printHuman("Keystore generated and uploaded.");
@@ -29893,15 +29925,19 @@ const listCommand$4 = defineCommand({
29893
29925
  yield* printList([
29894
29926
  "ID",
29895
29927
  "Name",
29928
+ "Identifier",
29896
29929
  "Platform",
29897
29930
  "Type",
29898
- "Distribution"
29931
+ "Created",
29932
+ "SHA-1"
29899
29933
  ], filterCredentials(yield* listAllCredentials(yield* apiClient), args.platform ? { platform: args.platform } : {}).map((row) => [
29900
29934
  row.id,
29901
- row.name,
29935
+ row.name ?? "-",
29936
+ row.identifier,
29902
29937
  row.platform,
29903
29938
  row.type,
29904
- row.distribution ?? "-"
29939
+ isoDate(row.createdAt),
29940
+ row.sha1Fingerprint ?? "-"
29905
29941
  ]), "No credentials found.");
29906
29942
  }))
29907
29943
  });
@@ -30012,8 +30048,9 @@ const CREDENTIAL_TYPES$2 = [
30012
30048
  const isPlatform = (value) => value === "ios" || value === "android";
30013
30049
  const isType = (value) => CREDENTIAL_TYPES$2.includes(value);
30014
30050
  const formatRowLabel = (row) => {
30051
+ const label = row.name ? `${row.name} (${row.identifier})` : row.identifier;
30015
30052
  const distro = row.distribution ? ` (${row.distribution})` : "";
30016
- return `${row.type}: ${row.name}${distro} — ${row.id.slice(0, 8)}…`;
30053
+ return `${row.type}: ${label}${distro} — ${row.id.slice(0, 8)}…`;
30017
30054
  };
30018
30055
  const removeCommand = defineCommand({
30019
30056
  meta: {
@@ -31183,7 +31220,12 @@ const viewKeystore = (api, id) => Effect.gen(function* () {
31183
31220
  pairs: [
31184
31221
  ["ID", item.id],
31185
31222
  ["Type", "Android upload keystore"],
31223
+ ["Name", item.name ?? "-"],
31186
31224
  ["Key alias", item.keyAlias],
31225
+ ["Keystore type", item.keystoreType ?? "-"],
31226
+ ["SHA-1", item.sha1Fingerprint ?? "-"],
31227
+ ["SHA-256", item.sha256Fingerprint ?? "-"],
31228
+ ["MD5", item.md5Fingerprint ?? "-"],
31187
31229
  ["Created", item.createdAt],
31188
31230
  ["Updated", item.updatedAt]
31189
31231
  ],