@better-update/cli 0.3.2 → 0.4.1

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from "module";
2
+ import { createRequire } from "node:module";
3
3
  import process from "node:process";
4
4
  import { Args, Command, Options, Prompt } from "@effect/cli";
5
5
  import { NodeContext, NodeRuntime } from "@effect/platform-node";
@@ -15,7 +15,7 @@ import { ExpoRunFormatter } from "@expo/xcpretty";
15
15
  import { getFormattedSerialNumber, getX509Certificate, parsePKCS12 } from "@expo/pkcs12";
16
16
  import { createServer } from "node:http";
17
17
 
18
- //#region rolldown:runtime
18
+ //#region \0rolldown/runtime.js
19
19
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  //#endregion
@@ -26,6 +26,7 @@ var AuthContext = class extends Context.Tag("api/AuthContext")() {};
26
26
  //#region ../../packages/api/src/auth/errors.ts
27
27
  var Unauthorized = class extends Schema.TaggedError()("Unauthorized", { message: Schema.String }, HttpApiSchema.annotations({ status: 401 })) {};
28
28
  var Forbidden = class extends Schema.TaggedError()("Forbidden", { message: Schema.String }, HttpApiSchema.annotations({ status: 403 })) {};
29
+ var OrgRequired = class extends Schema.TaggedError()("OrgRequired", { message: Schema.String }, HttpApiSchema.annotations({ status: 400 })) {};
29
30
 
30
31
  //#endregion
31
32
  //#region ../../packages/api/src/auth/middleware.ts
