@better-update/cli 0.41.0 → 0.41.2

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
@@ -31,11 +31,11 @@ import { getFormattedSerialNumber, getX509Certificate, parsePKCS12 } from "@expo
31
31
  import qrcode from "qrcode-terminal";
32
32
 
33
33
  //#region \0rolldown/runtime.js
34
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
34
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
35
35
 
36
36
  //#endregion
37
37
  //#region package.json
38
- var version = "0.41.0";
38
+ var version = "0.41.2";
39
39
 
40
40
  //#endregion
41
41
  //#region src/lib/interactive-mode.ts
@@ -2404,10 +2404,27 @@ var Project = class extends Schema.Class("Project")({
2404
2404
  lastActivityAt: DateTimeString,
2405
2405
  /** ISO-8601 timestamp the project was archived (read-only); `null` when active. */
2406
2406
  archivedAt: Schema.NullOr(DateTimeString),
2407
+ /** Absolute public CDN URL of the project logo; `null` when none is set. */
2408
+ logoUrl: Schema.NullOr(Schema.String),
2407
2409
  branchCount: Schema.Number,
2408
2410
  channelCount: Schema.Number,
2409
2411
  updateCount: Schema.Number
2410
2412
  }) {};
2413
+ /** Image MIME types accepted for a project logo. */
2414
+ const ProjectLogoContentType = Schema.Literal("image/png", "image/jpeg", "image/webp", "image/svg+xml");
2415
+ /**
2416
+ * Request a presigned PUT to upload a project logo. The server builds the R2 key
2417
+ * itself (`logos/{projectId}`) — never trusting a client-sent key — and signs the
2418
+ * content type into the URL, so the direct upload must send the returned headers.
2419
+ */
2420
+ const ProjectLogoUploadBody = Schema.Struct({ contentType: ProjectLogoContentType });
2421
+ const ProjectLogoUploadResult = Schema.Struct({
2422
+ /** R2 object key the presigned URL targets (`logos/{projectId}`). */
2423
+ key: Schema.String,
2424
+ uploadUrl: Schema.String,
2425
+ uploadExpiresAt: DateTimeString,
2426
+ uploadHeaders: UploadHeaders
2427
+ });
2411
2428
  const ProjectSortColumn = Schema.Literal("lastActivityAt", "name", "createdAt", "branchCount", "channelCount", "updateCount");
2412
2429
  const ProjectSort = sortParam(ProjectSortColumn);
2413
2430
  const ListProjectsParams = Schema.Struct({
@@ -2441,6 +2458,15 @@ var ProjectsGroup = class extends HttpApiGroup.make("projects").add(HttpApiEndpo
2441
2458
  }))).add(HttpApiEndpoint.patch("rename")`/api/projects/${idParam}`.setPayload(UpdateProjectBody).addSuccess(Project).annotateContext(OpenApi.annotations({
2442
2459
  title: "Rename project",
2443
2460
  description: "Rename a project"
2461
+ }))).add(HttpApiEndpoint.post("createLogoUploadUrl")`/api/projects/${idParam}/logo/upload-url`.setPayload(ProjectLogoUploadBody).addSuccess(ProjectLogoUploadResult).annotateContext(OpenApi.annotations({
2462
+ title: "Create project logo upload URL",
2463
+ description: "Request a presigned PUT URL to upload a project logo directly to object storage. Send the returned headers with the upload, then call “Set project logo” to finalize."
2464
+ }))).add(HttpApiEndpoint.put("setLogo")`/api/projects/${idParam}/logo`.addSuccess(Project).annotateContext(OpenApi.annotations({
2465
+ title: "Set project logo",
2466
+ description: "Finalize a project logo after its bytes were uploaded via the presigned URL: validates the stored object and records its public CDN URL on the project."
2467
+ }))).add(HttpApiEndpoint.del("removeLogo")`/api/projects/${idParam}/logo`.addSuccess(Project).annotateContext(OpenApi.annotations({
2468
+ title: "Remove project logo",
2469
+ description: "Remove the project logo, clearing it back to the default avatar"
2444
2470
  }))).add(HttpApiEndpoint.del("delete")`/api/projects/${idParam}`.addSuccess(DeleteProjectResult).annotateContext(OpenApi.annotations({
2445
2471
  title: "Delete project",
2446
2472
  description: "Delete a project and all its branches, channels, and updates"
@@ -2450,7 +2476,7 @@ var ProjectsGroup = class extends HttpApiGroup.make("projects").add(HttpApiEndpo
2450
2476
  }))).add(HttpApiEndpoint.post("unarchive")`/api/projects/${idParam}/unarchive`.addSuccess(Project).annotateContext(OpenApi.annotations({
2451
2477
  title: "Unarchive project",
2452
2478
  description: "Restore an archived project to active, writable state"
2453
- }))).addError(NotFound).addError(Conflict).addError(Forbidden).annotateContext(OpenApi.annotations({
2479
+ }))).addError(NotFound).addError(Conflict).addError(BadRequest).addError(Forbidden).annotateContext(OpenApi.annotations({
2454
2480
  title: "Projects",
2455
2481
  description: "Project management endpoints"
2456
2482
  })) {};