@@ -157,6 +158,7 @@ const DeleteAndroidApplicationIdentifierResult = Schema.Struct({ deleted: Schema
157
158
  //#region ../../packages/api/src/domain/errors.ts
158
159
  var BadRequest = class extends Schema.TaggedError()("BadRequest", { message: Schema.String }, HttpApiSchema.annotations({ status: 400 })) {};
159
160
  var Conflict = class extends Schema.TaggedError()("Conflict", { message: Schema.String }, HttpApiSchema.annotations({ status: 409 })) {};
161
+ var NotAcceptable = class extends Schema.TaggedError()("NotAcceptable", { message: Schema.String }, HttpApiSchema.annotations({ status: 406 })) {};
160
162
 
161
163
  //#endregion
162
164
  //#region ../../packages/api/src/groups/android-application-identifiers.ts
@@ -712,6 +714,15 @@ var Build = class extends Schema.Class("Build")({
712
714
  metadataJson: Schema.String,
713
715
  createdAt: DateTimeString
714
716
  }) {};
717
+ var BuildArtifact = class extends Schema.Class("BuildArtifact")({
718
+ buildId: Id,
719
+ r2Key: Schema.String,
720
+ format: ArtifactFormat,
721
+ contentType: Schema.String,
722
+ byteSize: Schema.Number,
723
+ sha256: Schema.String,
724
+ createdAt: DateTimeString
725
+ }) {};
715
726
  var BuildWithArtifact = class extends Build.extend("BuildWithArtifact")({ artifact: Schema.NullOr(Schema.Struct({
716
727
  r2Key: Schema.String,
717
728
  format: ArtifactFormat,
@@ -1331,6 +1342,26 @@ var ManagementApi = class extends HttpApi.make("management-api").add(ProjectsGro
1331
1342
  //#endregion
1332
1343
  //#region ../../packages/api/src/groups/manifest.ts
1333
1344
  const projectIdParam = HttpApiSchema.param("projectId", Schema.String);
1345
+ var ManifestGroup = class extends HttpApiGroup.make("manifest").add(HttpApiEndpoint.get("serve")`/manifest/${projectIdParam}`.addError(BadRequest).addError(NotFound).addError(NotAcceptable).annotateContext(OpenApi.annotations({
1346
+ title: "Serve manifest",
1347
+ description: "Expo Updates protocol v1 manifest endpoint"
1348
+ }))).annotateContext(OpenApi.annotations({
1349
+ title: "Protocol",
1350
+ description: "Expo Updates protocol endpoints"
1351
+ })) {};
1352
+
1353
+ //#endregion
1354
+ //#region ../../packages/api/src/protocol-api.ts
1355
+ /**
1356
+ * Documentation-only contract for OpenAPI/Scalar generation.
1357
+ * The manifest endpoint bypasses HttpApiBuilder at runtime because the Expo Updates
1358
+ * protocol requires multipart/mixed responses that do not fit the standard pipeline.
1359
+ */
1360
+ var ProtocolApi = class extends HttpApi.make("protocol-api").add(ManifestGroup).annotateContext(OpenApi.annotations({
1361
+ title: "Better Update Protocol API",
1362
+ version: "1.0.0",
1363
+ description: "Expo Updates protocol endpoints (unauthenticated)"
1364
+ })) {};
1334
1365
 
1335
1366
  //#endregion
1336
1367
  //#region src/lib/exit-codes.ts
@@ -1361,9 +1392,9 @@ const formatCause = (cause) => {
1361
1392
  if (typeof cause === "object" && cause !== null) {
1362
1393
  const tagged = cause;
1363
1394
  const tag = typeof tagged._tag === "string" ? tagged._tag : void 0;
1364
- const message$3 = typeof tagged.message === "string" ? tagged.message : void 0;
1365
- if (tag && message$3) return `${tag}: ${message$3}`;
1366
- if (message$3) return message$3;
1395
+ const message = typeof tagged.message === "string" ? tagged.message : void 0;
1396
+ if (tag && message) return `${tag}: ${message}`;
1397
+ if (message) return message;
1367
1398
  if (tag) return tag;
1368
1399
  }
1369
1400
  return String(cause);
@@ -1382,7 +1413,7 @@ const CliRuntimeLive = Layer.succeed(CliRuntime, {
1382
1413
  argv: [...process.argv],
1383
1414
  platform: process.platform,
1384
1415
  cwd: Effect.sync(() => process.cwd()),
1385
- getEnv: (name$2) => Effect.sync(() => process.env[name$2]),
1416
+ getEnv: (name) => Effect.sync(() => process.env[name]),
1386
1417
  homeDirectory: Effect.sync(() => process.env["HOME"] ?? process.env["USERPROFILE"] ?? process.cwd()),
1387
1418
  userName: Effect.sync(() => process.env["USER"] ?? process.env["USERNAME"] ?? "better-update"),
1388
1419
  commandEnvironment: (overrides = {}) => Effect.sync(() => ({
@@ -1429,24 +1460,10 @@ const AuthStoreLive = Layer.effect(AuthStore, Effect.gen(function* () {
1429
1460
 
1430
1461
  //#endregion
1431
1462
  //#region src/services/config-store.ts
1432
- const DEFAULT_BASE_URL = "https://api.better-update.dev";
1433
- const DEFAULT_DASHBOARD_URL = "https://better-update.dev";
1463
+ const DEFAULT_BASE_URL = "https://graph.better-update.dev";
1464
+ const DEFAULT_ACCOUNTS_URL = "https://accounts.better-update.dev";
1434
1465
  var ConfigStoreParseError = class extends Data.TaggedError("ConfigStoreParseError") {};
1435
1466
  const normalizeUrl = (value) => value.replace(/\/$/, "");
1436
- const deriveDashboardUrl = (serverUrl) => {
1437
- const normalized = normalizeUrl(serverUrl);
1438
- if (!URL.canParse(normalized)) return DEFAULT_DASHBOARD_URL;
1439
- const url = new URL(normalized);
1440
- if (url.hostname.startsWith("api.")) {
1441
- url.hostname = url.hostname.slice(4);
1442
- return normalizeUrl(url.toString());
1443
- }
1444
- if (url.pathname === "/api") {
1445
- url.pathname = "/";
1446
- return normalizeUrl(url.toString());
1447
- }
1448
- return normalized;
1449
- };
1450
1467
  var ConfigStore = class extends Context.Tag("cli/ConfigStore")() {};
1451
1468
  const ConfigStoreLive = Layer.effect(ConfigStore, Effect.gen(function* () {
1452
1469
  const fs = yield* FileSystem.FileSystem;
@@ -1460,31 +1477,27 @@ const ConfigStoreLive = Layer.effect(ConfigStore, Effect.gen(function* () {
1460
1477
  cause
1461
1478
  })
1462
1479
  }).pipe(Effect.map((parsed) => isRecord(parsed) ? parsed : void 0), Effect.catchAll(() => Effect.succeed(void 0)))));
1463
- const resolveBaseUrl = Effect.gen(function* () {
1464
- const envUrl = yield* runtime.getEnv("BETTER_UPDATE_URL");
1465
- if (envUrl) return normalizeUrl(envUrl);
1466
- const parsed = yield* readConfig;
1467
- const serverUrl = parsed?.["serverUrl"];
1468
- if (typeof serverUrl === "string") return normalizeUrl(serverUrl);
1469
- return DEFAULT_BASE_URL;
1470
- });
1471
1480
  return {
1472
- getBaseUrl: resolveBaseUrl,
1473
- getDashboardUrl: Effect.gen(function* () {
1474
- const envUrl = yield* runtime.getEnv("BETTER_UPDATE_DASHBOARD_URL");
1481
+ getBaseUrl: Effect.gen(function* () {
1482
+ const envUrl = yield* runtime.getEnv("BETTER_UPDATE_URL");
1475
1483
  if (envUrl) return normalizeUrl(envUrl);
1476
- const parsed = yield* readConfig;
1477
- const dashboardUrl = parsed?.["dashboardUrl"];
1478
- if (typeof dashboardUrl === "string") return normalizeUrl(dashboardUrl);
1479
- const serverUrl = yield* resolveBaseUrl;
1480
- return deriveDashboardUrl(serverUrl);
1484
+ const baseUrl = (yield* readConfig)?.["baseUrl"];
1485
+ if (typeof baseUrl === "string") return normalizeUrl(baseUrl);
1486
+ return DEFAULT_BASE_URL;
1487
+ }),
1488
+ getAccountsUrl: Effect.gen(function* () {
1489
+ const envUrl = yield* runtime.getEnv("BETTER_UPDATE_ACCOUNTS_URL");
1490
+ if (envUrl) return normalizeUrl(envUrl);
1491
+ const accountsUrl = (yield* readConfig)?.["accountsUrl"];
1492
+ if (typeof accountsUrl === "string") return normalizeUrl(accountsUrl);
1493
+ return DEFAULT_ACCOUNTS_URL;
1481
1494
  })
1482
1495
  };
1483
1496
  }));
1484
1497
 
1485
1498
  //#endregion
1486
1499
  //#region src/services/api-client.ts
1487
- const client = HttpApiClient.make(ManagementApi);
1500
+ HttpApiClient.make(ManagementApi);
1488
1501
  var ApiClientService = class extends Context.Tag("cli/ApiClient")() {};
1489
1502
  const apiClient = Effect.flatMap(ApiClientService, ({ get }) => get);
1490
1503
  const ApiClientLive = Layer.effect(ApiClientService, Effect.gen(function* () {
@@ -1514,8 +1527,7 @@ const safeJsonParse = (text) => Effect.runSync(Effect.orElseSucceed(Effect.try({
1514
1527
  var AppleSessionStore = class extends Context.Tag("cli/AppleSessionStore")() {};
1515
1528
  const AppleSessionStoreLive = Layer.effect(AppleSessionStore, Effect.gen(function* () {
1516
1529
  const fs = yield* FileSystem.FileSystem;
1517
- const runtime = yield* CliRuntime;
1518
- const homeDirectory = yield* runtime.homeDirectory;
1530
+ const homeDirectory = yield* (yield* CliRuntime).homeDirectory;
1519
1531
  const sessionDir = path.join(homeDirectory, ".better-update");
1520
1532
  const sessionFile = path.join(sessionDir, "apple-session.json");
1521
1533
  return {
@@ -1527,14 +1539,12 @@ const AppleSessionStoreLive = Layer.effect(AppleSessionStore, Effect.gen(functio
1527
1539
  if (typeof parsed["teamId"] !== "string" || typeof parsed["username"] !== "string" || !parsed["cookies"]) return null;
1528
1540
  const providerIdRaw = parsed["providerId"];
1529
1541
  const hasProviderId = typeof providerIdRaw === "number" && Number.isInteger(providerIdRaw);
1530
- const cookies = parsed["cookies"];
1531
- const session = {
1532
- cookies,
1542
+ return {
1543
+ cookies: parsed["cookies"],
1533
1544
  teamId: parsed["teamId"],
1534
1545
  username: parsed["username"],
1535
1546
  ...hasProviderId ? { providerId: providerIdRaw } : {}
1536
1547
  };
1537
- return session;
1538
1548
  }),
1539
1549
  saveSession: (session) => Effect.gen(function* () {
1540
1550
  yield* fs.makeDirectory(sessionDir, { recursive: true });
@@ -1551,7 +1561,7 @@ const AppleSessionStoreLive = Layer.effect(AppleSessionStore, Effect.gen(functio
1551
1561
  const EXPIRY_SAFETY_MARGIN_MS = 3e4;
1552
1562
  var PresignedUploadClient = class extends Context.Tag("cli/PresignedUploadClient")() {};
1553
1563
  const PresignedUploadClientLive = Layer.effect(PresignedUploadClient, Effect.gen(function* () {
1554
- const client$1 = yield* HttpClient.HttpClient;
1564
+ const client = yield* HttpClient.HttpClient;
1555
1565
  const fileSystem = yield* FileSystem.FileSystem;
1556
1566
  return { putToPresignedUrl: ({ url, filePath, byteSize, expiresAt, headers }) => Effect.gen(function* () {
1557
1567
  const now = Date.now();
@@ -1561,12 +1571,11 @@ const PresignedUploadClientLive = Layer.effect(PresignedUploadClient, Effect.gen
1561
1571
  "content-length": String(byteSize),
1562
1572
  ...headers
1563
1573
  })), Effect.mapError((cause) => new UploadFailedError({ message: `Failed to open artifact for upload: ${String(cause)}` })));
1564
- const response = yield* client$1.execute(request).pipe(Effect.mapError((cause) => new UploadFailedError({ message: `HTTP request to presigned URL failed: ${String(cause)}` })));
1574
+ const response = yield* client.execute(request).pipe(Effect.mapError((cause) => new UploadFailedError({ message: `HTTP request to presigned URL failed: ${String(cause)}` })));
1565
1575
  if (response.status < 200 || response.status >= 300) {
1566
1576
  const body = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
1567
1577
  return yield* new UploadFailedError({ message: `Presigned URL upload failed with status ${response.status}: ${body}` });
1568
1578
  }
1569
- return void 0;
1570
1579
  }) };
1571
1580
  }));
1572
1581
 
@@ -1602,8 +1611,7 @@ const CliLive = Layer.mergeAll(CliAdapterDependencies, ApiClientLayer, Presigned
1602
1611
  //#endregion
1603
1612
  //#region src/lib/app-json.ts
1604
1613
  const readAppJson = Effect.gen(function* () {
1605
- const fs = yield* FileSystem.FileSystem;
1606
- const content = yield* fs.readFileString("./app.json").pipe(Effect.mapError(() => new ProjectNotLinkedError({ message: "app.json not found in current directory" })));
1614
+ const content = yield* (yield* FileSystem.FileSystem).readFileString("./app.json").pipe(Effect.mapError(() => new ProjectNotLinkedError({ message: "app.json not found in current directory" })));
1607
1615
  const parsed = yield* Effect.try({
1608
1616
  try: () => JSON.parse(content),
1609
1617
  catch: () => new ProjectNotLinkedError({ message: "app.json contains malformed JSON" })
@@ -1612,28 +1620,22 @@ const readAppJson = Effect.gen(function* () {
1612
1620
  return parsed;
1613
1621
  });
1614
1622
  const readProjectId = Effect.gen(function* () {
1615
- const appJson = yield* readAppJson;
1616
- const expo = asRecord(appJson["expo"]);
1617
- const extra = asRecord(expo?.["extra"]);
1618
- const betterUpdate = asRecord(extra?.["betterUpdate"]);
1619
- const projectId = betterUpdate?.["projectId"];
1623
+ const projectId = asRecord(asRecord(asRecord((yield* readAppJson)["expo"])?.["extra"])?.["betterUpdate"])?.["projectId"];
1620
1624
  if (typeof projectId !== "string") return yield* new ProjectNotLinkedError({ message: "Project not linked. Run `better-update link` to connect this project, or set expo.extra.betterUpdate.projectId in app.json." });
1621
1625
  return projectId;
1622
1626
  });
1623
1627
  const readSlug = Effect.gen(function* () {
1624
- const appJson = yield* readAppJson;
1625
- const expo = asRecord(appJson["expo"]);
1626
- const slug = expo?.["slug"];
1628
+ const slug = asRecord((yield* readAppJson)["expo"])?.["slug"];
1627
1629
  if (typeof slug !== "string") return yield* new ProjectNotLinkedError({ message: "Missing expo.slug in app.json. Required to identify the project." });
1628
1630
  return slug;
1629
1631
  });
1630
- const writeProjectId = (id$9) => Effect.gen(function* () {
1632
+ const writeProjectId = (id) => Effect.gen(function* () {
1631
1633
  const fs = yield* FileSystem.FileSystem;
1632
1634
  const appJson = yield* readAppJson;
1633
1635
  const expo = asRecord(appJson["expo"]) ?? {};
1634
1636
  const extra = asRecord(expo["extra"]) ?? {};
1635
1637
  const betterUpdate = asRecord(extra["betterUpdate"]) ?? {};
1636
- betterUpdate["projectId"] = id$9;
1638
+ betterUpdate["projectId"] = id;
1637
1639
  extra["betterUpdate"] = betterUpdate;
1638
1640
  expo["extra"] = extra;
1639
1641
  appJson["expo"] = expo;
@@ -1657,9 +1659,8 @@ const printKeyValue = (pairs) => Effect.gen(function* () {
1657
1659
 
1658
1660
  //#endregion
1659
1661
  //#region src/application/command-exit.ts
1660
- const exitWith = (code, message$3) => Console.error(message$3).pipe(Effect.zipRight(Effect.gen(function* () {
1661
- const runtime = yield* CliRuntime;
1662
- yield* runtime.setExitCode(code);
1662
+ const exitWith = (code, message) => Console.error(message).pipe(Effect.zipRight(Effect.gen(function* () {
1663
+ yield* (yield* CliRuntime).setExitCode(code);
1663
1664
  })));
1664
1665
 
1665
1666
  //#endregion
@@ -1692,12 +1693,7 @@ const makeCommandErrorHandler = (extras = {}) => {
1692
1693
  handlers[tag] = (error) => exitWith(resolvedCode, systemFormat ? systemFormat(error) : error.message);
1693
1694
  }
1694
1695
  return (effect) => {
1695
- const piped = effect.pipe(
1696
- // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Effect.catchTags tag-inference requires a literal object; we accept a dynamic handler map so tags are chosen at runtime
1697
- Effect.catchTags(handlers),
1698
- Effect.catchAll((cause) => exitWith(1, formatCause(cause)))
1699
- );
1700
- return piped;
1696
+ return effect.pipe(Effect.catchTags(handlers), Effect.catchAll((cause) => exitWith(1, formatCause(cause))));
1701
1697
  };
1702
1698
  };
1703
1699
 
@@ -1802,10 +1798,10 @@ const platformsCommand = Command.make("platforms", { period: period$1 }, (opts)
1802
1798
  "Platform",
1803
1799
  "Requests",
1804
1800
  "Devices"
1805
- ], result.platforms.map((platform$7) => [
1806
- platform$7.platform,
1807
- String(platform$7.requests),
1808
- String(platform$7.devices)
1801
+ ], result.platforms.map((platform) => [
1802
+ platform.platform,
1803
+ String(platform.requests),
1804
+ String(platform.devices)
1809
1805
  ]));
1810
1806
  }).pipe(handleAnalyticsCommandErrors));
1811
1807
 
@@ -1932,8 +1928,7 @@ const idArg$1 = Args.text({ name: "id" });
1932
1928
  const nameOption$1 = Options.text("name");
1933
1929
  const listCommand$6 = Command.make("list", {}, () => Effect.gen(function* () {
1934
1930
  const projectId = yield* readProjectId;
1935
- const api = yield* apiClient;
1936
- const { items } = yield* api.branches.list({ urlParams: {
1931
+ const { items } = yield* (yield* apiClient).branches.list({ urlParams: {
1937
1932
  projectId,
1938
1933
  page: 1,
1939
1934
  limit: 1e3
@@ -1946,39 +1941,36 @@ const listCommand$6 = Command.make("list", {}, () => Effect.gen(function* () {
1946
1941
  "ID",
1947
1942
  "Name",
1948
1943
  "Created"
1949
- ], items.map((branch$6) => [
1950
- branch$6.id,
1951
- branch$6.name,
1952
- branch$6.createdAt
1944
+ ], items.map((branch) => [
1945
+ branch.id,
1946
+ branch.name,
1947
+ branch.createdAt
1953
1948
  ]));
1954
1949
  }).pipe(handleErrors$1));
1955
1950
  const createCommand$3 = Command.make("create", { name: nameOption$1 }, (opts) => Effect.gen(function* () {
1956
1951
  const projectId = yield* readProjectId;
1957
- const api = yield* apiClient;
1958
- const branch$6 = yield* api.branches.create({ payload: {
1952
+ const branch = yield* (yield* apiClient).branches.create({ payload: {
1959
1953
  projectId,
1960
1954
  name: opts.name
1961
1955
  } });
1962
1956
  yield* printKeyValue([
1963
- ["ID", branch$6.id],
1964
- ["Name", branch$6.name],
1965
- ["Created", branch$6.createdAt]
1957
+ ["ID", branch.id],
1958
+ ["Name", branch.name],
1959
+ ["Created", branch.createdAt]
1966
1960
  ]);
1967
1961
  }).pipe(handleErrors$1));
1968
1962
  const renameCommand$1 = Command.make("rename", {
1969
1963
  id: idArg$1,
1970
1964
  name: nameOption$1
1971
1965
  }, (opts) => Effect.gen(function* () {
1972
- const api = yield* apiClient;
1973
- const branch$6 = yield* api.branches.rename({
1966
+ const branch = yield* (yield* apiClient).branches.rename({
1974
1967
  path: { id: opts.id },
1975
1968
  payload: { name: opts.name }
1976
1969
  });
1977
- yield* Console.log(`Branch renamed to "${branch$6.name}".`);
1970
+ yield* Console.log(`Branch renamed to "${branch.name}".`);
1978
1971
  }).pipe(handleErrors$1));
1979
1972
  const deleteCommand$6 = Command.make("delete", { id: idArg$1 }, (opts) => Effect.gen(function* () {
1980
- const api = yield* apiClient;
1981
- yield* api.branches.delete({ path: { id: opts.id } });
1973
+ yield* (yield* apiClient).branches.delete({ path: { id: opts.id } });
1982
1974
  yield* Console.log(`Branch ${opts.id} deleted.`);
1983
1975
  }).pipe(handleErrors$1));
1984
1976
  const branchesCommand = Command.make("branches", {}, () => Console.log("Manage branches. Run with --help for subcommands.")).pipe(Command.withSubcommands([
@@ -2002,7 +1994,7 @@ const escapeGroovySingleQuoted = (value) => value.replaceAll("\\", String.raw`\\
2002
1994
  * `./gradlew --init-script <path>` so the keystore never has to live in the
2003
1995
  * project tree.
2004
1996
  */
2005
- const renderSigningGradle = ({ keystorePath, storePassword, keyAlias: keyAlias$1, keyPassword: keyPassword$1 }) => `allprojects {
1997
+ const renderSigningGradle = ({ keystorePath, storePassword, keyAlias, keyPassword }) => `allprojects {
2006
1998
  afterEvaluate { project ->
2007
1999
  if (project.plugins.hasPlugin('com.android.application')) {
2008
2000
  project.android {
@@ -2010,8 +2002,8 @@ const renderSigningGradle = ({ keystorePath, storePassword, keyAlias: keyAlias$1
2010
2002
  release {
2011
2003
  storeFile file('${escapeGroovySingleQuoted(keystorePath)}')
2012
2004
  storePassword '${escapeGroovySingleQuoted(storePassword)}'
2013
- keyAlias '${escapeGroovySingleQuoted(keyAlias$1)}'
2014
- keyPassword '${escapeGroovySingleQuoted(keyPassword$1)}'
2005
+ keyAlias '${escapeGroovySingleQuoted(keyAlias)}'
2006
+ keyPassword '${escapeGroovySingleQuoted(keyPassword)}'
2015
2007
  }
2016
2008
  }
2017
2009
  buildTypes {
@@ -2058,12 +2050,10 @@ const walkAndFind = (root, extension) => Effect.gen(function* () {
2058
2050
  return results;
2059
2051
  });
2060
2052
  const newest = (files, minMtimeMs) => {
2061
- const eligible = minMtimeMs === void 0 ? files : files.filter((file$1) => file$1.mtimeMs >= minMtimeMs);
2062
- return maxBy(eligible, (file$1) => file$1.mtimeMs);
2053
+ return maxBy(minMtimeMs === void 0 ? files : files.filter((file) => file.mtimeMs >= minMtimeMs), (file) => file.mtimeMs);
2063
2054
  };
2064
2055
  const findIosArtifact = ({ exportPath }) => Effect.gen(function* () {
2065
- const files = yield* walkAndFind(exportPath, ".ipa");
2066
- const picked = newest(files);
2056
+ const picked = newest(yield* walkAndFind(exportPath, ".ipa"));
2067
2057
  if (!picked) return yield* new ArtifactNotFoundError({ message: `No .ipa file found under "${exportPath}".` });
2068
2058
  return picked.path;
2069
2059
  });
@@ -2071,12 +2061,9 @@ const findAndroidArtifact = ({ projectRoot, format, flavor, buildType, minMtimeM
2071
2061
  const outputsRoot = path.join(projectRoot, "android", "app", "build", "outputs");
2072
2062
  const subdir = format === "aab" ? "bundle" : "apk";
2073
2063
  const variantDir = flavor ? `${flavor}${capitalize(buildType)}` : buildType;
2074
- const expectedDir = path.join(outputsRoot, subdir, variantDir);
2075
- const direct = yield* walkAndFind(expectedDir, `.${format}`);
2076
- const pickedDirect = newest(direct, minMtimeMs);
2064
+ const pickedDirect = newest(yield* walkAndFind(path.join(outputsRoot, subdir, variantDir), `.${format}`), minMtimeMs);
2077
2065
  if (pickedDirect) return pickedDirect.path;
2078
- const fallback = yield* walkAndFind(outputsRoot, `.${format}`);
2079
- const pickedFallback = newest(fallback, minMtimeMs);
2066
+ const pickedFallback = newest(yield* walkAndFind(outputsRoot, `.${format}`), minMtimeMs);
2080
2067
  if (!pickedFallback) return yield* new ArtifactNotFoundError({ message: `No .${format} artifact found under "${outputsRoot}"${minMtimeMs === void 0 ? "" : " (newer than build start)"}.` });
2081
2068
  return pickedFallback.path;
2082
2069
  });
@@ -2105,25 +2092,25 @@ const bindHint = "Bind the bundle via the dashboard (Credentials → iOS Bundle
2105
2092
  const permissionHint = "Ask an org admin to grant the build-credentials download permission.";
2106
2093
  const androidBindHint = "Register the package in the dashboard (Credentials → Android Build Credentials) and bind a keystore to the default group.";
2107
2094
  const hasTag = (cause) => typeof cause === "object" && cause !== null && "_tag" in cause;
2108
- const resolveErrorToMissingCredentials = (cause, platform$7) => {
2095
+ const resolveErrorToMissingCredentials = (cause, platform) => {
2109
2096
  const tag = hasTag(cause) ? cause._tag : null;
2110
- const message$3 = hasTag(cause) && typeof cause.message === "string" ? cause.message : null;
2111
- const platformLabel = platform$7 === "ios" ? "iOS" : "Android";
2112
- const bind = platform$7 === "ios" ? bindHint : androidBindHint;
2097
+ const message = hasTag(cause) && typeof cause.message === "string" ? cause.message : null;
2098
+ const platformLabel = platform === "ios" ? "iOS" : "Android";
2099
+ const bind = platform === "ios" ? bindHint : androidBindHint;
2113
2100
  if (tag === "Forbidden") return new MissingCredentialsError({
2114
- message: message$3 ?? `Permission denied when resolving ${platformLabel} build credentials`,
2101
+ message: message ?? `Permission denied when resolving ${platformLabel} build credentials`,
2115
2102
  hint: permissionHint
2116
2103
  });
2117
2104
  if (tag === "NotFound") return new MissingCredentialsError({
2118
- message: message$3 ?? `No ${platformLabel} build credentials configured`,
2105
+ message: message ?? `No ${platformLabel} build credentials configured`,
2119
2106
  hint: bind
2120
2107
  });
2121
2108
  if (tag === "BadRequest") return new MissingCredentialsError({
2122
- message: message$3 ?? `${platformLabel} build credentials are misconfigured`,
2109
+ message: message ?? `${platformLabel} build credentials are misconfigured`,
2123
2110
  hint: bind
2124
2111
  });
2125
2112
  return new MissingCredentialsError({
2126
- message: message$3 ?? `Failed to resolve ${platformLabel} build credentials`,
2113
+ message: message ?? `Failed to resolve ${platformLabel} build credentials`,
2127
2114
  hint: bind
2128
2115
  });
2129
2116
  };
@@ -2179,26 +2166,26 @@ const downloadAndroidCredentials = (api, options) => Effect.gen(function* () {
2179
2166
 
2180
2167
  //#endregion
2181
2168
  //#region src/lib/sha256.ts
2182
- const hashReadError = (message$3) => new BuildFailedError({
2169
+ const hashReadError = (message) => new BuildFailedError({
2183
2170
  step: "sha256",
2184
2171
  exitCode: 1,
2185
- message: message$3
2172
+ message
2186
2173
  });
2187
- const hashFile = (path$1, formatDigest) => Effect.async((resume) => {
2188
- const hash$1 = createHash("sha256");
2189
- const stream = createReadStream(path$1);
2174
+ const hashFile = (path, formatDigest) => Effect.async((resume) => {
2175
+ const hash = createHash("sha256");
2176
+ const stream = createReadStream(path);
2190
2177
  let byteSize = 0;
2191
2178
  stream.on("data", (chunk) => {
2192
2179
  const buffer = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
2193
2180
  byteSize += buffer.byteLength;
2194
- hash$1.update(buffer);
2181
+ hash.update(buffer);
2195
2182
  });
2196
2183
  stream.on("error", (error) => {
2197
2184
  resume(Effect.fail(hashReadError(`Failed to read file for SHA-256: ${error.message}`)));
2198
2185
  });
2199
2186
  stream.on("end", () => {
2200
2187
  resume(Effect.succeed({
2201
- digest: formatDigest(hash$1.digest()),
2188
+ digest: formatDigest(hash.digest()),
2202
2189
  byteSize
2203
2190
  }));
2204
2191
  });
@@ -2208,7 +2195,7 @@ const hashFile = (path$1, formatDigest) => Effect.async((resume) => {
2208
2195
  * hash API. The file is never fully loaded into memory — chunks flow through
2209
2196
  * `createReadStream` into `crypto.createHash("sha256")`.
2210
2197
  */
2211
- const sha256File = (path$1) => hashFile(path$1, (digest) => digest.toString("hex")).pipe(Effect.map(({ digest, byteSize }) => ({
2198
+ const sha256File = (path) => hashFile(path, (digest) => digest.toString("hex")).pipe(Effect.map(({ digest, byteSize }) => ({
2212
2199
  sha256: digest,
2213
2200
  byteSize
2214
2201
  })));
@@ -2275,7 +2262,6 @@ const runStepFormatted = (cmd, step, formatter) => Effect.gen(function* () {
2275
2262
  message: `${step} exited with code ${code}`
2276
2263
  });
2277
2264
  }
2278
- return void 0;
2279
2265
  });
2280
2266
 
2281
2267
  //#endregion
@@ -2374,8 +2360,7 @@ const renderExportOptionsPlist = ({ method, teamId, bundleId, provisioningProfil
2374
2360
  //#region src/lib/ios-keychain.ts
2375
2361
  const runOrFail = (cmd, step) => Command$1.string(cmd).pipe(Effect.mapError((cause) => new KeychainError({ message: `keychain ${step} failed: ${String(cause)}` })));
2376
2362
  const listCurrentKeychains = Effect.gen(function* () {
2377
- const output = yield* runOrFail(Command$1.make("security", "list-keychains", "-d", "user"), "list-keychains");
2378
- return output.split("\n").map((line) => line.trim().replace(/^"/, "").replace(/"$/, "")).filter((line) => line.length > 0);
2363
+ return (yield* runOrFail(Command$1.make("security", "list-keychains", "-d", "user"), "list-keychains")).split("\n").map((line) => line.trim().replace(/^"/, "").replace(/"$/, "")).filter((line) => line.length > 0);
2379
2364
  });
2380
2365
  const parseSigningIdentity = (output) => {
2381
2366
  const lines = output.split("\n");
@@ -2383,7 +2368,6 @@ const parseSigningIdentity = (output) => {
2383
2368
  const match = /"([^"]+)"/.exec(line);
2384
2369
  if (match?.[1]) return match[1];
2385
2370
  }
2386
- return void 0;
2387
2371
  };
2388
2372
  /**
2389
2373
  * Acquire an ephemeral macOS keychain, import a `.p12` into it, add it to the
@@ -2395,34 +2379,28 @@ const acquireKeychain = ({ tempDir, p12Path, p12Password }) => {
2395
2379
  const keychainName = `better-update-${randomUUID()}.keychain-db`;
2396
2380
  const keychainPath = path.join(tempDir, keychainName);
2397
2381
  const keychainPassword = randomBytes(32).toString("hex");
2398
- return Effect.acquireRelease(
2399
- // ── acquire ─────────────────────────────────────────────────
2400
- Effect.gen(function* () {
2401
- const priorKeychains = yield* listCurrentKeychains;
2402
- yield* runOrFail(Command$1.make("security", "create-keychain", "-p", keychainPassword, keychainPath), "create-keychain");
2403
- yield* runOrFail(Command$1.make("security", "unlock-keychain", "-p", keychainPassword, keychainPath), "unlock-keychain");
2404
- yield* runOrFail(Command$1.make("security", "set-keychain-settings", "-t", "3600", "-l", keychainPath), "set-keychain-settings");
2405
- yield* runOrFail(Command$1.make("security", "import", p12Path, "-k", keychainPath, "-P", p12Password, "-T", "/usr/bin/codesign"), "import");
2406
- yield* runOrFail(Command$1.make("security", "set-key-partition-list", "-S", "apple-tool:,apple:,codesign:", "-s", "-k", keychainPassword, keychainPath), "set-key-partition-list");
2407
- yield* runOrFail(Command$1.make("security", "list-keychains", "-d", "user", "-s", keychainPath, ...priorKeychains), "list-keychains -s (add)");
2408
- const identitiesOutput = yield* runOrFail(Command$1.make("security", "find-identity", "-v", "-p", "codesigning", keychainPath), "find-identity");
2409
- const signingIdentity = parseSigningIdentity(identitiesOutput);
2410
- if (!signingIdentity) return yield* new KeychainError({ message: "No code signing identity found after importing .p12 into ephemeral keychain." });
2411
- return {
2412
- handle: {
2413
- keychainName,
2414
- keychainPath,
2415
- signingIdentity
2416
- },
2417
- priorKeychains
2418
- };
2419
- }),
2420
- // ── release ─────────────────────────────────────────────────
2421
- ({ priorKeychains }) => Effect.gen(function* () {
2422
- yield* Command$1.string(Command$1.make("security", "list-keychains", "-d", "user", "-s", ...priorKeychains)).pipe(Effect.catchAll(() => Effect.void));
2423
- yield* Command$1.string(Command$1.make("security", "delete-keychain", keychainPath)).pipe(Effect.catchAll(() => Effect.void));
2424
- })
2425
- ).pipe(Effect.map(({ handle }) => handle));
2382
+ return Effect.acquireRelease(Effect.gen(function* () {
2383
+ const priorKeychains = yield* listCurrentKeychains;
2384
+ yield* runOrFail(Command$1.make("security", "create-keychain", "-p", keychainPassword, keychainPath), "create-keychain");
2385
+ yield* runOrFail(Command$1.make("security", "unlock-keychain", "-p", keychainPassword, keychainPath), "unlock-keychain");
2386
+ yield* runOrFail(Command$1.make("security", "set-keychain-settings", "-t", "3600", "-l", keychainPath), "set-keychain-settings");
2387
+ yield* runOrFail(Command$1.make("security", "import", p12Path, "-k", keychainPath, "-P", p12Password, "-T", "/usr/bin/codesign"), "import");
2388
+ yield* runOrFail(Command$1.make("security", "set-key-partition-list", "-S", "apple-tool:,apple:,codesign:", "-s", "-k", keychainPassword, keychainPath), "set-key-partition-list");
2389
+ yield* runOrFail(Command$1.make("security", "list-keychains", "-d", "user", "-s", keychainPath, ...priorKeychains), "list-keychains -s (add)");
2390
+ const signingIdentity = parseSigningIdentity(yield* runOrFail(Command$1.make("security", "find-identity", "-v", "-p", "codesigning", keychainPath), "find-identity"));
2391
+ if (!signingIdentity) return yield* new KeychainError({ message: "No code signing identity found after importing .p12 into ephemeral keychain." });
2392
+ return {
2393
+ handle: {
2394
+ keychainName,
2395
+ keychainPath,
2396
+ signingIdentity
2397
+ },
2398
+ priorKeychains
2399
+ };
2400
+ }), ({ priorKeychains }) => Effect.gen(function* () {
2401
+ yield* Command$1.string(Command$1.make("security", "list-keychains", "-d", "user", "-s", ...priorKeychains)).pipe(Effect.catchAll(() => Effect.void));
2402
+ yield* Command$1.string(Command$1.make("security", "delete-keychain", keychainPath)).pipe(Effect.catchAll(() => Effect.void));
2403
+ })).pipe(Effect.map(({ handle }) => handle));
2426
2404
  };
2427
2405
 
2428
2406
  //#endregion
@@ -2437,8 +2415,7 @@ const parsePlistXml = (xml) => plist.parse(xml);
2437
2415
  * Uses bplist-parser for Apple's binary plist format.
2438
2416
  */
2439
2417
  const parsePlistBinary = (buffer) => {
2440
- const bplistParser = __require("bplist-parser");
2441
- const [result] = bplistParser.parseBuffer(buffer);
2418
+ const [result] = __require("bplist-parser").parseBuffer(buffer);
2442
2419
  return result;
2443
2420
  };
2444
2421
  const BPLIST_MAGIC = Buffer.from("bplist00");
@@ -2456,7 +2433,6 @@ const getString = (obj, key) => {
2456
2433
  const getFirstArrayString = (obj, key) => {
2457
2434
  const value = obj[key];
2458
2435
  if (Array.isArray(value) && typeof value[0] === "string") return value[0];
2459
- return void 0;
2460
2436
  };
2461
2437
  /**
2462
2438
  * Extract `UUID`, `Name`, and the first `TeamIdentifier` from the XML plist
@@ -2469,12 +2445,12 @@ const extractProvisioningInfo = (plistXml) => Effect.gen(function* () {
2469
2445
  catch: (error) => new ProvisioningError({ message: `Failed to parse provisioning profile plist: ${error instanceof Error ? error.message : String(error)}` })
2470
2446
  });
2471
2447
  const uuid = getString(parsed, "UUID");
2472
- const name$2 = getString(parsed, "Name");
2448
+ const name = getString(parsed, "Name");
2473
2449
  const teamId = getFirstArrayString(parsed, "TeamIdentifier");
2474
- if (!uuid || !name$2 || !teamId) return yield* new ProvisioningError({ message: `Failed to parse provisioning profile: missing ${uuid ? "" : "UUID "}${name$2 ? "" : "Name "}${teamId ? "" : "TeamIdentifier "}`.trim() });
2450
+ if (!uuid || !name || !teamId) return yield* new ProvisioningError({ message: `Failed to parse provisioning profile: missing ${uuid ? "" : "UUID "}${name ? "" : "Name "}${teamId ? "" : "TeamIdentifier "}`.trim() });
2475
2451
  return {
2476
2452
  uuid,
2477
- name: name$2,
2453
+ name,
2478
2454
  teamId
2479
2455
  };
2480
2456
  });
@@ -2488,13 +2464,11 @@ const userProvisioningProfilesDir = () => path.join(os.homedir(), "Library", "Mo
2488
2464
  */
2489
2465
  const installProvisioningProfile = ({ profilePath }) => Effect.acquireRelease(Effect.gen(function* () {
2490
2466
  const fs = yield* FileSystem.FileSystem;
2491
- const plistXml = yield* Command$1.string(Command$1.make("security", "cms", "-D", "-i", profilePath)).pipe(Effect.mapError((cause) => new ProvisioningError({ message: `security cms -D failed for ${profilePath}: ${String(cause)}` })));
2492
- const info = yield* extractProvisioningInfo(plistXml);
2467
+ const info = yield* extractProvisioningInfo(yield* Command$1.string(Command$1.make("security", "cms", "-D", "-i", profilePath)).pipe(Effect.mapError((cause) => new ProvisioningError({ message: `security cms -D failed for ${profilePath}: ${String(cause)}` }))));
2493
2468
  const targetDir = userProvisioningProfilesDir();
2494
2469
  const installedPath = path.join(targetDir, `${info.uuid}.mobileprovision`);
2495
2470
  yield* fs.makeDirectory(targetDir, { recursive: true }).pipe(Effect.catchAll((cause) => new ProvisioningError({ message: `Failed to create provisioning profiles dir: ${String(cause)}` })));
2496
- const alreadyInstalled = yield* fs.exists(installedPath).pipe(Effect.orElseSucceed(() => false));
2497
- if (alreadyInstalled) return {
2471
+ if (yield* fs.exists(installedPath).pipe(Effect.orElseSucceed(() => false))) return {
2498
2472
  ...info,
2499
2473
  installedPath,
2500
2474
  ownsInstallation: false
@@ -2507,11 +2481,10 @@ const installProvisioningProfile = ({ profilePath }) => Effect.acquireRelease(Ef
2507
2481
  };
2508
2482
  }), (acquired) => Effect.gen(function* () {
2509
2483
  if (!acquired.ownsInstallation) return;
2510
- const fs = yield* FileSystem.FileSystem;
2511
- yield* fs.remove(acquired.installedPath).pipe(Effect.catchAll(() => Effect.void));
2512
- })).pipe(Effect.map(({ uuid, name: name$2, teamId, installedPath }) => ({
2484
+ yield* (yield* FileSystem.FileSystem).remove(acquired.installedPath).pipe(Effect.catchAll(() => Effect.void));
2485
+ })).pipe(Effect.map(({ uuid, name, teamId, installedPath }) => ({
2513
2486
  uuid,
2514
- name: name$2,
2487
+ name,
2515
2488
  teamId,
2516
2489
  installedPath
2517
2490
  })));
@@ -2528,13 +2501,10 @@ const installProvisioningProfile = ({ profilePath }) => Effect.acquireRelease(Ef
2528
2501
  */
2529
2502
  const validateIosBuild = (params) => Effect.gen(function* () {
2530
2503
  const appDir = yield* findAppDirectory(params.archivePath).pipe(Effect.catchAll(() => Effect.succeed(void 0)));
2531
- if (!appDir) {
2532
- const warnings$1 = ["Could not locate .app bundle in archive — skipping post-build validation"];
2533
- return {
2534
- passed: false,
2535
- warnings: warnings$1
2536
- };
2537
- }
2504
+ if (!appDir) return {
2505
+ passed: false,
2506
+ warnings: ["Could not locate .app bundle in archive — skipping post-build validation"]
2507
+ };
2538
2508
  const bundleWarning = yield* checkBundleId(appDir, params.expectedBundleId).pipe(Effect.catchAll(() => Effect.succeed(void 0)));
2539
2509
  const profileWarnings = yield* checkEmbeddedProfile(appDir, params.expectedProfileUuid, params.expectedTeamId).pipe(Effect.catchAll(() => Effect.succeed([])));
2540
2510
  const warnings = [...bundleWarning ? [bundleWarning] : [], ...profileWarnings];
@@ -2550,8 +2520,7 @@ const validateIosBuild = (params) => Effect.gen(function* () {
2550
2520
  const findAppDirectory = (archivePath) => Effect.gen(function* () {
2551
2521
  const fs = yield* FileSystem.FileSystem;
2552
2522
  const productsDir = path.join(archivePath, "Products", "Applications");
2553
- const entries = yield* fs.readDirectory(productsDir);
2554
- const appEntry = entries.find((entry) => entry.endsWith(".app"));
2523
+ const appEntry = (yield* fs.readDirectory(productsDir)).find((entry) => entry.endsWith(".app"));
2555
2524
  if (!appEntry) return yield* Effect.fail("No .app found");
2556
2525
  return path.join(productsDir, appEntry);
2557
2526
  });
@@ -2559,16 +2528,13 @@ const checkBundleId = (appDir, expectedBundleId) => Effect.gen(function* () {
2559
2528
  const fs = yield* FileSystem.FileSystem;
2560
2529
  const plistPath = path.join(appDir, "Info.plist");
2561
2530
  const data = yield* fs.readFile(plistPath);
2562
- const parsed = parsePlist(Buffer.from(data));
2563
- const actualBundleId = parsed["CFBundleIdentifier"];
2531
+ const actualBundleId = parsePlist(Buffer.from(data))["CFBundleIdentifier"];
2564
2532
  if (typeof actualBundleId === "string" && actualBundleId !== expectedBundleId) return `Bundle ID mismatch: expected "${expectedBundleId}", got "${actualBundleId}"`;
2565
- return void 0;
2566
2533
  });
2567
2534
  const checkEmbeddedProfile = (appDir, expectedUuid, expectedTeamId) => Effect.gen(function* () {
2568
2535
  const warnings = [];
2569
2536
  const profilePath = path.join(appDir, "embedded.mobileprovision");
2570
- const plistXml = yield* Command$1.string(Command$1.make("security", "cms", "-D", "-i", profilePath));
2571
- const parsed = parsePlistXml(plistXml);
2537
+ const parsed = parsePlistXml(yield* Command$1.string(Command$1.make("security", "cms", "-D", "-i", profilePath)));
2572
2538
  const actualUuid = parsed["UUID"];
2573
2539
  if (typeof actualUuid === "string" && actualUuid !== expectedUuid) warnings.push(`Profile UUID mismatch: expected "${expectedUuid}", got "${actualUuid}"`);
2574
2540
  const teamIdentifiers = parsed["TeamIdentifier"];
@@ -2599,9 +2565,7 @@ const createXcodebuildFormatter = (projectRoot) => {
2599
2565
  //#endregion
2600
2566
  //#region src/commands/build/ios.ts
2601
2567
  const findXcworkspace = (iosDir) => Effect.gen(function* () {
2602
- const fs = yield* FileSystem.FileSystem;
2603
- const entries = yield* fs.readDirectory(iosDir);
2604
- const workspace = entries.find((entry) => entry.endsWith(".xcworkspace"));
2568
+ const workspace = (yield* (yield* FileSystem.FileSystem).readDirectory(iosDir)).find((entry) => entry.endsWith(".xcworkspace"));
2605
2569
  if (!workspace) return yield* new BuildFailedError({
2606
2570
  step: "detect xcworkspace",
2607
2571
  exitCode: 1,
@@ -2735,9 +2699,7 @@ const reserveAndUpload = (api, input) => Effect.gen(function* () {
2735
2699
  //#region src/lib/build-profile.ts
2736
2700
  const asString$1 = (value) => typeof value === "string" ? value : void 0;
2737
2701
  const getBetterUpdateExtra = (appJson) => {
2738
- const expo = asRecord(appJson["expo"]);
2739
- const extra = asRecord(expo?.["extra"]);
2740
- return asRecord(extra?.["betterUpdate"]);
2702
+ return asRecord(asRecord(asRecord(appJson["expo"])?.["extra"])?.["betterUpdate"]);
2741
2703
  };
2742
2704
  const VALID_IOS_DISTRIBUTIONS = [
2743
2705
  "app-store",
@@ -2748,10 +2710,10 @@ const VALID_IOS_DISTRIBUTIONS = [
2748
2710
  const isIosDistribution = (value) => VALID_IOS_DISTRIBUTIONS.includes(value);
2749
2711
  const readIosProfile = (raw) => {
2750
2712
  const iosRaw = asRecord(raw);
2751
- if (!iosRaw) return void 0;
2713
+ if (!iosRaw) return;
2752
2714
  const distributionRaw = asString$1(iosRaw["distribution"]);
2753
- if (!distributionRaw) return void 0;
2754
- if (!isIosDistribution(distributionRaw)) return void 0;
2715
+ if (!distributionRaw) return;
2716
+ if (!isIosDistribution(distributionRaw)) return;
2755
2717
  const distribution = distributionRaw;
2756
2718
  const buildConfiguration = asString$1(iosRaw["buildConfiguration"]);
2757
2719
  const scheme = asString$1(iosRaw["scheme"]);
@@ -2767,33 +2729,31 @@ const resolveAndroidDistribution = (raw, format) => {
2767
2729
  };
2768
2730
  const readAndroidProfile = (raw) => {
2769
2731
  const androidRaw = asRecord(raw);
2770
- if (!androidRaw) return void 0;
2732
+ if (!androidRaw) return;
2771
2733
  const formatValue = asString$1(androidRaw["format"]);
2772
2734
  const format = formatValue === "apk" || formatValue === "aab" ? formatValue : void 0;
2773
- if (!format) return void 0;
2735
+ if (!format) return;
2774
2736
  const buildTypeValue = asString$1(androidRaw["buildType"]);
2775
2737
  const buildType = buildTypeValue === "debug" || buildTypeValue === "release" ? buildTypeValue : void 0;
2776
2738
  const flavor = asString$1(androidRaw["flavor"]);
2777
- const distribution = resolveAndroidDistribution(asString$1(androidRaw["distribution"]), format);
2778
2739
  return {
2779
2740
  format,
2780
- distribution,
2741
+ distribution: resolveAndroidDistribution(asString$1(androidRaw["distribution"]), format),
2781
2742
  ...buildType === void 0 ? {} : { buildType },
2782
2743
  ...flavor === void 0 ? {} : { flavor }
2783
2744
  };
2784
2745
  };
2785
2746
  const readBuildProfile = (appJson, profileName) => Effect.gen(function* () {
2786
- const betterUpdate = getBetterUpdateExtra(appJson);
2787
- const profiles = asRecord(betterUpdate?.["profiles"]);
2747
+ const profiles = asRecord(getBetterUpdateExtra(appJson)?.["profiles"]);
2788
2748
  if (!profiles) return yield* new BuildProfileError({ message: "No build profiles defined. Add expo.extra.betterUpdate.profiles to app.json." });
2789
2749
  const profileRaw = asRecord(profiles[profileName]);
2790
2750
  if (!profileRaw) return yield* new BuildProfileError({ message: `Build profile "${profileName}" not found in app.json.` });
2791
- const environment$1 = asString$1(profileRaw["environment"]) ?? "production";
2751
+ const environment = asString$1(profileRaw["environment"]) ?? "production";
2792
2752
  const ios = readIosProfile(profileRaw["ios"]);
2793
2753
  const android = readAndroidProfile(profileRaw["android"]);
2794
2754
  return {
2795
2755
  name: profileName,
2796
- environment: environment$1,
2756
+ environment,
2797
2757
  ...ios === void 0 ? {} : { ios },
2798
2758
  ...android === void 0 ? {} : { android }
2799
2759
  };
@@ -2806,19 +2766,15 @@ const readRuntimeVersionMeta = (appJson) => Effect.gen(function* () {
2806
2766
  rawRuntimeVersion: readRawRuntimeVersion(expo["runtimeVersion"])
2807
2767
  };
2808
2768
  });
2809
- const readAppMeta = (appJson, platform$7) => Effect.gen(function* () {
2769
+ const readAppMeta = (appJson, platform) => Effect.gen(function* () {
2810
2770
  const expo = asRecord(appJson["expo"]);
2811
2771
  if (!expo) return yield* new BuildProfileError({ message: "Missing expo section in app.json." });
2812
- if (platform$7 === "ios") {
2813
- const ios = asRecord(expo["ios"]);
2814
- if (!ios) return yield* new BuildProfileError({ message: "Missing expo.ios section in app.json. Required for iOS builds (bundleIdentifier)." });
2815
- } else {
2816
- const android = asRecord(expo["android"]);
2817
- if (!android) return yield* new BuildProfileError({ message: "Missing expo.android section in app.json. Required for Android builds (package)." });
2818
- }
2772
+ if (platform === "ios") {
2773
+ if (!asRecord(expo["ios"])) return yield* new BuildProfileError({ message: "Missing expo.ios section in app.json. Required for iOS builds (bundleIdentifier)." });
2774
+ } else if (!asRecord(expo["android"])) return yield* new BuildProfileError({ message: "Missing expo.android section in app.json. Required for Android builds (package)." });
2819
2775
  const iosSection = asRecord(expo["ios"]);
2820
2776
  const androidSection = asRecord(expo["android"]);
2821
- const buildNumber = platform$7 === "ios" ? asString$1(iosSection?.["buildNumber"]) : asStringOrNumber(androidSection?.["versionCode"]);
2777
+ const buildNumber = platform === "ios" ? asString$1(iosSection?.["buildNumber"]) : asStringOrNumber(androidSection?.["versionCode"]);
2822
2778
  return {
2823
2779
  bundleId: asString$1(iosSection?.["bundleIdentifier"]),
2824
2780
  androidPackage: asString$1(androidSection?.["package"]),
@@ -2830,14 +2786,11 @@ const readAppMeta = (appJson, platform$7) => Effect.gen(function* () {
2830
2786
  const asStringOrNumber = (value) => {
2831
2787
  if (typeof value === "string") return value;
2832
2788
  if (typeof value === "number" && Number.isFinite(value)) return String(value);
2833
- return void 0;
2834
2789
  };
2835
2790
  const readRawRuntimeVersion = (value) => {
2836
2791
  if (typeof value === "string") return value;
2837
- const record = asRecord(value);
2838
- const policy = asString$1(record?.["policy"]);
2792
+ const policy = asString$1(asRecord(value)?.["policy"]);
2839
2793
  if (policy) return { policy };
2840
- return void 0;
2841
2794
  };
2842
2795
 
2843
2796
  //#endregion
@@ -2846,10 +2799,10 @@ const readRawRuntimeVersion = (value) => {
2846
2799
  * Pull environment variables for a project + environment and flatten them into
2847
2800
  * a key/value map. Returns an empty map when the project has no variables.
2848
2801
  */
2849
- const pullEnvVars = (api, { projectId, environment: environment$1 }) => api["env-vars"].export({ urlParams: {
2802
+ const pullEnvVars = (api, { projectId, environment }) => api["env-vars"].export({ urlParams: {
2850
2803
  projectId,
2851
- environment: environment$1
2852
- } }).pipe(Effect.map((result) => Object.fromEntries(result.items.map((item) => [item.key, item.value]))), Effect.mapError((cause) => new EnvExportError({ message: `Failed to export environment variables for "${environment$1}": ${String(cause)}` })));
2804
+ environment
2805
+ } }).pipe(Effect.map((result) => Object.fromEntries(result.items.map((item) => [item.key, item.value]))), Effect.mapError((cause) => new EnvExportError({ message: `Failed to export environment variables for "${environment}": ${String(cause)}` })));
2853
2806
 
2854
2807
  //#endregion
2855
2808
  //#region src/lib/expo-config.ts
@@ -2872,8 +2825,7 @@ const readExpoConfig = (projectRoot, envVars = {}) => Effect.acquireUseRelease(E
2872
2825
  return previous;
2873
2826
  }), () => Effect.try({
2874
2827
  try: () => {
2875
- const expoConfigCjs = __require("@expo/config");
2876
- const { getConfig } = expoConfigCjs;
2828
+ const { getConfig } = __require("@expo/config");
2877
2829
  const { exp } = getConfig(projectRoot, { skipSDKVersionRequirement: true });
2878
2830
  return exp;
2879
2831
  },
@@ -2882,29 +2834,28 @@ const readExpoConfig = (projectRoot, envVars = {}) => Effect.acquireUseRelease(E
2882
2834
  for (const [key, value] of Object.entries(previous)) if (value === void 0) delete process.env[key];
2883
2835
  else process.env[key] = value;
2884
2836
  }));
2885
- const extractBuildNumber = (config, platform$7) => {
2886
- if (platform$7 === "ios") return config.ios?.buildNumber;
2887
- if (config.android?.versionCode === void 0) return void 0;
2837
+ const extractBuildNumber = (config, platform) => {
2838
+ if (platform === "ios") return config.ios?.buildNumber;
2839
+ if (config.android?.versionCode === void 0) return;
2888
2840
  return String(config.android.versionCode);
2889
2841
  };
2890
2842
  const extractRawRuntimeVersion = (config) => {
2891
2843
  if (typeof config.runtimeVersion === "string") return config.runtimeVersion;
2892
2844
  if (typeof config.runtimeVersion === "object") return config.runtimeVersion;
2893
- return void 0;
2894
2845
  };
2895
2846
  /**
2896
2847
  * Extract AppMeta from a resolved ExpoConfig (from `@expo/config`).
2897
2848
  * Mirrors `readAppMeta` from build-profile.ts but uses the resolved config
2898
2849
  * which handles dynamic configs (`app.config.js`, `app.config.ts`).
2899
2850
  */
2900
- const readAppMetaFromConfig = (config, platform$7) => Effect.gen(function* () {
2901
- if (platform$7 === "ios" && !config.ios) return yield* new BuildProfileError({ message: "Missing expo.ios section in config. Required for iOS builds (bundleIdentifier)." });
2902
- if (platform$7 === "android" && !config.android) return yield* new BuildProfileError({ message: "Missing expo.android section in config. Required for Android builds (package)." });
2851
+ const readAppMetaFromConfig = (config, platform) => Effect.gen(function* () {
2852
+ if (platform === "ios" && !config.ios) return yield* new BuildProfileError({ message: "Missing expo.ios section in config. Required for iOS builds (bundleIdentifier)." });
2853
+ if (platform === "android" && !config.android) return yield* new BuildProfileError({ message: "Missing expo.android section in config. Required for Android builds (package)." });
2903
2854
  return {
2904
2855
  bundleId: config.ios?.bundleIdentifier,
2905
2856
  androidPackage: config.android?.package,
2906
2857
  appVersion: config.version,
2907
- buildNumber: extractBuildNumber(config, platform$7),
2858
+ buildNumber: extractBuildNumber(config, platform),
2908
2859
  rawRuntimeVersion: extractRawRuntimeVersion(config)
2909
2860
  };
2910
2861
  });
@@ -2950,14 +2901,13 @@ const readGradleConfig = (androidDir) => Effect.gen(function* () {
2950
2901
  const ktsPath = path.join(androidDir, "app", "build.gradle.kts");
2951
2902
  const hasGroovy = yield* fs.exists(gradlePath).pipe(Effect.orElseSucceed(() => false));
2952
2903
  const hasKts = yield* fs.exists(ktsPath).pipe(Effect.orElseSucceed(() => false));
2953
- if (!hasGroovy && hasKts) return void 0;
2954
- if (!hasGroovy) return void 0;
2904
+ if (!hasGroovy && hasKts) return;
2905
+ if (!hasGroovy) return;
2955
2906
  const content = yield* fs.readFileString(gradlePath).pipe(Effect.catchAll(() => Effect.succeed(void 0)));
2956
- if (!content) return void 0;
2907
+ if (!content) return;
2957
2908
  return yield* Effect.tryPromise({
2958
2909
  try: async () => {
2959
- const gradle = __require("gradle-to-js");
2960
- return gradle.parseText(stripGroovyComments(content));
2910
+ return __require("gradle-to-js").parseText(stripGroovyComments(content));
2961
2911
  },
2962
2912
  catch: () => void 0
2963
2913
  }).pipe(Effect.map(extractGradleConfig), Effect.catchAll(() => Effect.succeed(void 0)));
@@ -2978,11 +2928,9 @@ const stripGroovyComments = (text) => text.replaceAll(/\/\/.*$/gmu, "").replaceA
2978
2928
  const parseVersionCode = (raw) => {
2979
2929
  if (typeof raw === "number") return raw;
2980
2930
  if (typeof raw === "string") return Number.parseInt(raw, 10) || void 0;
2981
- return void 0;
2982
2931
  };
2983
2932
  const extractGradleConfig = (parsed) => {
2984
- const android = asRecord(parsed["android"]);
2985
- const defaultConfig = asRecord(android?.["defaultConfig"]);
2933
+ const defaultConfig = asRecord(asRecord(parsed["android"])?.["defaultConfig"]);
2986
2934
  const applicationId = typeof defaultConfig?.["applicationId"] === "string" ? unquote(defaultConfig["applicationId"]) : void 0;
2987
2935
  const versionCode = parseVersionCode(defaultConfig?.["versionCode"]);
2988
2936
  const versionName = typeof defaultConfig?.["versionName"] === "string" ? unquote(defaultConfig["versionName"]) : void 0;
@@ -3005,13 +2953,12 @@ const runFingerprintFull = (projectRoot) => Effect.gen(function* () {
3005
2953
  catch: () => new FingerprintError({ message: "Failed to parse @expo/fingerprint output as JSON." })
3006
2954
  });
3007
2955
  if (!isRecord(parsed)) return yield* new FingerprintError({ message: "@expo/fingerprint output was not a JSON object." });
3008
- const { hash: hash$1 } = parsed;
3009
- if (typeof hash$1 !== "string" || hash$1.length === 0) return yield* new FingerprintError({ message: "@expo/fingerprint output did not contain a \"hash\" string field." });
2956
+ const { hash } = parsed;
2957
+ if (typeof hash !== "string" || hash.length === 0) return yield* new FingerprintError({ message: "@expo/fingerprint output did not contain a \"hash\" string field." });
3010
2958
  const sourcesRaw = parsed["sources"];
3011
- const sources = Array.isArray(sourcesRaw) ? sourcesRaw : [];
3012
2959
  return {
3013
- hash: hash$1,
3014
- sources
2960
+ hash,
2961
+ sources: Array.isArray(sourcesRaw) ? sourcesRaw : []
3015
2962
  };
3016
2963
  });
3017
2964
 
@@ -3047,77 +2994,71 @@ const acquireBuildTempDir = Effect.gen(function* () {
3047
2994
  //#endregion
3048
2995
  //#region src/application/build-workflow.ts
3049
2996
  const runIosPlatformBuild = (input) => Effect.gen(function* () {
3050
- const { api, appMeta, envVars, options, profile: profile$1, projectId, projectRoot, tempDir } = input;
3051
- if (!profile$1.ios) return yield* new BuildProfileError({ message: `Profile "${profile$1.name}" has no ios section.` });
3052
- const iosProfile = profile$1.ios;
2997
+ const { api, appMeta, envVars, options, profile, projectId, projectRoot, tempDir } = input;
2998
+ if (!profile.ios) return yield* new BuildProfileError({ message: `Profile "${profile.name}" has no ios section.` });
2999
+ const iosProfile = profile.ios;
3053
3000
  const iosBundleId = appMeta.bundleId;
3054
3001
  if (!iosBundleId) return yield* new BuildProfileError({ message: "Missing expo.ios.bundleIdentifier in app.json." });
3055
- const build = yield* runIosBuild({
3056
- api,
3057
- tempDir,
3058
- projectRoot,
3059
- iosProfile,
3060
- bundleId: iosBundleId,
3061
- envVars,
3062
- projectId,
3063
- rawOutput: options.rawOutput
3064
- });
3065
- const target = {
3066
- platform: "ios",
3067
- distribution: iosProfile.distribution,
3068
- artifactFormat: "ipa"
3069
- };
3070
3002
  return {
3071
- build,
3072
- target,
3003
+ build: yield* runIosBuild({
3004
+ api,
3005
+ tempDir,
3006
+ projectRoot,
3007
+ iosProfile,
3008
+ bundleId: iosBundleId,
3009
+ envVars,
3010
+ projectId,
3011
+ rawOutput: options.rawOutput
3012
+ }),
3013
+ target: {
3014
+ platform: "ios",
3015
+ distribution: iosProfile.distribution,
3016
+ artifactFormat: "ipa"
3017
+ },
3073
3018
  bundleId: iosBundleId
3074
3019
  };
3075
3020
  });
3076
3021
  const runAndroidPlatformBuild = (input) => Effect.gen(function* () {
3077
- const { api, appMeta, envVars, profile: profile$1, projectId, projectRoot, tempDir } = input;
3078
- if (!profile$1.android) return yield* new BuildProfileError({ message: `Profile "${profile$1.name}" has no android section.` });
3079
- const androidProfile = profile$1.android;
3022
+ const { api, appMeta, envVars, profile, projectId, projectRoot, tempDir } = input;
3023
+ if (!profile.android) return yield* new BuildProfileError({ message: `Profile "${profile.name}" has no android section.` });
3024
+ const androidProfile = profile.android;
3080
3025
  const androidBundleId = appMeta.androidPackage;
3081
3026
  if (!androidBundleId) return yield* new BuildProfileError({ message: "Missing expo.android.package in app.json." });
3082
- const androidDir = `${projectRoot}/android`;
3083
- const gradleConfig = yield* readGradleConfig(androidDir);
3027
+ const gradleConfig = yield* readGradleConfig(`${projectRoot}/android`);
3084
3028
  yield* warnOnGradleMismatch(gradleConfig, androidBundleId);
3085
3029
  const applicationIdentifier = gradleConfig?.applicationId ?? androidBundleId;
3086
- const build = yield* runAndroidBuild({
3087
- api,
3088
- tempDir,
3089
- projectRoot,
3090
- androidProfile,
3091
- applicationIdentifier,
3092
- envVars,
3093
- projectId
3094
- });
3095
- const target = androidProfile.format === "aab" ? {
3096
- platform: "android",
3097
- distribution: "play-store",
3098
- artifactFormat: "aab"
3099
- } : {
3100
- platform: "android",
3101
- distribution: "direct",
3102
- artifactFormat: "apk"
3103
- };
3104
3030
  return {
3105
- build,
3106
- target,
3031
+ build: yield* runAndroidBuild({
3032
+ api,
3033
+ tempDir,
3034
+ projectRoot,
3035
+ androidProfile,
3036
+ applicationIdentifier,
3037
+ envVars,
3038
+ projectId
3039
+ }),
3040
+ target: androidProfile.format === "aab" ? {
3041
+ platform: "android",
3042
+ distribution: "play-store",
3043
+ artifactFormat: "aab"
3044
+ } : {
3045
+ platform: "android",
3046
+ distribution: "direct",
3047
+ artifactFormat: "apk"
3048
+ },
3107
3049
  bundleId: applicationIdentifier
3108
3050
  };
3109
3051
  });
3110
3052
  const runPlatformBuild = (input) => input.options.platform === "ios" ? runIosPlatformBuild(input) : runAndroidPlatformBuild(input);
3111
3053
  const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
3112
3054
  const api = yield* apiClient;
3113
- const runtime = yield* CliRuntime;
3114
- const projectRoot = yield* runtime.cwd;
3055
+ const projectRoot = yield* (yield* CliRuntime).cwd;
3115
3056
  const appJson = yield* readAppJson;
3116
3057
  const projectId = yield* readProjectId;
3117
- const profile$1 = yield* readBuildProfile(appJson, options.profileName);
3058
+ const profile = yield* readBuildProfile(appJson, options.profileName);
3118
3059
  const envVars = yield* pullEnvVars(api, {
3119
3060
  projectId,
3120
- environment: profile$1.environment
3061
+ environment: profile.environment
3121
3062
  });
3122
3063
  const expoConfig = yield* readExpoConfig(projectRoot, envVars);
3123
3064
  const appMeta = expoConfig ? yield* readAppMetaFromConfig(expoConfig, options.platform).pipe(Effect.tap(() => Console.log("Resolved app config via @expo/config")), Effect.catchAll(() => readAppMeta(appJson, options.platform))) : yield* readAppMeta(appJson, options.platform);
@@ -3127,18 +3068,17 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
3127
3068
  projectRoot
3128
3069
  });
3129
3070
  const tempDir = yield* acquireBuildTempDir;
3130
- yield* Console.log(`Building ${options.platform} artifact for profile "${profile$1.name}" (runtimeVersion=${runtimeVersion})`);
3131
- const outcome = yield* runPlatformBuild({
3071
+ yield* Console.log(`Building ${options.platform} artifact for profile "${profile.name}" (runtimeVersion=${runtimeVersion})`);
3072
+ const { build, target, bundleId } = yield* runPlatformBuild({
3132
3073
  api,
3133
3074
  options,
3134
- profile: profile$1,
3075
+ profile,
3135
3076
  appMeta,
3136
3077
  envVars,
3137
3078
  projectId,
3138
3079
  projectRoot,
3139
3080
  tempDir
3140
3081
  });
3141
- const { build, target, bundleId } = outcome;
3142
3082
  yield* Console.log(`Artifact produced: ${build.artifactPath}`);
3143
3083
  if (options.noUpload) {
3144
3084
  yield* printKeyValue([
@@ -3158,7 +3098,7 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
3158
3098
  const result = yield* reserveAndUpload(api, {
3159
3099
  target,
3160
3100
  projectId,
3161
- profileName: profile$1.name,
3101
+ profileName: profile.name,
3162
3102
  runtimeVersion,
3163
3103
  ...appMeta.appVersion === void 0 ? {} : { appVersion: appMeta.appVersion },
3164
3104
  ...appMeta.buildNumber === void 0 ? {} : { buildNumber: appMeta.buildNumber },
@@ -3174,7 +3114,7 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
3174
3114
  ["Build ID", result.id],
3175
3115
  ["Status", result.status],
3176
3116
  ["Platform", options.platform],
3177
- ["Profile", profile$1.name],
3117
+ ["Profile", profile.name],
3178
3118
  ["Runtime version", runtimeVersion],
3179
3119
  ["Artifact", build.artifactPath],
3180
3120
  ["SHA-256", build.sha256],
@@ -3228,8 +3168,7 @@ const handleBuildsCommandErrors = makeCommandErrorHandler();
3228
3168
  //#region src/commands/builds/compatibility-matrix.ts
3229
3169
  const compatibilityMatrixCommand = Command.make("compatibility-matrix", {}, () => Effect.gen(function* () {
3230
3170
  const projectId = yield* readProjectId;
3231
- const api = yield* apiClient;
3232
- const result = yield* api.builds.compatibilityMatrix({ urlParams: { projectId } });
3171
+ const result = yield* (yield* apiClient).builds.compatibilityMatrix({ urlParams: { projectId } });
3233
3172
  if (result.rows.length === 0 && result.missingRuntimeVersions.length === 0) {
3234
3173
  yield* Console.log("No compatibility data found.");
3235
3174
  return;
@@ -3245,7 +3184,7 @@ const compatibilityMatrixCommand = Command.make("compatibility-matrix", {}, () =
3245
3184
  row.id,
3246
3185
  row.platform,
3247
3186
  row.runtimeVersion ?? "-",
3248
- row.channels.map((channel$2) => channel$2.channelName).join(", ") || "-"
3187
+ row.channels.map((channel) => channel.channelName).join(", ") || "-"
3249
3188
  ]));
3250
3189
  }
3251
3190
  if (result.missingRuntimeVersions.length > 0) {
@@ -3255,11 +3194,11 @@ const compatibilityMatrixCommand = Command.make("compatibility-matrix", {}, () =
3255
3194
  "Platform",
3256
3195
  "Runtime Version",
3257
3196
  "Updates"
3258
- ], result.missingRuntimeVersions.map((missing$1) => [
3259
- missing$1.channelName,
3260
- missing$1.platform,
3261
- missing$1.runtimeVersion,
3262
- String(missing$1.updateCount)
3197
+ ], result.missingRuntimeVersions.map((missing) => [
3198
+ missing.channelName,
3199
+ missing.platform,
3200
+ missing.runtimeVersion,
3201
+ String(missing.updateCount)
3263
3202
  ]));
3264
3203
  }
3265
3204
  }).pipe(handleBuildsCommandErrors));
@@ -3268,8 +3207,7 @@ const compatibilityMatrixCommand = Command.make("compatibility-matrix", {}, () =
3268
3207
  //#region src/commands/builds/delete.ts
3269
3208
  const id$8 = Args.text({ name: "id" });
3270
3209
  const deleteCommand$5 = Command.make("delete", { id: id$8 }, (opts) => Effect.gen(function* () {
3271
- const api = yield* apiClient;
3272
- yield* api.builds.delete({ path: { id: opts.id } });
3210
+ yield* (yield* apiClient).builds.delete({ path: { id: opts.id } });
3273
3211
  yield* Console.log(`Build ${opts.id} deleted.`);
3274
3212
  }).pipe(handleBuildsCommandErrors));
3275
3213
 
@@ -3277,8 +3215,7 @@ const deleteCommand$5 = Command.make("delete", { id: id$8 }, (opts) => Effect.ge
3277
3215
  //#region src/commands/builds/get.ts
3278
3216
  const id$7 = Args.text({ name: "id" });
3279
3217
  const getCommand$2 = Command.make("get", { id: id$7 }, (opts) => Effect.gen(function* () {
3280
- const api = yield* apiClient;
3281
- const build = yield* api.builds.get({ path: { id: opts.id } });
3218
+ const build = yield* (yield* apiClient).builds.get({ path: { id: opts.id } });
3282
3219
  yield* printKeyValue([
3283
3220
  ["ID", build.id],
3284
3221
  ["Platform", build.platform],
@@ -3299,8 +3236,7 @@ const getCommand$2 = Command.make("get", { id: id$7 }, (opts) => Effect.gen(func
3299
3236
  //#region src/commands/builds/install-link.ts
3300
3237
  const id$6 = Args.text({ name: "id" });
3301
3238
  const installLinkCommand = Command.make("install-link", { id: id$6 }, (opts) => Effect.gen(function* () {
3302
- const api = yield* apiClient;
3303
- const result = yield* api.builds.getInstallLink({ path: { id: opts.id } });
3239
+ const result = yield* (yield* apiClient).builds.getInstallLink({ path: { id: opts.id } });
3304
3240
  yield* printKeyValue([
3305
3241
  ["Artifact URL", result.artifactUrl],
3306
3242
  ["Install URL", result.installUrl ?? "-"],
@@ -3367,7 +3303,7 @@ const resolveNamedResourceId$2 = (params, makeError) => Effect.gen(function* ()
3367
3303
  //#region src/commands/channels/helpers.ts
3368
3304
  var ChannelCommandError = class extends Data.TaggedError("ChannelCommandError") {};
3369
3305
  const handleChannelCommandErrors = makeCommandErrorHandler({ ChannelCommandError: 2 });
3370
- const resolveNamedResourceId$1 = (params) => resolveNamedResourceId$2(params, (message$3) => new ChannelCommandError({ message: message$3 }));
3306
+ const resolveNamedResourceId$1 = (params) => resolveNamedResourceId$2(params, (message) => new ChannelCommandError({ message }));
3371
3307
 
3372
3308
  //#endregion
3373
3309
  //#region src/commands/channels/create.ts
@@ -3389,16 +3325,16 @@ const createCommand$2 = Command.make("create", {
3389
3325
  kind: "Branch",
3390
3326
  name: opts.branch
3391
3327
  });
3392
- const channel$2 = yield* api.channels.create({ payload: {
3328
+ const channel = yield* api.channels.create({ payload: {
3393
3329
  projectId,
3394
3330
  name: opts.name,
3395
3331
  branchId
3396
3332
  } });
3397
3333
  yield* printKeyValue([
3398
- ["ID", channel$2.id],
3399
- ["Name", channel$2.name],
3334
+ ["ID", channel.id],
3335
+ ["Name", channel.name],
3400
3336
  ["Branch", opts.branch],
3401
- ["Created", channel$2.createdAt]
3337
+ ["Created", channel.createdAt]
3402
3338
  ]);
3403
3339
  }).pipe(handleChannelCommandErrors));
3404
3340
 
@@ -3406,8 +3342,7 @@ const createCommand$2 = Command.make("create", {
3406
3342
  //#region src/commands/channels/delete.ts
3407
3343
  const id$5 = Args.text({ name: "id" });
3408
3344
  const deleteCommand$4 = Command.make("delete", { id: id$5 }, (opts) => Effect.gen(function* () {
3409
- const api = yield* apiClient;
3410
- yield* api.channels.delete({ path: { id: opts.id } });
3345
+ yield* (yield* apiClient).channels.delete({ path: { id: opts.id } });
3411
3346
  yield* Console.log(`Channel ${opts.id} deleted.`);
3412
3347
  }).pipe(handleChannelCommandErrors));
3413
3348
 
@@ -3429,7 +3364,7 @@ const listCommand$4 = Command.make("list", {}, () => Effect.gen(function* () {
3429
3364
  yield* Console.log("No channels found.");
3430
3365
  return;
3431
3366
  }
3432
- const branchNames = new Map(branches.map((branch$6) => [branch$6.id, branch$6.name]));
3367
+ const branchNames = new Map(branches.map((branch) => [branch.id, branch.name]));
3433
3368
  yield* printTable([
3434
3369
  "ID",
3435
3370
  "Name",
@@ -3437,13 +3372,13 @@ const listCommand$4 = Command.make("list", {}, () => Effect.gen(function* () {
3437
3372
  "Paused",
3438
3373
  "Rollout",
3439
3374
  "Created"
3440
- ], items.map((channel$2) => [
3441
- channel$2.id,
3442
- channel$2.name,
3443
- branchNames.get(channel$2.branchId) ?? channel$2.branchId,
3444
- channel$2.isPaused ? "yes" : "no",
3445
- channel$2.branchMappingJson === null ? "-" : "active",
3446
- channel$2.createdAt
3375
+ ], items.map((channel) => [
3376
+ channel.id,
3377
+ channel.name,
3378
+ branchNames.get(channel.branchId) ?? channel.branchId,
3379
+ channel.isPaused ? "yes" : "no",
3380
+ channel.branchMappingJson === null ? "-" : "active",
3381
+ channel.createdAt
3447
3382
  ]));
3448
3383
  }).pipe(handleChannelCommandErrors));
3449
3384
 
@@ -3451,27 +3386,24 @@ const listCommand$4 = Command.make("list", {}, () => Effect.gen(function* () {
3451
3386
  //#region src/commands/channels/pause.ts
3452
3387
  const id$4 = Args.text({ name: "id" });
3453
3388
  const pauseCommand = Command.make("pause", { id: id$4 }, (opts) => Effect.gen(function* () {
3454
- const api = yield* apiClient;
3455
- const channel$2 = yield* api.channels.pause({ path: { id: opts.id } });
3456
- yield* Console.log(`Channel "${channel$2.name}" paused.`);
3389
+ const channel = yield* (yield* apiClient).channels.pause({ path: { id: opts.id } });
3390
+ yield* Console.log(`Channel "${channel.name}" paused.`);
3457
3391
  }).pipe(handleChannelCommandErrors));
3458
3392
 
3459
3393
  //#endregion
3460
3394
  //#region src/commands/channels/resume.ts
3461
3395
  const id$3 = Args.text({ name: "id" });
3462
3396
  const resumeCommand = Command.make("resume", { id: id$3 }, (opts) => Effect.gen(function* () {
3463
- const api = yield* apiClient;
3464
- const channel$2 = yield* api.channels.resume({ path: { id: opts.id } });
3465
- yield* Console.log(`Channel "${channel$2.name}" resumed.`);
3397
+ const channel = yield* (yield* apiClient).channels.resume({ path: { id: opts.id } });
3398
+ yield* Console.log(`Channel "${channel.name}" resumed.`);
3466
3399
  }).pipe(handleChannelCommandErrors));
3467
3400
 
3468
3401
  //#endregion
3469
3402
  //#region src/commands/channels/rollout/complete.ts
3470
3403
  const channelId$3 = Args.text({ name: "channelId" });
3471
3404
  const completeCommand$1 = Command.make("complete", { channelId: channelId$3 }, (opts) => Effect.gen(function* () {
3472
- const api = yield* apiClient;
3473
- const channel$2 = yield* api.channels.completeBranchRollout({ path: { id: opts.channelId } });
3474
- yield* Console.log(`Completed rollout on channel "${channel$2.name}".`);
3405
+ const channel = yield* (yield* apiClient).channels.completeBranchRollout({ path: { id: opts.channelId } });
3406
+ yield* Console.log(`Completed rollout on channel "${channel.name}".`);
3475
3407
  }).pipe(handleChannelCommandErrors));
3476
3408
 
3477
3409
  //#endregion
@@ -3480,7 +3412,7 @@ const RolloutPercentage = Schema.Number.pipe(Schema.int(), Schema.between(1, 100
3480
3412
  message: () => "Rollout percentage must be between 1 and 100.",
3481
3413
  identifier: "RolloutPercentage"
3482
3414
  });
3483
- const rolloutPercentageOption = (name$2) => Options.integer(name$2).pipe(Options.withSchema(RolloutPercentage));
3415
+ const rolloutPercentageOption = (name) => Options.integer(name).pipe(Options.withSchema(RolloutPercentage));
3484
3416
  const KeyValuePair = Schema.Struct({
3485
3417
  key: Schema.String,
3486
3418
  value: Schema.String
@@ -3497,7 +3429,7 @@ const KeyValueFromString = Schema.transformOrFail(Schema.String, KeyValuePair, {
3497
3429
  },
3498
3430
  encode: ({ key, value }) => ParseResult.succeed(`${key}=${value}`)
3499
3431
  });
3500
- const keyValueArg = (name$2) => Args.text({ name: name$2 }).pipe(Args.withSchema(KeyValueFromString));
3432
+ const keyValueArg = (name) => Args.text({ name }).pipe(Args.withSchema(KeyValueFromString));
3501
3433
 
3502
3434
  //#endregion
3503
3435
  //#region src/commands/channels/rollout/create.ts
@@ -3521,23 +3453,22 @@ const createCommand$1 = Command.make("create", {
3521
3453
  kind: "Branch",
3522
3454
  name: opts.branch
3523
3455
  });
3524
- const channel$2 = yield* api.channels.createBranchRollout({
3456
+ const channel = yield* api.channels.createBranchRollout({
3525
3457
  path: { id: opts.channelId },
3526
3458
  payload: {
3527
3459
  newBranchId,
3528
3460
  percentage: opts.percentage
3529
3461
  }
3530
3462
  });
3531
- yield* Console.log(`Started rollout on channel "${channel$2.name}" to branch "${opts.branch}" at ${String(opts.percentage)}%.`);
3463
+ yield* Console.log(`Started rollout on channel "${channel.name}" to branch "${opts.branch}" at ${String(opts.percentage)}%.`);
3532
3464
  }).pipe(handleChannelCommandErrors));
3533
3465
 
3534
3466
  //#endregion
3535
3467
  //#region src/commands/channels/rollout/revert.ts
3536
3468
  const channelId$1 = Args.text({ name: "channelId" });
3537
3469
  const revertCommand$1 = Command.make("revert", { channelId: channelId$1 }, (opts) => Effect.gen(function* () {
3538
- const api = yield* apiClient;
3539
- const channel$2 = yield* api.channels.revertBranchRollout({ path: { id: opts.channelId } });
3540
- yield* Console.log(`Reverted rollout on channel "${channel$2.name}".`);
3470
+ const channel = yield* (yield* apiClient).channels.revertBranchRollout({ path: { id: opts.channelId } });
3471
+ yield* Console.log(`Reverted rollout on channel "${channel.name}".`);
3541
3472
  }).pipe(handleChannelCommandErrors));
3542
3473
 
3543
3474
  //#endregion
@@ -3548,12 +3479,11 @@ const updateCommand$2 = Command.make("update", {
3548
3479
  channelId,
3549
3480
  percentage: percentage$1
3550
3481
  }, (opts) => Effect.gen(function* () {
3551
- const api = yield* apiClient;
3552
- const channel$2 = yield* api.channels.updateBranchRollout({
3482
+ const channel = yield* (yield* apiClient).channels.updateBranchRollout({
3553
3483
  path: { id: opts.channelId },
3554
3484
  payload: { percentage: opts.percentage }
3555
3485
  });
3556
- yield* Console.log(`Updated rollout on channel "${channel$2.name}" to ${String(opts.percentage)}%.`);
3486
+ yield* Console.log(`Updated rollout on channel "${channel.name}" to ${String(opts.percentage)}%.`);
3557
3487
  }).pipe(handleChannelCommandErrors));
3558
3488
 
3559
3489
  //#endregion
@@ -3585,11 +3515,11 @@ const updateCommand$1 = Command.make("update", {
3585
3515
  kind: "Branch",
3586
3516
  name: opts.branch
3587
3517
  });
3588
- const channel$2 = yield* api.channels.update({
3518
+ const channel = yield* api.channels.update({
3589
3519
  path: { id: opts.id },
3590
3520
  payload: { branchId }
3591
3521
  });
3592
- yield* Console.log(`Channel "${channel$2.name}" relinked to branch "${opts.branch}".`);
3522
+ yield* Console.log(`Channel "${channel.name}" relinked to branch "${opts.branch}".`);
3593
3523
  }).pipe(handleChannelCommandErrors));
3594
3524
 
3595
3525
  //#endregion
@@ -3609,32 +3539,23 @@ const channelsCommand = Command.make("channels", {}, () => Console.log("Manage c
3609
3539
  const APPLE_TEAM_ID_RE = /^[A-Z0-9]{10}$/u;
3610
3540
  const extractTeamId = (params) => {
3611
3541
  if (params.orgUnit && APPLE_TEAM_ID_RE.test(params.orgUnit)) return params.orgUnit;
3612
- const parenMatch = /\(([A-Z0-9]{10})\)\s*$/u.exec(params.signingIdentity);
3613
- return parenMatch?.[1];
3542
+ return /\(([A-Z0-9]{10})\)\s*$/u.exec(params.signingIdentity)?.[1];
3614
3543
  };
3615
3544
  /**
3616
3545
  * Parse a PKCS#12 (.p12) buffer and extract certificate metadata.
3617
3546
  */
3618
3547
  const inspectP12 = (params) => Effect.try({
3619
3548
  try: () => {
3620
- const p12 = parsePKCS12(params.data, params.password);
3621
- const cert = getX509Certificate(p12);
3549
+ const cert = getX509Certificate(parsePKCS12(params.data, params.password));
3622
3550
  const serialNumber = getFormattedSerialNumber(cert) ?? "unknown";
3623
3551
  const validFrom = cert.validity.notBefore instanceof Date ? cert.validity.notBefore : void 0;
3624
3552
  const expiresAt = cert.validity.notAfter instanceof Date ? cert.validity.notAfter : void 0;
3625
- const subjectParts = cert.subject.attributes.map((attr) => `${attr.shortName ?? attr.name}=${String(attr.value)}`);
3626
- const subject = subjectParts.join(", ");
3553
+ const subject = cert.subject.attributes.map((attr) => `${attr.shortName ?? attr.name}=${String(attr.value)}`).join(", ");
3627
3554
  const issuerCNValue = cert.issuer.getField("CN")?.value;
3628
3555
  const issuerCN = typeof issuerCNValue === "string" ? issuerCNValue : void 0;
3629
3556
  const cnValue = cert.subject.getField("CN")?.value;
3630
- const cn = typeof cnValue === "string" ? cnValue : void 0;
3631
- const signingIdentity = cn ?? subject;
3557
+ const signingIdentity = (typeof cnValue === "string" ? cnValue : void 0) ?? subject;
3632
3558
  const orgUnitValue = cert.subject.getField("OU")?.value;
3633
- const orgUnit = typeof orgUnitValue === "string" ? orgUnitValue : void 0;
3634
- const teamId = extractTeamId({
3635
- signingIdentity,
3636
- orgUnit
3637
- });
3638
3559
  return {
3639
3560
  serialNumber,
3640
3561
  validFrom,
@@ -3642,7 +3563,10 @@ const inspectP12 = (params) => Effect.try({
3642
3563
  subject,
3643
3564
  issuerCN,
3644
3565
  signingIdentity,
3645
- teamId
3566
+ teamId: extractTeamId({
3567
+ signingIdentity,
3568
+ orgUnit: typeof orgUnitValue === "string" ? orgUnitValue : void 0
3569
+ })
3646
3570
  };
3647
3571
  },
3648
3572
  catch: (error) => new CredentialValidationError({ message: `Failed to parse P12 certificate: ${error instanceof Error ? error.message : String(error)}` })
@@ -3660,7 +3584,7 @@ const listAllCredentials = (api) => Effect.gen(function* () {
3660
3584
  api.androidUploadKeystores.list(),
3661
3585
  api.googleServiceAccountKeys.list()
3662
3586
  ], { concurrency: "unbounded" });
3663
- const rows = [
3587
+ return [
3664
3588
  ...certs.items.map((cert) => ({
3665
3589
  id: cert.id,
3666
3590
  name: cert.serialNumber,
@@ -3682,12 +3606,12 @@ const listAllCredentials = (api) => Effect.gen(function* () {
3682
3606
  type: "asc-api-key",
3683
3607
  distribution: null
3684
3608
  })),
3685
- ...profiles.items.map((profile$1) => ({
3686
- id: profile$1.id,
3687
- name: profile$1.profileName ?? profile$1.bundleIdentifier,
3609
+ ...profiles.items.map((profile) => ({
3610
+ id: profile.id,
3611
+ name: profile.profileName ?? profile.bundleIdentifier,
3688
3612
  platform: "ios",
3689
3613
  type: "provisioning-profile",
3690
- distribution: formatDistribution(profile$1.distributionType)
3614
+ distribution: formatDistribution(profile.distributionType)
3691
3615
  })),
3692
3616
  ...keystores.items.map((ks) => ({
3693
3617
  id: ks.id,
@@ -3704,7 +3628,6 @@ const listAllCredentials = (api) => Effect.gen(function* () {
3704
3628
  distribution: null
3705
3629
  }))
3706
3630
  ];
3707
- return rows;
3708
3631
  });
3709
3632
  const filterCredentials = (rows, filter) => rows.filter((row) => {
3710
3633
  if (filter.platform && row.platform !== filter.platform) return false;
@@ -3722,16 +3645,15 @@ const uploadIosDistributionCertificate = (api, input, bytes) => Effect.gen(funct
3722
3645
  });
3723
3646
  if (!info.teamId) return yield* new CredentialValidationError({ message: "Could not derive Apple Team ID from certificate subject (expected OU=TEAMID or CN with (TEAMID))." });
3724
3647
  if (!info.validFrom || !info.expiresAt) return yield* new CredentialValidationError({ message: "Certificate is missing notBefore/notAfter dates." });
3725
- const created = yield* api.appleDistributionCertificates.upload({ payload: {
3726
- p12Base64: toBase64(bytes),
3727
- p12Password: input.password,
3728
- serialNumber: info.serialNumber,
3729
- appleTeamIdentifier: info.teamId,
3730
- validFrom: info.validFrom.toISOString(),
3731
- validUntil: info.expiresAt.toISOString()
3732
- } });
3733
3648
  return {
3734
- id: created.id,
3649
+ id: (yield* api.appleDistributionCertificates.upload({ payload: {
3650
+ p12Base64: toBase64(bytes),
3651
+ p12Password: input.password,
3652
+ serialNumber: info.serialNumber,
3653
+ appleTeamIdentifier: info.teamId,
3654
+ validFrom: info.validFrom.toISOString(),
3655
+ validUntil: info.expiresAt.toISOString()
3656
+ } })).id,
3735
3657
  name: input.name,
3736
3658
  platform: "ios",
3737
3659
  type: "distribution-certificate"
@@ -3740,13 +3662,12 @@ const uploadIosDistributionCertificate = (api, input, bytes) => Effect.gen(funct
3740
3662
  const uploadIosPushKey = (api, input, bytes) => Effect.gen(function* () {
3741
3663
  if (!input.keyId) return yield* missing("key-id");
3742
3664
  if (!input.appleTeamIdentifier) return yield* missing("apple-team-identifier");
3743
- const created = yield* api.applePushKeys.upload({ payload: {
3744
- keyId: input.keyId,
3745
- p8Pem: toUtf8(bytes),
3746
- appleTeamIdentifier: input.appleTeamIdentifier
3747
- } });
3748
3665
  return {
3749
- id: created.id,
3666
+ id: (yield* api.applePushKeys.upload({ payload: {
3667
+ keyId: input.keyId,
3668
+ p8Pem: toUtf8(bytes),
3669
+ appleTeamIdentifier: input.appleTeamIdentifier
3670
+ } })).id,
3750
3671
  name: input.name,
3751
3672
  platform: "ios",
3752
3673
  type: "push-key"
@@ -3755,24 +3676,22 @@ const uploadIosPushKey = (api, input, bytes) => Effect.gen(function* () {
3755
3676
  const uploadIosAscApiKey = (api, input, bytes) => Effect.gen(function* () {
3756
3677
  if (!input.keyId) return yield* missing("key-id");
3757
3678
  if (!input.issuerId) return yield* missing("issuer-id");
3758
- const created = yield* api.ascApiKeys.upload({ payload: {
3759
- name: input.name,
3760
- keyId: input.keyId,
3761
- issuerId: input.issuerId,
3762
- p8Pem: toUtf8(bytes),
3763
- ...input.appleTeamIdentifier === void 0 ? {} : { appleTeamIdentifier: input.appleTeamIdentifier }
3764
- } });
3765
3679
  return {
3766
- id: created.id,
3680
+ id: (yield* api.ascApiKeys.upload({ payload: {
3681
+ name: input.name,
3682
+ keyId: input.keyId,
3683
+ issuerId: input.issuerId,
3684
+ p8Pem: toUtf8(bytes),
3685
+ ...input.appleTeamIdentifier === void 0 ? {} : { appleTeamIdentifier: input.appleTeamIdentifier }
3686
+ } })).id,
3767
3687
  name: input.name,
3768
3688
  platform: "ios",
3769
3689
  type: "asc-api-key"
3770
3690
  };
3771
3691
  });
3772
3692
  const uploadIosProvisioningProfile = (api, input, bytes) => Effect.gen(function* () {
3773
- const created = yield* api.appleProvisioningProfiles.upload({ payload: { profileBase64: toBase64(bytes) } });
3774
3693
  return {
3775
- id: created.id,
3694
+ id: (yield* api.appleProvisioningProfiles.upload({ payload: { profileBase64: toBase64(bytes) } })).id,
3776
3695
  name: input.name,
3777
3696
  platform: "ios",
3778
3697
  type: "provisioning-profile"
@@ -3782,23 +3701,21 @@ const uploadAndroidKeystore = (api, input, bytes) => Effect.gen(function* () {
3782
3701
  if (input.password === void 0) return yield* missing("password");
3783
3702
  if (!input.keyAlias) return yield* missing("key-alias");
3784
3703
  if (!input.keyPassword) return yield* missing("key-password");
3785
- const created = yield* api.androidUploadKeystores.upload({ payload: {
3786
- keystoreBase64: toBase64(bytes),
3787
- keyAlias: input.keyAlias,
3788
- keystorePassword: input.password,
3789
- keyPassword: input.keyPassword
3790
- } });
3791
3704
  return {
3792
- id: created.id,
3705
+ id: (yield* api.androidUploadKeystores.upload({ payload: {
3706
+ keystoreBase64: toBase64(bytes),
3707
+ keyAlias: input.keyAlias,
3708
+ keystorePassword: input.password,
3709
+ keyPassword: input.keyPassword
3710
+ } })).id,
3793
3711
  name: input.name,
3794
3712
  platform: "android",
3795
3713
  type: "keystore"
3796
3714
  };
3797
3715
  });
3798
3716
  const uploadAndroidGoogleServiceAccountKey = (api, input, bytes) => Effect.gen(function* () {
3799
- const created = yield* api.googleServiceAccountKeys.upload({ payload: { json: toUtf8(bytes) } });
3800
3717
  return {
3801
- id: created.id,
3718
+ id: (yield* api.googleServiceAccountKeys.upload({ payload: { json: toUtf8(bytes) } })).id,
3802
3719
  name: input.name,
3803
3720
  platform: "android",
3804
3721
  type: "google-service-account-key"
@@ -3813,8 +3730,7 @@ const uploadHandlers = {
3813
3730
  "android:google-service-account-key": uploadAndroidGoogleServiceAccountKey
3814
3731
  };
3815
3732
  const uploadCredential = (api, input) => Effect.gen(function* () {
3816
- const fs = yield* FileSystem.FileSystem;
3817
- const bytes = yield* fs.readFile(input.filePath);
3733
+ const bytes = yield* (yield* FileSystem.FileSystem).readFile(input.filePath);
3818
3734
  const key = `${input.platform}:${input.type}`;
3819
3735
  const hasKey = (candidate) => Object.hasOwn(uploadHandlers, candidate);
3820
3736
  const handler = hasKey(key) ? uploadHandlers[key] : void 0;
@@ -3822,29 +3738,29 @@ const uploadCredential = (api, input) => Effect.gen(function* () {
3822
3738
  return yield* handler(api, input, bytes);
3823
3739
  });
3824
3740
  const deleteCredential = (api, input) => {
3825
- const path$1 = { id: input.id };
3741
+ const path = { id: input.id };
3826
3742
  return Match.value({
3827
3743
  platform: input.platform,
3828
3744
  type: input.type
3829
3745
  }).pipe(Match.when({
3830
3746
  platform: "ios",
3831
3747
  type: "distribution-certificate"
3832
- }, () => api.appleDistributionCertificates.delete({ path: path$1 })), Match.when({
3748
+ }, () => api.appleDistributionCertificates.delete({ path })), Match.when({
3833
3749
  platform: "ios",
3834
3750
  type: "push-key"
3835
- }, () => api.applePushKeys.delete({ path: path$1 })), Match.when({
3751
+ }, () => api.applePushKeys.delete({ path })), Match.when({
3836
3752
  platform: "ios",
3837
3753
  type: "asc-api-key"
3838
- }, () => api.ascApiKeys.delete({ path: path$1 })), Match.when({
3754
+ }, () => api.ascApiKeys.delete({ path })), Match.when({
3839
3755
  platform: "ios",
3840
3756
  type: "provisioning-profile"
3841
- }, () => api.appleProvisioningProfiles.delete({ path: path$1 })), Match.when({
3757
+ }, () => api.appleProvisioningProfiles.delete({ path })), Match.when({
3842
3758
  platform: "android",
3843
3759
  type: "keystore"
3844
- }, () => api.androidUploadKeystores.delete({ path: path$1 })), Match.when({
3760
+ }, () => api.androidUploadKeystores.delete({ path })), Match.when({
3845
3761
  platform: "android",
3846
3762
  type: "google-service-account-key"
3847
- }, () => api.googleServiceAccountKeys.delete({ path: path$1 })), Match.orElse(() => Effect.fail(new CredentialValidationError({ message: `Unsupported credential combination: platform=${input.platform} type=${input.type}` }))));
3763
+ }, () => api.googleServiceAccountKeys.delete({ path })), Match.orElse(() => Effect.fail(new CredentialValidationError({ message: `Unsupported credential combination: platform=${input.platform} type=${input.type}` }))));
3848
3764
  };
3849
3765
 
3850
3766
  //#endregion
@@ -3864,8 +3780,7 @@ const deleteCommand$3 = Command.make("delete", {
3864
3780
  platform: platform$4,
3865
3781
  type: type$1
3866
3782
  }, (opts) => Effect.gen(function* () {
3867
- const api = yield* apiClient;
3868
- yield* deleteCredential(api, {
3783
+ yield* deleteCredential(yield* apiClient, {
3869
3784
  id: opts.id,
3870
3785
  platform: opts.platform,
3871
3786
  type: opts.type
@@ -3877,9 +3792,7 @@ const deleteCommand$3 = Command.make("delete", {
3877
3792
  //#region src/commands/credentials/list.ts
3878
3793
  const platform$3 = Options.choice("platform", ["ios", "android"]).pipe(Options.optional);
3879
3794
  const listCommand$3 = Command.make("list", { platform: platform$3 }, (opts) => Effect.gen(function* () {
3880
- const api = yield* apiClient;
3881
- const rows = yield* listAllCredentials(api);
3882
- const filtered = filterCredentials(rows, Option.match(opts.platform, {
3795
+ const filtered = filterCredentials(yield* listAllCredentials(yield* apiClient), Option.match(opts.platform, {
3883
3796
  onNone: () => ({}),
3884
3797
  onSome: (platformValue) => ({ platform: platformValue })
3885
3798
  }));
@@ -3940,7 +3853,7 @@ const uploadCommand = Command.make("upload", {
3940
3853
  const keyIdOpt = Option.getOrUndefined(opts.keyId);
3941
3854
  const issuerIdOpt = Option.getOrUndefined(opts.issuerId);
3942
3855
  const appleTeamIdentifierOpt = Option.getOrUndefined(opts.appleTeamIdentifier);
3943
- const input = {
3856
+ const credential = yield* uploadCredential(api, {
3944
3857
  platform: opts.platform,
3945
3858
  type: opts.type,
3946
3859
  name: opts.name,
@@ -3951,8 +3864,7 @@ const uploadCommand = Command.make("upload", {
3951
3864
  ...keyIdOpt === void 0 ? {} : { keyId: keyIdOpt },
3952
3865
  ...issuerIdOpt === void 0 ? {} : { issuerId: issuerIdOpt },
3953
3866
  ...appleTeamIdentifierOpt === void 0 ? {} : { appleTeamIdentifier: appleTeamIdentifierOpt }
3954
- };
3955
- const credential = yield* uploadCredential(api, input);
3867
+ });
3956
3868
  yield* Console.log("Credential uploaded successfully.");
3957
3869
  yield* Console.log("");
3958
3870
  yield* printKeyValue([
@@ -3987,29 +3899,26 @@ const environmentOption$5 = Options.text("environment").pipe(Options.withDefault
3987
3899
  const deleteCommand$2 = Command.make("delete", {
3988
3900
  key: keyArg,
3989
3901
  environment: environmentOption$5
3990
- }, ({ key, environment: environment$1 }) => Effect.gen(function* () {
3902
+ }, ({ key, environment }) => Effect.gen(function* () {
3991
3903
  const projectId = yield* readProjectId;
3992
3904
  const api = yield* apiClient;
3993
- const existing = yield* api["env-vars"].list({ urlParams: {
3905
+ const match = (yield* api["env-vars"].list({ urlParams: {
3994
3906
  projectId,
3995
- environment: environment$1
3996
- } });
3997
- const match = existing.items.find((item) => item.key === key);
3998
- if (!match) return yield* new EnvResourceNotFoundError({ message: `Environment variable ${key} not found in ${environment$1}` });
3907
+ environment
3908
+ } })).items.find((item) => item.key === key);
3909
+ if (!match) return yield* new EnvResourceNotFoundError({ message: `Environment variable ${key} not found in ${environment}` });
3999
3910
  yield* api["env-vars"].delete({ path: { id: match.id } });
4000
- yield* Console.log(`Deleted ${key} from ${environment$1}`);
4001
- return void 0;
3911
+ yield* Console.log(`Deleted ${key} from ${environment}`);
4002
3912
  }).pipe(handleEnvCommandErrors));
4003
3913
 
4004
3914
  //#endregion
4005
3915
  //#region src/commands/env/export.ts
4006
3916
  const environmentOption$4 = Options.text("environment").pipe(Options.withDefault("production"));
4007
- const exportCommand = Command.make("export", { environment: environmentOption$4 }, ({ environment: environment$1 }) => Effect.gen(function* () {
3917
+ const exportCommand = Command.make("export", { environment: environmentOption$4 }, ({ environment }) => Effect.gen(function* () {
4008
3918
  const projectId = yield* readProjectId;
4009
- const api = yield* apiClient;
4010
- const result = yield* api["env-vars"].export({ urlParams: {
3919
+ const result = yield* (yield* apiClient)["env-vars"].export({ urlParams: {
4011
3920
  projectId,
4012
- environment: environment$1
3921
+ environment
4013
3922
  } });
4014
3923
  for (const item of result.items) {
4015
3924
  const escaped = item.value.replaceAll("'", String.raw`'\''`);
@@ -4021,8 +3930,7 @@ const exportCommand = Command.make("export", { environment: environmentOption$4
4021
3930
  //#region src/commands/env/get.ts
4022
3931
  const id = Args.text({ name: "id" });
4023
3932
  const getCommand$1 = Command.make("get", { id }, (opts) => Effect.gen(function* () {
4024
- const api = yield* apiClient;
4025
- const envVar = yield* api["env-vars"].get({ path: { id: opts.id } });
3933
+ const envVar = yield* (yield* apiClient)["env-vars"].get({ path: { id: opts.id } });
4026
3934
  yield* printKeyValue([
4027
3935
  ["ID", envVar.id],
4028
3936
  ["Key", envVar.key],
@@ -4041,14 +3949,12 @@ const environmentOption$3 = Options.text("environment").pipe(Options.withDefault
4041
3949
  const importCommand = Command.make("import", {
4042
3950
  file: fileArg,
4043
3951
  environment: environmentOption$3
4044
- }, ({ file: file$1, environment: environment$1 }) => Effect.gen(function* () {
4045
- const fs = yield* FileSystem.FileSystem;
4046
- const content = yield* fs.readFileString(file$1);
3952
+ }, ({ file, environment }) => Effect.gen(function* () {
3953
+ const content = yield* (yield* FileSystem.FileSystem).readFileString(file);
4047
3954
  const projectId = yield* readProjectId;
4048
- const api = yield* apiClient;
4049
- const result = yield* api["env-vars"].bulkImport({ payload: {
3955
+ const result = yield* (yield* apiClient)["env-vars"].bulkImport({ payload: {
4050
3956
  projectId,
4051
- environment: environment$1,
3957
+ environment,
4052
3958
  content,
4053
3959
  visibility: "plaintext"
4054
3960
  } });
@@ -4058,10 +3964,10 @@ const importCommand = Command.make("import", {
4058
3964
  //#endregion
4059
3965
  //#region src/commands/env/list.ts
4060
3966
  const environmentOption$2 = Options.text("environment").pipe(Options.optional);
4061
- const listCommand$2 = Command.make("list", { environment: environmentOption$2 }, ({ environment: environment$1 }) => Effect.gen(function* () {
3967
+ const listCommand$2 = Command.make("list", { environment: environmentOption$2 }, ({ environment }) => Effect.gen(function* () {
4062
3968
  const projectId = yield* readProjectId;
4063
3969
  const api = yield* apiClient;
4064
- const envFilter = Option.match(environment$1, {
3970
+ const envFilter = Option.match(environment, {
4065
3971
  onNone: () => ({}),
4066
3972
  onSome: (value) => ({ environment: value })
4067
3973
  });
@@ -4089,12 +3995,11 @@ const listCommand$2 = Command.make("list", { environment: environmentOption$2 },
4089
3995
  //#endregion
4090
3996
  //#region src/commands/env/pull.ts
4091
3997
  const environmentOption$1 = Options.text("environment").pipe(Options.withDefault("production"));
4092
- const pullCommand = Command.make("pull", { environment: environmentOption$1 }, ({ environment: environment$1 }) => Effect.gen(function* () {
3998
+ const pullCommand = Command.make("pull", { environment: environmentOption$1 }, ({ environment }) => Effect.gen(function* () {
4093
3999
  const projectId = yield* readProjectId;
4094
- const api = yield* apiClient;
4095
- const result = yield* api["env-vars"].export({ urlParams: {
4000
+ const result = yield* (yield* apiClient)["env-vars"].export({ urlParams: {
4096
4001
  projectId,
4097
- environment: environment$1
4002
+ environment
4098
4003
  } });
4099
4004
  for (const item of result.items) {
4100
4005
  const escaped = item.value.replaceAll("'", String.raw`'\''`);
@@ -4115,14 +4020,13 @@ const setCommand$1 = Command.make("set", {
4115
4020
  keyValue,
4116
4021
  environment: environmentOption,
4117
4022
  visibility: visibilityOption
4118
- }, ({ keyValue: { key, value }, environment: environment$1, visibility }) => Effect.gen(function* () {
4023
+ }, ({ keyValue: { key, value }, environment, visibility }) => Effect.gen(function* () {
4119
4024
  const projectId = yield* readProjectId;
4120
4025
  const api = yield* apiClient;
4121
- const existing = yield* api["env-vars"].list({ urlParams: {
4026
+ const match = (yield* api["env-vars"].list({ urlParams: {
4122
4027
  projectId,
4123
- environment: environment$1
4124
- } });
4125
- const match = existing.items.find((item) => item.key === key);
4028
+ environment
4029
+ } })).items.find((item) => item.key === key);
4126
4030
  if (match) {
4127
4031
  yield* api["env-vars"].update({
4128
4032
  path: { id: match.id },
@@ -4131,16 +4035,16 @@ const setCommand$1 = Command.make("set", {
4131
4035
  visibility
4132
4036
  }
4133
4037
  });
4134
- yield* Console.log(`Updated ${key} in ${environment$1}`);
4038
+ yield* Console.log(`Updated ${key} in ${environment}`);
4135
4039
  } else {
4136
4040
  yield* api["env-vars"].create({ payload: {
4137
4041
  projectId,
4138
- environment: environment$1,
4042
+ environment,
4139
4043
  key,
4140
4044
  value,
4141
4045
  visibility
4142
4046
  } });
4143
- yield* Console.log(`Created ${key} in ${environment$1}`);
4047
+ yield* Console.log(`Created ${key} in ${environment}`);
4144
4048
  }
4145
4049
  }).pipe(handleEnvCommandErrors));
4146
4050
 
@@ -4160,12 +4064,10 @@ const envCommand = Command.make("env", {}, () => Console.log("Manage environment
4160
4064
  //#region src/commands/fingerprint/compare.ts
4161
4065
  const hash = Args.text({ name: "hash" });
4162
4066
  const compareCommand = Command.make("compare", { hash }, (opts) => Effect.gen(function* () {
4163
- const runtime = yield* CliRuntime;
4164
- const projectRoot = yield* runtime.cwd;
4165
- const result = yield* runFingerprintFull(projectRoot);
4067
+ const result = yield* runFingerprintFull(yield* (yield* CliRuntime).cwd);
4166
4068
  if (result.hash === opts.hash) {
4167
4069
  yield* Console.log("Fingerprints match.");
4168
- return void 0;
4070
+ return;
4169
4071
  }
4170
4072
  yield* Console.log("Fingerprints differ.");
4171
4073
  yield* Console.log(` Local: ${result.hash}`);
@@ -4176,9 +4078,7 @@ const compareCommand = Command.make("compare", { hash }, (opts) => Effect.gen(fu
4176
4078
  //#endregion
4177
4079
  //#region src/commands/fingerprint/generate.ts
4178
4080
  const generateCommand = Command.make("generate", {}, () => Effect.gen(function* () {
4179
- const runtime = yield* CliRuntime;
4180
- const projectRoot = yield* runtime.cwd;
4181
- const result = yield* runFingerprintFull(projectRoot);
4081
+ const result = yield* runFingerprintFull(yield* (yield* CliRuntime).cwd);
4182
4082
  yield* Console.log(result.hash);
4183
4083
  if (result.sources.length > 0) yield* Console.log(`${result.sources.length} sources`);
4184
4084
  }).pipe(Effect.catchTag("FingerprintError", (error) => exitWith(2, error.message))));
@@ -4190,11 +4090,10 @@ const fingerprintCommand = Command.make("fingerprint", {}, () => Console.log("Fi
4190
4090
  //#endregion
4191
4091
  //#region src/commands/init.ts
4192
4092
  const initCommand = Command.make("init", {}, () => Effect.gen(function* () {
4193
- const appJson = yield* readAppJson;
4194
- const expo = asRecord(appJson["expo"]);
4195
- const name$2 = asString$1(expo?.["name"]) ?? asString$1(expo?.["slug"]) ?? "untitled";
4093
+ const expo = asRecord((yield* readAppJson)["expo"]);
4094
+ const name = asString$1(expo?.["name"]) ?? asString$1(expo?.["slug"]) ?? "untitled";
4196
4095
  const slug = yield* readSlug;
4197
- yield* Console.log(`Linking project: ${name$2} (${slug})`);
4096
+ yield* Console.log(`Linking project: ${name} (${slug})`);
4198
4097
  const api = yield* apiClient;
4199
4098
  const { items } = yield* api.projects.list({ urlParams: {
4200
4099
  page: 1,
@@ -4207,7 +4106,7 @@ const initCommand = Command.make("init", {}, () => Effect.gen(function* () {
4207
4106
  } else {
4208
4107
  yield* Console.log("No existing project found. Creating new project...");
4209
4108
  const project = yield* api.projects.create({ payload: {
4210
- name: name$2,
4109
+ name,
4211
4110
  slug
4212
4111
  } });
4213
4112
  yield* Console.log(`Created project: ${project.name} (${project.id})`);
@@ -4268,7 +4167,7 @@ const CALLBACK_PAGE = `<!doctype html>
4268
4167
  render(error instanceof Error ? error.message : "Callback failed.");
4269
4168
  });
4270
4169
  }
4271
- </script>
4170
+ <\/script>
4272
4171
  </body>
4273
4172
  </html>`;
4274
4173
  const createBrowserLoginSession = (options = {}) => {
@@ -4336,8 +4235,7 @@ const writeFetchResponse = async (res, response) => {
4336
4235
  const handleIncoming = async (req, res, session) => {
4337
4236
  try {
4338
4237
  const request = await toFetchRequest(req, "http://127.0.0.1");
4339
- const response = await session.handleRequest(request);
4340
- await writeFetchResponse(res, response);
4238
+ await writeFetchResponse(res, await session.handleRequest(request));
4341
4239
  } catch {
4342
4240
  res.statusCode = 500;
4343
4241
  res.end("Local callback failed");
@@ -4350,9 +4248,8 @@ const createBrowserLoginServer = (options = {}) => {
4350
4248
  });
4351
4249
  server.listen(0, "127.0.0.1");
4352
4250
  const address = server.address();
4353
- const port = address !== null && typeof address === "object" ? address.port : 0;
4354
4251
  return {
4355
- callbackUrl: `http://127.0.0.1:${port}${session.callbackPath}`,
4252
+ callbackUrl: `http://127.0.0.1:${address !== null && typeof address === "object" ? address.port : 0}${session.callbackPath}`,
4356
4253
  waitForToken: session.waitForToken,
4357
4254
  stop: () => {
4358
4255
  session.dispose();
@@ -4364,23 +4261,21 @@ const createBrowserLoginServer = (options = {}) => {
4364
4261
  //#endregion
4365
4262
  //#region src/application/login.ts
4366
4263
  const tokenPrompt = Prompt.password({ message: "Paste your API key (from dashboard > API Keys):" });
4367
- const buildOpenBrowserCommand = (platform$7, url) => {
4368
- if (platform$7 === "darwin") return Command$1.make("open", url);
4369
- if (platform$7 === "win32") return Command$1.make("cmd", "/c", "start", "", url);
4264
+ const buildOpenBrowserCommand = (platform, url) => {
4265
+ if (platform === "darwin") return Command$1.make("open", url);
4266
+ if (platform === "win32") return Command$1.make("cmd", "/c", "start", "", url);
4370
4267
  return Command$1.make("xdg-open", url);
4371
4268
  };
4372
4269
  const openBrowser = (url) => Effect.gen(function* () {
4373
- const runtime = yield* CliRuntime;
4374
- const command$1 = buildOpenBrowserCommand(runtime.platform, url);
4375
- const opened = yield* Command$1.exitCode(command$1).pipe(Effect.map((code) => code === 0), Effect.catchAll(() => Effect.succeed(false)));
4376
- if (!opened) yield* Console.log(`Open this URL manually:\n${url}`);
4270
+ const command = buildOpenBrowserCommand((yield* CliRuntime).platform, url);
4271
+ if (!(yield* Command$1.exitCode(command).pipe(Effect.map((code) => code === 0), Effect.catchAll(() => Effect.succeed(false))))) yield* Console.log(`Open this URL manually:\n${url}`);
4377
4272
  });
4378
4273
  const browserLogin = Effect.scoped(Effect.gen(function* () {
4379
4274
  const configStore = yield* ConfigStore;
4380
4275
  const authStore = yield* AuthStore;
4381
- const dashboardUrl = yield* configStore.getDashboardUrl;
4276
+ const accountsUrl = yield* configStore.getAccountsUrl;
4382
4277
  const loginServer = yield* Effect.acquireRelease(Effect.sync(createBrowserLoginServer), (server) => Effect.sync(server.stop));
4383
- const loginUrl = `${dashboardUrl}/cli-login?callbackUrl=${encodeURIComponent(loginServer.callbackUrl)}`;
4278
+ const loginUrl = `${accountsUrl}/cli-login?callbackUrl=${encodeURIComponent(loginServer.callbackUrl)}`;
4384
4279
  yield* Console.log("Opening browser for better-update login...");
4385
4280
  yield* Console.log("");
4386
4281
  yield* openBrowser(loginUrl);
@@ -4394,8 +4289,7 @@ const manualLogin = Effect.gen(function* () {
4394
4289
  yield* Console.log("Get your API key from the dashboard > API Keys page");
4395
4290
  yield* Console.log("");
4396
4291
  const token = Redacted.value(yield* tokenPrompt);
4397
- const authStore = yield* AuthStore;
4398
- yield* authStore.saveToken(token);
4292
+ yield* (yield* AuthStore).saveToken(token);
4399
4293
  yield* Console.log("");
4400
4294
  yield* Console.log("Logged in successfully. Token saved to ~/.better-update/auth.json");
4401
4295
  });
@@ -4416,8 +4310,7 @@ const loginCommand = Command.make("login", { manualApiKey }, (opts) => runLogin(
4416
4310
  //#endregion
4417
4311
  //#region src/commands/logout.ts
4418
4312
  const logoutCommand = Command.make("logout", {}, () => Effect.gen(function* () {
4419
- const authStore = yield* AuthStore;
4420
- yield* authStore.clearToken;
4313
+ yield* (yield* AuthStore).clearToken;
4421
4314
  yield* Console.log("Logged out. Auth token removed.");
4422
4315
  }));
4423
4316
 
@@ -4428,8 +4321,7 @@ const idArg = Args.text({ name: "id" });
4428
4321
  const nameOption = Options.text("name");
4429
4322
  const slugOption = Options.text("slug");
4430
4323
  const listCommand$1 = Command.make("list", {}, () => Effect.gen(function* () {
4431
- const api = yield* apiClient;
4432
- const { items } = yield* api.projects.list({ urlParams: {
4324
+ const { items } = yield* (yield* apiClient).projects.list({ urlParams: {
4433
4325
  page: 1,
4434
4326
  limit: 1e3
4435
4327
  } });
@@ -4453,8 +4345,7 @@ const createCommand = Command.make("create", {
4453
4345
  name: nameOption,
4454
4346
  slug: slugOption
4455
4347
  }, (opts) => Effect.gen(function* () {
4456
- const api = yield* apiClient;
4457
- const project = yield* api.projects.create({ payload: {
4348
+ const project = yield* (yield* apiClient).projects.create({ payload: {
4458
4349
  name: opts.name,
4459
4350
  slug: opts.slug
4460
4351
  } });
@@ -4466,8 +4357,7 @@ const createCommand = Command.make("create", {
4466
4357
  ]);
4467
4358
  }).pipe(handleErrors));
4468
4359
  const getCommand = Command.make("get", { id: idArg }, (opts) => Effect.gen(function* () {
4469
- const api = yield* apiClient;
4470
- const project = yield* api.projects.get({ path: { id: opts.id } });
4360
+ const project = yield* (yield* apiClient).projects.get({ path: { id: opts.id } });
4471
4361
  yield* printKeyValue([
4472
4362
  ["ID", project.id],
4473
4363
  ["Name", project.name],
@@ -4479,16 +4369,14 @@ const renameCommand = Command.make("rename", {
4479
4369
  id: idArg,
4480
4370
  name: nameOption
4481
4371
  }, (opts) => Effect.gen(function* () {
4482
- const api = yield* apiClient;
4483
- const project = yield* api.projects.rename({
4372
+ const project = yield* (yield* apiClient).projects.rename({
4484
4373
  path: { id: opts.id },
4485
4374
  payload: { name: opts.name }
4486
4375
  });
4487
4376
  yield* Console.log(`Project renamed to "${project.name}".`);
4488
4377
  }).pipe(handleErrors));
4489
4378
  const deleteCommand$1 = Command.make("delete", { id: idArg }, (opts) => Effect.gen(function* () {
4490
- const api = yield* apiClient;
4491
- yield* api.projects.delete({ path: { id: opts.id } });
4379
+ yield* (yield* apiClient).projects.delete({ path: { id: opts.id } });
4492
4380
  yield* Console.log(`Project ${opts.id} deleted.`);
4493
4381
  }).pipe(handleErrors));
4494
4382
  const projectsCommand = Command.make("projects", {}, () => Console.log("Manage projects. Run with --help for subcommands.")).pipe(Command.withSubcommands([
@@ -4543,14 +4431,13 @@ const handleUpdateCommandErrors = makeCommandErrorHandler({
4543
4431
  UpdateRollbackError: 2,
4544
4432
  UpdatePromoteError: 2
4545
4433
  });
4546
- const resolveNamedResourceId = (params) => resolveNamedResourceId$2(params, (message$3) => new UpdateCommandError({ message: message$3 }));
4434
+ const resolveNamedResourceId = (params) => resolveNamedResourceId$2(params, (message) => new UpdateCommandError({ message }));
4547
4435
 
4548
4436
  //#endregion
4549
4437
  //#region src/commands/update/delete.ts
4550
4438
  const groupId = Args.text({ name: "groupId" });
4551
4439
  const deleteCommand = Command.make("delete", { groupId }, (opts) => Effect.gen(function* () {
4552
- const api = yield* apiClient;
4553
- const result = yield* api.updates.deleteGroup({ path: { groupId: opts.groupId } });
4440
+ const result = yield* (yield* apiClient).updates.deleteGroup({ path: { groupId: opts.groupId } });
4554
4441
  yield* Console.log(`Deleted ${String(result.deleted)} update(s) from group ${opts.groupId}.`);
4555
4442
  }).pipe(handleUpdateCommandErrors));
4556
4443
 
@@ -4639,30 +4526,30 @@ const loadSignedPayloadFromFiles = (params) => Effect.gen(function* () {
4639
4526
  const loadOptionalSignedPayload = loadSignedPayloadFromFiles;
4640
4527
  const loadSignedPublishPayloads = (params) => Effect.gen(function* () {
4641
4528
  const targetedPlatforms = new Set(params.platforms);
4642
- const nonTargetedPlatforms = ["ios", "android"].filter((platform$7) => !targetedPlatforms.has(platform$7) && hasAnySignedPayloadFile(params.platformFiles[platform$7] ?? emptySignedPayloadFileSet));
4529
+ const nonTargetedPlatforms = ["ios", "android"].filter((platform) => !targetedPlatforms.has(platform) && hasAnySignedPayloadFile(params.platformFiles[platform] ?? emptySignedPayloadFileSet));
4643
4530
  if (nonTargetedPlatforms.length > 0) return yield* Effect.fail(params.makeError(`Signed publish inputs were provided for non-targeted platform(s): ${nonTargetedPlatforms.join(", ")}.`));
4644
4531
  const hasGlobalFiles = hasAnySignedPayloadFile(params.globalFiles);
4645
4532
  if (!hasGlobalFiles && Object.values(params.platformFiles).every((files) => !hasAnySignedPayloadFile(files))) return {};
4646
4533
  if (params.platforms.length > 1 && hasGlobalFiles) return yield* Effect.fail(params.makeError("Signed multi-platform publish requires per-platform file sets. Use the --*-ios and --*-android options."));
4647
4534
  if (params.platforms.length === 1 && hasGlobalFiles) {
4648
- const [platform$7] = params.platforms;
4649
- if (!platform$7) return {};
4650
- if (hasAnySignedPayloadFile(params.platformFiles[platform$7] ?? emptySignedPayloadFileSet)) return yield* Effect.fail(params.makeError(`Signed publish for ${platform$7} is ambiguous. Use either the generic file options or the ${platform$7}-specific file options, not both.`));
4535
+ const [platform] = params.platforms;
4536
+ if (!platform) return {};
4537
+ if (hasAnySignedPayloadFile(params.platformFiles[platform] ?? emptySignedPayloadFileSet)) return yield* Effect.fail(params.makeError(`Signed publish for ${platform} is ambiguous. Use either the generic file options or the ${platform}-specific file options, not both.`));
4651
4538
  const globalPayload = yield* loadSignedPayloadFromFiles({
4652
4539
  files: params.globalFiles,
4653
4540
  label: "Signed publish",
4654
4541
  makeError: params.makeError
4655
4542
  });
4656
- return globalPayload === null ? {} : { [platform$7]: globalPayload };
4543
+ return globalPayload === null ? {} : { [platform]: globalPayload };
4657
4544
  }
4658
- const platformPayloadEntries = yield* Effect.forEach(params.platforms, (platform$7) => Effect.gen(function* () {
4545
+ const platformPayloadEntries = yield* Effect.forEach(params.platforms, (platform) => Effect.gen(function* () {
4659
4546
  const payload = yield* loadSignedPayloadFromFiles({
4660
- files: params.platformFiles[platform$7] ?? emptySignedPayloadFileSet,
4661
- label: `Signed publish for ${platform$7}`,
4547
+ files: params.platformFiles[platform] ?? emptySignedPayloadFileSet,
4548
+ label: `Signed publish for ${platform}`,
4662
4549
  makeError: params.makeError
4663
4550
  });
4664
- if (payload === null) return yield* Effect.fail(params.makeError(`Signed multi-platform publish requires a signed payload for ${platform$7}.`));
4665
- return [platform$7, payload];
4551
+ if (payload === null) return yield* Effect.fail(params.makeError(`Signed multi-platform publish requires a signed payload for ${platform}.`));
4552
+ return [platform, payload];
4666
4553
  }), { concurrency: 1 });
4667
4554
  return Object.fromEntries(platformPayloadEntries);
4668
4555
  });
@@ -4678,9 +4565,9 @@ const runUpdatePromote = (options) => Effect.gen(function* () {
4678
4565
  certificateChainFile: options.certificateChainFile
4679
4566
  },
4680
4567
  label: "Signed promote",
4681
- makeError: (message$3) => new UpdatePromoteError({ message: message$3 })
4568
+ makeError: (message) => new UpdatePromoteError({ message })
4682
4569
  });
4683
- const result = yield* api.updates.republish({ payload: {
4570
+ const [promotedUpdate] = (yield* api.updates.republish({ payload: {
4684
4571
  sourceUpdateId: options.updateId,
4685
4572
  destinationChannel: options.channel,
4686
4573
  ...signedPayload ? { signedUpdates: [{
@@ -4689,8 +4576,7 @@ const runUpdatePromote = (options) => Effect.gen(function* () {
4689
4576
  signature: signedPayload.signature,
4690
4577
  certificateChain: signedPayload.certificateChain
4691
4578
  }] } : {}
4692
- } }).pipe(Effect.catchIf((cause) => cause._tag !== "AuthRequiredError", (cause) => new UpdatePromoteError({ message: `Failed to promote update: ${formatCause(cause)}` })));
4693
- const [promotedUpdate] = result.updates;
4579
+ } }).pipe(Effect.catchIf((cause) => cause._tag !== "AuthRequiredError", (cause) => new UpdatePromoteError({ message: `Failed to promote update: ${formatCause(cause)}` })))).updates;
4694
4580
  if (!promotedUpdate) return yield* new UpdatePromoteError({ message: "Promote completed without returning a promoted update." });
4695
4581
  return {
4696
4582
  sourceUpdateId: options.updateId,
@@ -4727,7 +4613,7 @@ const promoteCommand = Command.make("promote", {
4727
4613
  //#region src/lib/expo-export.ts
4728
4614
  const asString = (value) => typeof value === "string" ? value : void 0;
4729
4615
  const normalizeExtension = (value) => {
4730
- if (!value) return void 0;
4616
+ if (!value) return;
4731
4617
  return value.startsWith(".") ? value.slice(1) : value;
4732
4618
  };
4733
4619
  const inferContentType = (fileExt, isLaunch) => {
@@ -4762,43 +4648,39 @@ const runCommand = (cmd, step) => Command$1.exitCode(cmd.pipe(Command$1.stdout("
4762
4648
  message: `${step} exited with code ${code}`
4763
4649
  }))));
4764
4650
  const readExpoPublicConfig = ({ projectRoot, envVars }) => Effect.gen(function* () {
4765
- const runtime = yield* CliRuntime;
4766
- const commandEnv = yield* runtime.commandEnvironment(envVars);
4651
+ const commandEnv = yield* (yield* CliRuntime).commandEnvironment(envVars);
4767
4652
  const stdout = yield* Command$1.string(makeBunxCommand("expo", "config", "--type", "public", "--json").pipe(Command$1.workingDirectory(projectRoot), Command$1.env(commandEnv))).pipe(Effect.mapError((cause) => new UpdatePublishError({ message: `Failed to read Expo public config: ${String(cause)}` })));
4768
- const parsed = yield* Effect.try({
4653
+ const config = asRecord(yield* Effect.try({
4769
4654
  try: () => JSON.parse(stdout),
4770
4655
  catch: () => new UpdatePublishError({ message: "Expo public config output was not valid JSON." })
4771
- });
4772
- const config = asRecord(parsed);
4656
+ }));
4773
4657
  if (!config) return yield* new UpdatePublishError({ message: "Expo public config did not decode to a JSON object." });
4774
4658
  return config;
4775
4659
  });
4776
- const runExpoExport = ({ projectRoot, exportDir, platform: platform$7, envVars, clear: clear$1 }) => Effect.gen(function* () {
4777
- const runtime = yield* CliRuntime;
4778
- const commandEnv = yield* runtime.commandEnvironment(envVars);
4660
+ const runExpoExport = ({ projectRoot, exportDir, platform, envVars, clear }) => Effect.gen(function* () {
4661
+ const commandEnv = yield* (yield* CliRuntime).commandEnvironment(envVars);
4779
4662
  const args = [
4780
4663
  "expo",
4781
4664
  "export",
4782
4665
  "--platform",
4783
- platform$7,
4666
+ platform,
4784
4667
  "--output-dir",
4785
4668
  exportDir,
4786
4669
  "--dump-assetmap"
4787
4670
  ];
4788
- if (clear$1) args.push("--clear");
4789
- return yield* runCommand(makeBunxCommand(...args).pipe(Command$1.workingDirectory(projectRoot), Command$1.env(commandEnv)), `expo export ${platform$7}`);
4671
+ if (clear) args.push("--clear");
4672
+ return yield* runCommand(makeBunxCommand(...args).pipe(Command$1.workingDirectory(projectRoot), Command$1.env(commandEnv)), `expo export ${platform}`);
4790
4673
  });
4791
- const readExpoExportAssets = ({ exportDir, platform: platform$7 }) => Effect.gen(function* () {
4674
+ const readExpoExportAssets = ({ exportDir, platform }) => Effect.gen(function* () {
4792
4675
  const fs = yield* FileSystem.FileSystem;
4793
4676
  const metadataPath = path.join(exportDir, "metadata.json");
4794
4677
  const metadataText = yield* fs.readFileString(metadataPath).pipe(Effect.mapError(() => new UpdatePublishError({ message: `Expected Expo export metadata at ${metadataPath}.` })));
4795
- const metadata = yield* Effect.try({
4678
+ const platformMetadata = asRecord(asRecord(asRecord(yield* Effect.try({
4796
4679
  try: () => JSON.parse(metadataText),
4797
4680
  catch: () => new UpdatePublishError({ message: `Failed to parse ${metadataPath} as JSON.` })
4798
- });
4799
- const platformMetadata = asRecord(asRecord(asRecord(metadata)?.["fileMetadata"])?.[platform$7]);
4681
+ }))?.["fileMetadata"])?.[platform]);
4800
4682
  const bundlePath = asString(platformMetadata?.["bundle"]);
4801
- if (!bundlePath) return yield* new UpdatePublishError({ message: `Expo export did not contain a bundle path for platform "${platform$7}".` });
4683
+ if (!bundlePath) return yield* new UpdatePublishError({ message: `Expo export did not contain a bundle path for platform "${platform}".` });
4802
4684
  const bundleExt = normalizeExtension(path.extname(bundlePath)) ?? "js";
4803
4685
  const rawAssets = Array.isArray(platformMetadata?.["assets"]) ? platformMetadata["assets"] : [];
4804
4686
  const assets = yield* Effect.forEach(rawAssets, (rawAsset, index) => Effect.gen(function* () {
@@ -4828,21 +4710,21 @@ const readExpoExportAssets = ({ exportDir, platform: platform$7 }) => Effect.gen
4828
4710
  const resolveUpdatePlatforms = (appJson, requestedPlatform) => {
4829
4711
  if (requestedPlatform !== "all") return [requestedPlatform];
4830
4712
  const expo = asRecord(appJson["expo"]);
4831
- return ["ios", "android"].filter((platform$7) => asRecord(expo?.[platform$7]) !== void 0);
4713
+ return ["ios", "android"].filter((platform) => asRecord(expo?.[platform]) !== void 0);
4832
4714
  };
4833
4715
 
4834
4716
  //#endregion
4835
4717
  //#region src/application/update-publish.ts
4836
- const buildUpdateExtra = (expoClient, projectId, environment$1) => ({
4718
+ const buildUpdateExtra = (expoClient, projectId, environment) => ({
4837
4719
  expoClient,
4838
4720
  eas: { projectId },
4839
- environment: environment$1
4721
+ environment
4840
4722
  });
4841
4723
  const dedupeAssetsByHash = (assets) => uniqBy(assets, (asset) => asset.hash);
4842
- const preparePlatformAssets = ({ exportDir, platform: platform$7 }) => Effect.gen(function* () {
4724
+ const preparePlatformAssets = ({ exportDir, platform }) => Effect.gen(function* () {
4843
4725
  const exportedAssets = yield* readExpoExportAssets({
4844
4726
  exportDir,
4845
- platform: platform$7
4727
+ platform
4846
4728
  });
4847
4729
  return yield* Effect.forEach(exportedAssets, (asset) => sha256File(asset.path).pipe(Effect.map(({ sha256: contentSha256Hex, byteSize }) => ({
4848
4730
  ...asset,
@@ -4924,85 +4806,80 @@ const publishPlatform = (params) => Effect.gen(function* () {
4924
4806
  deduplicatedAssets: assetRegistration.deduplicated.length
4925
4807
  };
4926
4808
  });
4927
- const runUpdatePublish = (options) => Effect.scoped(
4928
- // eslint-disable-next-line eslint/max-statements -- update publish orchestration is inherently sequential (read config → resolve runtime version → expo export → register assets → publish per platform); splitting further fragments the pipeline without improving readability
4929
- Effect.gen(function* () {
4930
- const runtime = yield* CliRuntime;
4931
- const projectRoot = yield* runtime.cwd;
4932
- const api = yield* apiClient;
4933
- const projectId = yield* readProjectId;
4934
- const slug = yield* readSlug;
4935
- const appJson = yield* readAppJson;
4936
- const platforms = resolveUpdatePlatforms(appJson, options.platform);
4937
- if (platforms.length === 0) return yield* new UpdatePublishError({ message: "No publishable platforms found in app.json. Add an \"expo.ios\" or \"expo.android\" section, or pass --platform explicitly." });
4938
- const environmentVars = yield* pullEnvVars(api, {
4939
- projectId,
4940
- environment: options.environment
4941
- });
4942
- const expoClientConfig = yield* readExpoPublicConfig({
4943
- projectRoot,
4944
- envVars: environmentVars
4945
- });
4946
- const tempDir = yield* acquireBuildTempDir.pipe(Effect.mapError((cause) => new UpdatePublishError({ message: `Failed to create a temporary export directory: ${formatCause(cause)}` })));
4947
- let resolvedBranch = options.branch;
4948
- let resolvedMessage = options.message;
4949
- if (options.auto) {
4950
- const gitContext = yield* readGitContext(projectRoot);
4951
- if (!resolvedBranch) {
4952
- if (!gitContext.ref) return yield* new UpdatePublishError({ message: "Cannot infer branch from git. Ensure you are in a git repo with a checked-out branch, or provide --branch explicitly." });
4953
- resolvedBranch = gitContext.ref;
4954
- }
4955
- if (!resolvedMessage && gitContext.commitMessage) resolvedMessage = gitContext.commitMessage;
4809
+ const runUpdatePublish = (options) => Effect.scoped(Effect.gen(function* () {
4810
+ const projectRoot = yield* (yield* CliRuntime).cwd;
4811
+ const api = yield* apiClient;
4812
+ const projectId = yield* readProjectId;
4813
+ const slug = yield* readSlug;
4814
+ const appJson = yield* readAppJson;
4815
+ const platforms = resolveUpdatePlatforms(appJson, options.platform);
4816
+ if (platforms.length === 0) return yield* new UpdatePublishError({ message: "No publishable platforms found in app.json. Add an \"expo.ios\" or \"expo.android\" section, or pass --platform explicitly." });
4817
+ const environmentVars = yield* pullEnvVars(api, {
4818
+ projectId,
4819
+ environment: options.environment
4820
+ });
4821
+ const expoClientConfig = yield* readExpoPublicConfig({
4822
+ projectRoot,
4823
+ envVars: environmentVars
4824
+ });
4825
+ const tempDir = yield* acquireBuildTempDir.pipe(Effect.mapError((cause) => new UpdatePublishError({ message: `Failed to create a temporary export directory: ${formatCause(cause)}` })));
4826
+ let resolvedBranch = options.branch;
4827
+ let resolvedMessage = options.message;
4828
+ if (options.auto) {
4829
+ const gitContext = yield* readGitContext(projectRoot);
4830
+ if (!resolvedBranch) {
4831
+ if (!gitContext.ref) return yield* new UpdatePublishError({ message: "Cannot infer branch from git. Ensure you are in a git repo with a checked-out branch, or provide --branch explicitly." });
4832
+ resolvedBranch = gitContext.ref;
4956
4833
  }
4957
- if (!resolvedBranch) return yield* new UpdatePublishError({ message: "Missing --branch. Provide it explicitly or use --auto to infer from git." });
4958
- const branch$6 = resolvedBranch;
4959
- const groupId$1 = randomUUID();
4960
- const message$3 = resolvedMessage ?? "Publish via better-update CLI";
4961
- const signedPayloads = yield* loadSignedPublishPayloads({
4962
- platforms,
4963
- globalFiles: {
4964
- manifestBodyFile: options.manifestBodyFile,
4965
- signatureFile: options.signatureFile,
4966
- certificateChainFile: options.certificateChainFile
4967
- },
4968
- platformFiles: {
4969
- ios: {
4970
- manifestBodyFile: options.manifestBodyFileIos,
4971
- signatureFile: options.signatureFileIos,
4972
- certificateChainFile: options.certificateChainFileIos
4973
- },
4974
- android: {
4975
- manifestBodyFile: options.manifestBodyFileAndroid,
4976
- signatureFile: options.signatureFileAndroid,
4977
- certificateChainFile: options.certificateChainFileAndroid
4978
- }
4834
+ if (!resolvedMessage && gitContext.commitMessage) resolvedMessage = gitContext.commitMessage;
4835
+ }
4836
+ if (!resolvedBranch) return yield* new UpdatePublishError({ message: "Missing --branch. Provide it explicitly or use --auto to infer from git." });
4837
+ const branch = resolvedBranch;
4838
+ const groupId = randomUUID();
4839
+ const message = resolvedMessage ?? "Publish via better-update CLI";
4840
+ const signedPayloads = yield* loadSignedPublishPayloads({
4841
+ platforms,
4842
+ globalFiles: {
4843
+ manifestBodyFile: options.manifestBodyFile,
4844
+ signatureFile: options.signatureFile,
4845
+ certificateChainFile: options.certificateChainFile
4846
+ },
4847
+ platformFiles: {
4848
+ ios: {
4849
+ manifestBodyFile: options.manifestBodyFileIos,
4850
+ signatureFile: options.signatureFileIos,
4851
+ certificateChainFile: options.certificateChainFileIos
4979
4852
  },
4980
- makeError: (errorMessage) => new UpdatePublishError({ message: errorMessage })
4981
- });
4982
- const results = yield* Effect.forEach(platforms, (platform$7) => publishPlatform({
4853
+ android: {
4854
+ manifestBodyFile: options.manifestBodyFileAndroid,
4855
+ signatureFile: options.signatureFileAndroid,
4856
+ certificateChainFile: options.certificateChainFileAndroid
4857
+ }
4858
+ },
4859
+ makeError: (errorMessage) => new UpdatePublishError({ message: errorMessage })
4860
+ });
4861
+ return {
4862
+ groupId,
4863
+ branch,
4864
+ results: yield* Effect.forEach(platforms, (platform) => publishPlatform({
4983
4865
  projectRoot,
4984
- exportDir: path.join(tempDir, `export-${platform$7}`),
4866
+ exportDir: path.join(tempDir, `export-${platform}`),
4985
4867
  projectId,
4986
4868
  slug,
4987
- branch: branch$6,
4988
- groupId: groupId$1,
4989
- message: message$3,
4869
+ branch,
4870
+ groupId,
4871
+ message,
4990
4872
  environment: options.environment,
4991
4873
  environmentVars,
4992
4874
  expoClientConfig,
4993
4875
  clear: options.clear,
4994
4876
  appJson,
4995
- platform: platform$7,
4996
- signedPayload: signedPayloads[platform$7] ?? null,
4877
+ platform,
4878
+ signedPayload: signedPayloads[platform] ?? null,
4997
4879
  rolloutPercentage: options.rolloutPercentage
4998
- }), { concurrency: 1 });
4999
- return {
5000
- groupId: groupId$1,
5001
- branch: branch$6,
5002
- results
5003
- };
5004
- })
5005
- );
4880
+ }), { concurrency: 1 })
4881
+ };
4882
+ }));
5006
4883
 
5007
4884
  //#endregion
5008
4885
  //#region src/commands/update/publish.ts
@@ -5089,17 +4966,17 @@ const publishCommand = Command.make("publish", {
5089
4966
 
5090
4967
  //#endregion
5091
4968
  //#region ../../packages/expo-protocol/src/index.ts
5092
- const buildRollbackDirectiveBody = (commitTime$1) => JSON.stringify({
4969
+ const buildRollbackDirectiveBody = (commitTime) => JSON.stringify({
5093
4970
  type: "rollBackToEmbedded",
5094
- parameters: { commitTime: commitTime$1 }
4971
+ parameters: { commitTime }
5095
4972
  });
5096
4973
 
5097
4974
  //#endregion
5098
4975
  //#region src/application/update-rollback.ts
5099
4976
  const resolveCommitTime = (input) => Effect.gen(function* () {
5100
- const commitTime$1 = input ?? new Date().toISOString();
5101
- if (Number.isNaN(Date.parse(commitTime$1))) return yield* new UpdateRollbackError({ message: "commitTime must be a valid ISO 8601 timestamp." });
5102
- return commitTime$1;
4977
+ const commitTime = input ?? (/* @__PURE__ */ new Date()).toISOString();
4978
+ if (Number.isNaN(Date.parse(commitTime))) return yield* new UpdateRollbackError({ message: "commitTime must be a valid ISO 8601 timestamp." });
4979
+ return commitTime;
5103
4980
  });
5104
4981
  const extractDirectiveCommitTime = (directiveBody) => Effect.gen(function* () {
5105
4982
  const directive = yield* Effect.try({
@@ -5110,14 +4987,13 @@ const extractDirectiveCommitTime = (directiveBody) => Effect.gen(function* () {
5110
4987
  if (directive["type"] !== "rollBackToEmbedded") return yield* new UpdateRollbackError({ message: "directiveBody.type must be \"rollBackToEmbedded\"." });
5111
4988
  const { parameters } = directive;
5112
4989
  if (!isRecord(parameters)) return yield* new UpdateRollbackError({ message: "directiveBody.parameters must be an object." });
5113
- const { commitTime: commitTime$1 } = parameters;
5114
- if (typeof commitTime$1 !== "string" || Number.isNaN(Date.parse(commitTime$1))) return yield* new UpdateRollbackError({ message: "directiveBody.parameters.commitTime must be a valid ISO 8601 timestamp." });
5115
- return commitTime$1;
4990
+ const { commitTime } = parameters;
4991
+ if (typeof commitTime !== "string" || Number.isNaN(Date.parse(commitTime))) return yield* new UpdateRollbackError({ message: "directiveBody.parameters.commitTime must be a valid ISO 8601 timestamp." });
4992
+ return commitTime;
5116
4993
  });
5117
4994
  const loadOptionalSignedRollbackPayload = (options) => Effect.gen(function* () {
5118
4995
  const fileSystem = yield* FileSystem.FileSystem;
5119
- const hasAnySigningInput = options.directiveBodyFile !== void 0 || options.signatureFile !== void 0 || options.certificateChainFile !== void 0;
5120
- if (!hasAnySigningInput) return null;
4996
+ if (!(options.directiveBodyFile !== void 0 || options.signatureFile !== void 0 || options.certificateChainFile !== void 0)) return null;
5121
4997
  if (!options.directiveBodyFile || !options.signatureFile || !options.certificateChainFile) return yield* new UpdateRollbackError({ message: "Signed rollback requires --directive-body-file, --signature-file, and --certificate-chain-file together." });
5122
4998
  const [directiveBody, signature, certificateChain] = yield* Effect.all([
5123
4999
  fileSystem.readFileString(options.directiveBodyFile),
@@ -5131,8 +5007,7 @@ const loadOptionalSignedRollbackPayload = (options) => Effect.gen(function* () {
5131
5007
  };
5132
5008
  });
5133
5009
  const createRollbackForPlatform = (params) => Effect.gen(function* () {
5134
- const api = yield* apiClient;
5135
- const update = yield* api.updates.create({ payload: {
5010
+ const update = yield* (yield* apiClient).updates.create({ payload: {
5136
5011
  branch: params.branch,
5137
5012
  slug: params.projectSlug,
5138
5013
  runtimeVersion: params.runtimeVersion,
@@ -5153,8 +5028,7 @@ const createRollbackForPlatform = (params) => Effect.gen(function* () {
5153
5028
  };
5154
5029
  });
5155
5030
  const runUpdateRollback = (options) => Effect.gen(function* () {
5156
- const runtime = yield* CliRuntime;
5157
- const projectRoot = yield* runtime.cwd;
5031
+ const projectRoot = yield* (yield* CliRuntime).cwd;
5158
5032
  yield* readProjectId;
5159
5033
  const projectSlug = yield* readSlug;
5160
5034
  const appJson = yield* readAppJson;
@@ -5167,28 +5041,28 @@ const runUpdateRollback = (options) => Effect.gen(function* () {
5167
5041
  projectRoot
5168
5042
  });
5169
5043
  const signedPayload = yield* loadOptionalSignedRollbackPayload(options);
5170
- const commitTime$1 = signedPayload ? yield* Effect.gen(function* () {
5044
+ const commitTime = signedPayload ? yield* Effect.gen(function* () {
5171
5045
  const directiveCommitTime = yield* extractDirectiveCommitTime(signedPayload.directiveBody);
5172
5046
  if (options.commitTime && options.commitTime !== directiveCommitTime) return yield* new UpdateRollbackError({ message: "commitTime must match directiveBody.parameters.commitTime in signed mode." });
5173
5047
  return directiveCommitTime;
5174
5048
  }) : yield* resolveCommitTime(options.commitTime);
5175
- const groupId$1 = randomUUID();
5176
- const message$3 = options.message ?? "Rollback to embedded via better-update CLI";
5177
- const results = yield* Effect.forEach(platforms, (platform$7) => createRollbackForPlatform({
5049
+ const groupId = randomUUID();
5050
+ const message = options.message ?? "Rollback to embedded via better-update CLI";
5051
+ const results = yield* Effect.forEach(platforms, (platform) => createRollbackForPlatform({
5178
5052
  branch: options.branch,
5179
5053
  projectSlug,
5180
5054
  runtimeVersion,
5181
- platform: platform$7,
5182
- message: message$3,
5183
- groupId: groupId$1,
5184
- directiveBody: signedPayload?.directiveBody ?? buildRollbackDirectiveBody(commitTime$1),
5055
+ platform,
5056
+ message,
5057
+ groupId,
5058
+ directiveBody: signedPayload?.directiveBody ?? buildRollbackDirectiveBody(commitTime),
5185
5059
  signature: signedPayload?.signature,
5186
5060
  certificateChain: signedPayload?.certificateChain
5187
5061
  }), { concurrency: 1 });
5188
5062
  return {
5189
- groupId: groupId$1,
5063
+ groupId,
5190
5064
  branch: options.branch,
5191
- commitTime: commitTime$1,
5065
+ commitTime,
5192
5066
  results
5193
5067
  };
5194
5068
  });
@@ -5241,8 +5115,7 @@ const rollbackCommand = Command.make("rollback", {
5241
5115
  //#region src/commands/update/rollout/complete.ts
5242
5116
  const updateId$2 = Args.text({ name: "updateId" });
5243
5117
  const completeCommand = Command.make("complete", { updateId: updateId$2 }, (opts) => Effect.gen(function* () {
5244
- const api = yield* apiClient;
5245
- const result = yield* api.updates.completeRollout({ path: { id: opts.updateId } });
5118
+ const result = yield* (yield* apiClient).updates.completeRollout({ path: { id: opts.updateId } });
5246
5119
  yield* Console.log(`Completed rollout for ${opts.updateId}. Current rollout is ${String(result.rolloutPercentage)}%.`);
5247
5120
  }).pipe(handleUpdateCommandErrors));
5248
5121
 
@@ -5250,8 +5123,7 @@ const completeCommand = Command.make("complete", { updateId: updateId$2 }, (opts
5250
5123
  //#region src/commands/update/rollout/revert.ts
5251
5124
  const updateId$1 = Args.text({ name: "updateId" });
5252
5125
  const revertCommand = Command.make("revert", { updateId: updateId$1 }, (opts) => Effect.gen(function* () {
5253
- const api = yield* apiClient;
5254
- const result = yield* api.updates.revertRollout({ path: { id: opts.updateId } });
5126
+ const result = yield* (yield* apiClient).updates.revertRollout({ path: { id: opts.updateId } });
5255
5127
  yield* Console.log(`Reverted rollout for ${opts.updateId}. Current rollout is ${String(result.rolloutPercentage)}%.`);
5256
5128
  }).pipe(handleUpdateCommandErrors));
5257
5129
 
@@ -5263,8 +5135,7 @@ const setCommand = Command.make("set", {
5263
5135
  updateId,
5264
5136
  percentage
5265
5137
  }, (opts) => Effect.gen(function* () {
5266
- const api = yield* apiClient;
5267
- const result = yield* api.updates.editRollout({
5138
+ const result = yield* (yield* apiClient).updates.editRollout({
5268
5139
  path: { id: opts.updateId },
5269
5140
  payload: { percentage: opts.percentage }
5270
5141
  });
@@ -5309,11 +5180,11 @@ const command = Command.make("better-update", {}, () => Console.log("better-upda
5309
5180
  analyticsCommand,
5310
5181
  auditLogsCommand
5311
5182
  ]));
5312
- const cli = Command.run(command, {
5183
+ Command.run(command, {
5313
5184
  name: "better-update",
5314
5185
  version: "0.1.0"
5315
- });
5316
- cli(process.argv).pipe(Effect.provide(CliLive), NodeRuntime.runMain);
5186
+ })(process.argv).pipe(Effect.provide(CliLive), NodeRuntime.runMain);
5317
5187
 
5318
5188
  //#endregion
5319
- //# sourceMappingURL=index.js.map
5189
+ export { };
5190
+ //# sourceMappingURL=index.mjs.map