@@ -4970,7 +4996,7 @@ const CODE_SIGNING_ALG = "rsa-v1_5-sha256";
4970
4996
  * `sig="<base64>", keyid="<id>", alg="rsa-v1_5-sha256"`. `alg` defaults to
4971
4997
  * {@link CODE_SIGNING_ALG} (the only value SDK56 verifies).
4972
4998
  */
4973
- const buildExpoSignatureHeader = (params) => serializeDictionary(new Map([
4999
+ const buildExpoSignatureHeader = (params) => serializeDictionary(/* @__PURE__ */ new Map([
4974
5000
  ["sig", [params.sig, /* @__PURE__ */ new Map()]],
4975
5001
  ["keyid", [params.keyid, /* @__PURE__ */ new Map()]],
4976
5002
  ["alg", [params.alg ?? "rsa-v1_5-sha256", /* @__PURE__ */ new Map()]]
@@ -6791,7 +6817,7 @@ function wrapMacConstructor(keyLen, macCons, fromMsg) {
6791
6817
  const mac = macCons;
6792
6818
  const getArgs = fromMsg || (() => []);
6793
6819
  const macC = (msg, key) => mac(key, ...getArgs(msg)).update(msg).digest();
6794
- const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0)));
6820
+ const tmp = mac(new Uint8Array(keyLen), ...getArgs(/* @__PURE__ */ new Uint8Array(0)));
6795
6821
  macC.outputLen = tmp.outputLen;
6796
6822
  macC.blockLen = tmp.blockLen;
6797
6823
  macC.create = (key, ...args) => mac(key, ...args);
@@ -6888,7 +6914,7 @@ function u64Lengths(dataLength, aadLength, isLE) {
6888
6914
  anumber$4(dataLength);
6889
6915
  anumber$4(aadLength);
6890
6916
  abool$2(isLE);
6891
- const num = new Uint8Array(16);
6917
+ const num = /* @__PURE__ */ new Uint8Array(16);
6892
6918
  const view = createView$2(num);
6893
6919
  view.setBigUint64(0, BigInt(aadLength), isLE);
6894
6920
  view.setBigUint64(8, BigInt(dataLength), isLE);
@@ -7145,7 +7171,7 @@ function createCipher(core, opts) {
7145
7171
  toClean.push(k = copyBytes$3(key));
7146
7172
  sigma = sigma32_32;
7147
7173
  } else if (l === 16 && allowShortKeys) {
7148
- k = new Uint8Array(32);
7174
+ k = /* @__PURE__ */ new Uint8Array(32);
7149
7175
  k.set(key);
7150
7176
  k.set(key, 16);
7151
7177
  sigma = sigma16_32;
@@ -7171,7 +7197,7 @@ function createCipher(core, opts) {
7171
7197
  const nonceNcLen = 16 - counterLength;
7172
7198
  if (nonceNcLen !== nonce.length) throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
7173
7199
  if (nonceNcLen !== 12) {
7174
- const nc = new Uint8Array(12);
7200
+ const nc = /* @__PURE__ */ new Uint8Array(12);
7175
7201
  nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
7176
7202
  nonce = nc;
7177
7203
  toClean.push(nonce);
@@ -7229,10 +7255,10 @@ function u8to16(a, i) {
7229
7255
  var Poly1305 = class {
7230
7256
  blockLen = 16;
7231
7257
  outputLen = 16;
7232
- buffer = new Uint8Array(16);
7233
- r = new Uint16Array(10);
7234
- h = new Uint16Array(10);
7235
- pad = new Uint16Array(8);
7258
+ buffer = /* @__PURE__ */ new Uint8Array(16);
7259
+ r = /* @__PURE__ */ new Uint16Array(10);
7260
+ h = /* @__PURE__ */ new Uint16Array(10);
7261
+ pad = /* @__PURE__ */ new Uint16Array(8);
7236
7262
  pos = 0;
7237
7263
  finished = false;
7238
7264
  destroyed = false;
@@ -7368,7 +7394,7 @@ var Poly1305 = class {
7368
7394
  }
7369
7395
  finalize() {
7370
7396
  const { h, pad } = this;
7371
- const g = new Uint16Array(10);
7397
+ const g = /* @__PURE__ */ new Uint16Array(10);
7372
7398
  let c = h[1] >>> 13;
7373
7399
  h[1] &= 8191;
7374
7400
  for (let i = 2; i < 10; i++) {
@@ -9683,7 +9709,7 @@ function blamka(Ah, Al, Bh, Bl) {
9683
9709
  l: Rll | 0
9684
9710
  };
9685
9711
  }
9686
- const A2_BUF = new Uint32Array(256);
9712
+ const A2_BUF = /* @__PURE__ */ new Uint32Array(256);
9687
9713
  function G(a, b, c, d) {
9688
9714
  let Al = A2_BUF[2 * a], Ah = A2_BUF[2 * a + 1];
9689
9715
  let Bl = A2_BUF[2 * b], Bh = A2_BUF[2 * b + 1];
@@ -9750,7 +9776,7 @@ function block(x, xPos, yPos, outPos, needXor) {
9750
9776
  }
9751
9777
  function Hp(A, dkLen) {
9752
9778
  const A8 = u8(A);
9753
- const T = new Uint32Array(1);
9779
+ const T = /* @__PURE__ */ new Uint32Array(1);
9754
9780
  const T8 = u8(T);
9755
9781
  T[0] = swap8IfBE(dkLen);
9756
9782
  if (dkLen <= 64) return blake2b.create({ dkLen }).update(T8).update(A8).digest();
@@ -9811,7 +9837,7 @@ function argon2Init(password, salt, type, opts) {
9811
9837
  key = abytesOrZero(key, "key");
9812
9838
  personalization = abytesOrZero(personalization, "personalization");
9813
9839
  const h = blake2b.create();
9814
- const BUF = new Uint32Array(1);
9840
+ const BUF = /* @__PURE__ */ new Uint32Array(1);
9815
9841
  const BUF8 = u8(BUF);
9816
9842
  for (let item of [
9817
9843
  p,
@@ -9833,7 +9859,7 @@ function argon2Init(password, salt, type, opts) {
9833
9859
  BUF[0] = swap8IfBE(i.length);
9834
9860
  h.update(BUF8).update(i);
9835
9861
  }
9836
- const H0 = new Uint32Array(18);
9862
+ const H0 = /* @__PURE__ */ new Uint32Array(18);
9837
9863
  const H0_8 = u8(H0);
9838
9864
  h.digestInto(H0_8);
9839
9865
  const lanes = p;
@@ -9879,7 +9905,7 @@ function argon2Init(password, salt, type, opts) {
9879
9905
  };
9880
9906
  }
9881
9907
  function argon2Output(B, p, laneLen, dkLen) {
9882
- const B_final = new Uint32Array(256);
9908
+ const B_final = /* @__PURE__ */ new Uint32Array(256);
9883
9909
  for (let l = 0; l < p; l++) for (let j = 0; j < 256; j++) B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j];
9884
9910
  const res = Hp(swap32IfBE$1(B_final), dkLen);
9885
9911
  clean$1(B, B_final);
@@ -10689,7 +10715,7 @@ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
10689
10715
  function pbkdf2(hash, password, salt, opts) {
10690
10716
  const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
10691
10717
  let prfW;
10692
- const arr = new Uint8Array(4);
10718
+ const arr = /* @__PURE__ */ new Uint8Array(4);
10693
10719
  const view = createView$1(arr);
10694
10720
  const u = new Uint8Array(PRF.outputLen);
10695
10721
  for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
@@ -13841,7 +13867,7 @@ const rotlH = (h, l, s) => s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s);
13841
13867
  const rotlL = (h, l, s) => s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s);
13842
13868
  /** `keccakf1600` internal function, additionally allows to adjust round count. */
13843
13869
  function keccakP(s, rounds = 24) {
13844
- const B = new Uint32Array(10);
13870
+ const B = /* @__PURE__ */ new Uint32Array(10);
13845
13871
  for (let round = 24 - rounds; round < 24; round++) {
13846
13872
  for (let x = 0; x < 10; x++) B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
13847
13873
  for (let x = 0; x < 10; x += 2) {
@@ -13898,7 +13924,7 @@ var Keccak = class Keccak {
13898
13924
  this.rounds = rounds;
13899
13925
  anumber$1(outputLen, "outputLen");
13900
13926
  if (!(0 < blockLen && blockLen < 200)) throw new Error("only keccak-f1600 function is supported");
13901
- this.state = new Uint8Array(200);
13927
+ this.state = /* @__PURE__ */ new Uint8Array(200);
13902
13928
  this.state32 = u32(this.state);
13903
13929
  }
13904
13930
  clone() {
@@ -14454,7 +14480,7 @@ const genKPKE = (opts) => {
14454
14480
  },
14455
14481
  keygen: (seed) => {
14456
14482
  abytes$1(seed, 32, "seed");
14457
- const seedDst = new Uint8Array(33);
14483
+ const seedDst = /* @__PURE__ */ new Uint8Array(33);
14458
14484
  seedDst.set(seed);
14459
14485
  seedDst[32] = K;
14460
14486
  const seedHash = HASH512(seedDst);
@@ -18298,7 +18324,7 @@ function domBuffer(arr) {
18298
18324
  var LineReader = class {
18299
18325
  s;
18300
18326
  transcript = [];
18301
- buf = new Uint8Array(0);
18327
+ buf = /* @__PURE__ */ new Uint8Array(0);
18302
18328
  constructor(stream) {
18303
18329
  this.s = stream.getReader();
18304
18330
  }
@@ -18569,20 +18595,20 @@ const hpkeMLKEM768P256 = 80;
18569
18595
  const hpkeDHKEMP256 = 16;
18570
18596
  function hpkeContext(kemID, sharedSecret, info) {
18571
18597
  const suiteID = hpkeSuiteID(kemID);
18572
- const pskIDHash = hpkeLabeledExtract(suiteID, void 0, "psk_id_hash", new Uint8Array(0));
18598
+ const pskIDHash = hpkeLabeledExtract(suiteID, void 0, "psk_id_hash", /* @__PURE__ */ new Uint8Array(0));
18573
18599
  const infoHash = hpkeLabeledExtract(suiteID, void 0, "info_hash", info);
18574
18600
  const ksContext = new Uint8Array(1 + pskIDHash.length + infoHash.length);
18575
18601
  ksContext[0] = 0;
18576
18602
  ksContext.set(pskIDHash, 1);
18577
18603
  ksContext.set(infoHash, 1 + pskIDHash.length);
18578
- const secret = hpkeLabeledExtract(suiteID, sharedSecret, "secret", new Uint8Array(0));
18604
+ const secret = hpkeLabeledExtract(suiteID, sharedSecret, "secret", /* @__PURE__ */ new Uint8Array(0));
18579
18605
  return {
18580
18606
  key: hpkeLabeledExpand(suiteID, secret, "key", ksContext, 32),
18581
18607
  nonce: hpkeLabeledExpand(suiteID, secret, "base_nonce", ksContext, 12)
18582
18608
  };
18583
18609
  }
18584
18610
  function hpkeSuiteID(kemID) {
18585
- const suiteID = new Uint8Array(10);
18611
+ const suiteID = /* @__PURE__ */ new Uint8Array(10);
18586
18612
  suiteID.set(new TextEncoder().encode("HPKE"), 0);
18587
18613
  suiteID[4] = kemID >> 8 & 255;
18588
18614
  suiteID[5] = kemID & 255;
@@ -18627,7 +18653,7 @@ function hpkeDHKEMP256Encapsulate(recipient) {
18627
18653
  const kemContext = new Uint8Array(encapsulatedKey.length + recipient.length);
18628
18654
  kemContext.set(encapsulatedKey, 0);
18629
18655
  kemContext.set(recipient, encapsulatedKey.length);
18630
- const suiteID = new Uint8Array(5);
18656
+ const suiteID = /* @__PURE__ */ new Uint8Array(5);
18631
18657
  suiteID.set(new TextEncoder().encode("KEM"), 0);
18632
18658
  suiteID[3] = 0;
18633
18659
  suiteID[4] = 16;
@@ -18748,7 +18774,7 @@ var ScryptRecipient = class {
18748
18774
  wrapFileKey(fileKey) {
18749
18775
  const salt = randomBytes$4(16);
18750
18776
  const label = "age-encryption.org/v1/scrypt";
18751
- const labelAndSalt = new Uint8Array(44);
18777
+ const labelAndSalt = /* @__PURE__ */ new Uint8Array(44);
18752
18778
  labelAndSalt.set(new TextEncoder().encode(label));
18753
18779
  labelAndSalt.set(salt, 28);
18754
18780
  const key = scrypt(this.passphrase, labelAndSalt, {
@@ -18780,7 +18806,7 @@ var ScryptIdentity = class {
18780
18806
  const logN = Number(s.args[2]);
18781
18807
  if (logN > 20) throw Error("scrypt work factor is too high");
18782
18808
  const label = "age-encryption.org/v1/scrypt";
18783
- const labelAndSalt = new Uint8Array(44);
18809
+ const labelAndSalt = /* @__PURE__ */ new Uint8Array(44);
18784
18810
  labelAndSalt.set(new TextEncoder().encode(label));
18785
18811
  labelAndSalt.set(salt, 28);
18786
18812
  const key = scrypt(this.passphrase, labelAndSalt, {
@@ -18796,11 +18822,11 @@ var ScryptIdentity = class {
18796
18822
  }
18797
18823
  };
18798
18824
  function encryptFileKey(fileKey, key) {
18799
- return chacha20poly1305(key, new Uint8Array(12)).encrypt(fileKey);
18825
+ return chacha20poly1305(key, /* @__PURE__ */ new Uint8Array(12)).encrypt(fileKey);
18800
18826
  }
18801
18827
  function decryptFileKey(body, key) {
18802
18828
  if (body.length !== 32) throw Error("invalid stanza");
18803
- const nonce = new Uint8Array(12);
18829
+ const nonce = /* @__PURE__ */ new Uint8Array(12);
18804
18830
  try {
18805
18831
  return chacha20poly1305(key, nonce).decrypt(body);
18806
18832
  } catch {
@@ -18817,7 +18843,7 @@ const chacha20poly1305Overhead = 16;
18817
18843
  const chunkSize = /* @__PURE__ */ (() => 64 * 1024)();
18818
18844
  const chunkSizeWithOverhead = /* @__PURE__ */ (() => chunkSize + chacha20poly1305Overhead)();
18819
18845
  function decryptSTREAM(key) {
18820
- const streamNonce = new Uint8Array(12);
18846
+ const streamNonce = /* @__PURE__ */ new Uint8Array(12);
18821
18847
  const incNonce = () => {
18822
18848
  for (let i = streamNonce.length - 2; i >= 0; i--) {
18823
18849
  streamNonce[i]++;
@@ -18863,7 +18889,7 @@ function plaintextSize(ciphertextSize) {
18863
18889
  return size;
18864
18890
  }
18865
18891
  function encryptSTREAM(key) {
18866
- const streamNonce = new Uint8Array(12);
18892
+ const streamNonce = /* @__PURE__ */ new Uint8Array(12);
18867
18893
  const incNonce = () => {
18868
18894
  for (let i = streamNonce.length - 2; i >= 0; i--) {
18869
18895
  streamNonce[i]++;
@@ -20081,6 +20107,50 @@ const initGitRepo = (stagingRoot) => Effect.tryPromise({
20081
20107
  catch: (cause) => new StagingError({ message: `Failed to init git repo in staging dir: ${formatCause(cause)}` })
20082
20108
  }).pipe(Effect.asVoid);
20083
20109
  /**
20110
+ * Snapshot the staged tree as a single commit so its working tree reads CLEAN.
20111
+ *
20112
+ * EAS stages via `git clone` + checkout, so the tree it hands to
20113
+ * `expo prebuild --clean` is a clean checkout. Our `cp` + `git init` leaves
20114
+ * every staged file UNTRACKED, which `expo prebuild`'s git check reads as
20115
+ * "dirty" (`git status --porcelain` is non-empty). Because the native build
20116
+ * runs inside a PTY, Expo's `isInteractive()` is true even with no real
20117
+ * controlling TTY, so it prompts `Continue with uncommitted changes?` and then
20118
+ * blocks on stdin we never write — hanging CI / backgrounded / piped builds.
20119
+ *
20120
+ * Committing once here makes `git status` clean, so Expo's check passes on
20121
+ * EVERY Expo version — the `EXPO_NO_GIT_STATUS` env gate the build sets only
20122
+ * exists in newer Expo — with no global `CI=1` side effects. The real
20123
+ * dirty-tree decision already ran against the user's *actual* working tree in
20124
+ * `ensureRepoClean` (honoring `--allow-dirty`). Best-effort: hooks are disabled
20125
+ * and a failure is non-fatal — the build proceeds and `EXPO_NO_GIT_STATUS`
20126
+ * still covers newer Expo.
20127
+ */
20128
+ const commitStagingSnapshot = (stagingRoot) => Effect.tryPromise(async () => {
20129
+ const run = async (args) => execFileAsync$1("git", [...args], {
20130
+ cwd: stagingRoot,
20131
+ env: {
20132
+ ...process.env,
20133
+ LEFTHOOK: "0",
20134
+ HUSKY: "0"
20135
+ }
20136
+ });
20137
+ await run(["add", "-A"]);
20138
+ await run([
20139
+ "-c",
20140
+ "user.name=better-update",
20141
+ "-c",
20142
+ "user.email=build@better-update.dev",
20143
+ "-c",
20144
+ "commit.gpgsign=false",
20145
+ "commit",
20146
+ "--no-verify",
20147
+ "--allow-empty",
20148
+ "-q",
20149
+ "-m",
20150
+ "better-update staging snapshot"
20151
+ ]);
20152
+ }).pipe(Effect.ignore);
20153
+ /**
20084
20154
  * Install args per package manager, frozen-lockfile variants matching EAS
20085
20155
  * (`bun install --frozen-lockfile` / `npm ci --include=dev` / etc.) so the
20086
20156
  * staged install resolves exactly what the user's lockfile pins.
@@ -20136,6 +20206,7 @@ const prepareStagingProject = (input) => Effect.gen(function* () {
20136
20206
  env: commandEnv
20137
20207
  });
20138
20208
  } else yield* printHuman("No package.json at the staging root — skipping dependency install.");
20209
+ yield* commitStagingSnapshot(stagingRoot);
20139
20210
  return {
20140
20211
  stagingRoot,
20141
20212
  projectRoot,
@@ -23928,7 +23999,7 @@ const validateEmbeddedProfile = (bundleDir, expectedUuid, expectedTeamId, bundle
23928
23999
  //#endregion
23929
24000
  //#region src/lib/xcode-targets.ts
23930
24001
  /** Product types whose targets require code-signing with a provisioning profile. */
23931
- const SIGNED_PRODUCT_TYPES = new Set([
24002
+ const SIGNED_PRODUCT_TYPES = /* @__PURE__ */ new Set([
23932
24003
  "com.apple.product-type.application",
23933
24004
  "com.apple.product-type.app-extension",
23934
24005
  "com.apple.product-type.messages-extension",