@better-update/cli 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +237 -189
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,15 @@ import { cancel, isCancel, password } from "@clack/prompts";
|
|
|
19
19
|
//#region \0rolldown/runtime.js
|
|
20
20
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
21
21
|
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region package.json
|
|
24
|
+
var version = "0.7.0";
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region ../../packages/type-guards/src/index.ts
|
|
28
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29
|
+
const asRecord = (value) => isRecord(value) ? value : void 0;
|
|
30
|
+
|
|
22
31
|
//#endregion
|
|
23
32
|
//#region src/lib/exit-codes.ts
|
|
24
33
|
var AuthRequiredError = class extends Data.TaggedError("AuthRequiredError") {};
|
|
@@ -57,11 +66,6 @@ const formatCause = (cause) => {
|
|
|
57
66
|
return String(cause);
|
|
58
67
|
};
|
|
59
68
|
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/lib/record.ts
|
|
62
|
-
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
63
|
-
const asRecord = (value) => isRecord(value) ? value : void 0;
|
|
64
|
-
|
|
65
69
|
//#endregion
|
|
66
70
|
//#region src/lib/app-json.ts
|
|
67
71
|
const readAppJson = Effect.gen(function* () {
|
|
@@ -135,6 +139,14 @@ const PaginationParams = Schema.Struct({
|
|
|
135
139
|
page: Schema.optional(Schema.NumberFromString),
|
|
136
140
|
limit: Schema.optional(Schema.NumberFromString)
|
|
137
141
|
});
|
|
142
|
+
const CursorPaginationParams = Schema.Struct({
|
|
143
|
+
cursor: Schema.optional(Schema.String),
|
|
144
|
+
limit: Schema.optional(Schema.NumberFromString)
|
|
145
|
+
});
|
|
146
|
+
const cursorPageResult = (itemSchema) => Schema.Struct({
|
|
147
|
+
items: Schema.Array(itemSchema),
|
|
148
|
+
nextCursor: Schema.NullOr(Schema.String)
|
|
149
|
+
});
|
|
138
150
|
const UpdateRolloutBody = Schema.Struct({ percentage: Schema.Number.pipe(Schema.int(), Schema.between(1, 100)) });
|
|
139
151
|
const UploadHeaders = Schema.Record({
|
|
140
152
|
key: Schema.String,
|
|
@@ -634,18 +646,11 @@ var AuditLog = class extends Schema.Class("AuditLog")({
|
|
|
634
646
|
//#region ../../packages/api/src/groups/audit-logs.ts
|
|
635
647
|
var AuditLogsGroup = class extends HttpApiGroup.make("audit-logs").add(HttpApiEndpoint.get("list", "/api/audit-logs").setUrlParams(Schema.Struct({
|
|
636
648
|
projectId: Schema.optional(Schema.String),
|
|
637
|
-
action: Schema.optional(Schema.String),
|
|
638
649
|
resourceType: Schema.optional(Schema.String),
|
|
639
|
-
actorId: Schema.optional(Schema.String),
|
|
640
650
|
from: Schema.optional(Schema.String),
|
|
641
651
|
to: Schema.optional(Schema.String),
|
|
642
|
-
...
|
|
643
|
-
})).addSuccess(
|
|
644
|
-
items: Schema.Array(AuditLog),
|
|
645
|
-
total: Schema.Number,
|
|
646
|
-
page: Schema.Number,
|
|
647
|
-
limit: Schema.Number
|
|
648
|
-
})).annotateContext(OpenApi.annotations({
|
|
652
|
+
...CursorPaginationParams.fields
|
|
653
|
+
})).addSuccess(cursorPageResult(AuditLog)).annotateContext(OpenApi.annotations({
|
|
649
654
|
title: "List audit logs",
|
|
650
655
|
description: "List audit log entries with optional filters"
|
|
651
656
|
}))).addError(Forbidden).annotateContext(OpenApi.annotations({
|
|
@@ -676,13 +681,8 @@ var BranchesGroup = class extends HttpApiGroup.make("branches").add(HttpApiEndpo
|
|
|
676
681
|
description: "Create a new branch within a project"
|
|
677
682
|
}))).add(HttpApiEndpoint.get("list", "/api/branches").setUrlParams(Schema.Struct({
|
|
678
683
|
projectId: Id,
|
|
679
|
-
...
|
|
680
|
-
})).addSuccess(
|
|
681
|
-
items: Schema.Array(Branch),
|
|
682
|
-
total: Schema.Number,
|
|
683
|
-
page: Schema.Number,
|
|
684
|
-
limit: Schema.Number
|
|
685
|
-
})).annotateContext(OpenApi.annotations({
|
|
684
|
+
...CursorPaginationParams.fields
|
|
685
|
+
})).addSuccess(cursorPageResult(Branch)).annotateContext(OpenApi.annotations({
|
|
686
686
|
title: "List branches",
|
|
687
687
|
description: "List all branches for a project"
|
|
688
688
|
}))).add(HttpApiEndpoint.patch("rename")`/api/branches/${idParam$8}`.setPayload(UpdateBranchBody).addSuccess(Branch).addError(Conflict).annotateContext(OpenApi.annotations({
|
|
@@ -852,15 +852,17 @@ const InstallLinkResult = Schema.Struct({
|
|
|
852
852
|
//#region ../../packages/api/src/domain/build-compatibility.ts
|
|
853
853
|
var BuildCompatibilityChannel = class extends Schema.Class("BuildCompatibilityChannel")({
|
|
854
854
|
channelId: Id,
|
|
855
|
-
channelName: Schema.String,
|
|
856
855
|
updateCount: Schema.Number,
|
|
857
856
|
latestUpdateId: Schema.NullOr(Id),
|
|
858
857
|
latestUpdateMessage: Schema.NullOr(Schema.String),
|
|
859
|
-
latestUpdateCreatedAt: Schema.NullOr(DateTimeString)
|
|
858
|
+
latestUpdateCreatedAt: Schema.NullOr(DateTimeString)
|
|
859
|
+
}) {};
|
|
860
|
+
var CompatibilityChannelInfo = class extends Schema.Class("CompatibilityChannelInfo")({
|
|
861
|
+
channelId: Id,
|
|
862
|
+
channelName: Schema.String,
|
|
860
863
|
isPaused: Schema.Boolean,
|
|
861
864
|
rolloutActive: Schema.Boolean
|
|
862
865
|
}) {};
|
|
863
|
-
var BuildCompatibilityRow = class extends BuildWithArtifact.extend("BuildCompatibilityRow")({ channels: Schema.Array(BuildCompatibilityChannel) }) {};
|
|
864
866
|
var MissingRuntimeVersionBuild = class extends Schema.Class("MissingRuntimeVersionBuild")({
|
|
865
867
|
channelId: Id,
|
|
866
868
|
channelName: Schema.String,
|
|
@@ -873,7 +875,11 @@ var MissingRuntimeVersionBuild = class extends Schema.Class("MissingRuntimeVersi
|
|
|
873
875
|
rolloutActive: Schema.Boolean
|
|
874
876
|
}) {};
|
|
875
877
|
const BuildCompatibilityMatrixResult = Schema.Struct({
|
|
876
|
-
|
|
878
|
+
channels: Schema.Array(CompatibilityChannelInfo),
|
|
879
|
+
channelStatusByKey: Schema.Record({
|
|
880
|
+
key: Schema.String,
|
|
881
|
+
value: Schema.Array(BuildCompatibilityChannel)
|
|
882
|
+
}),
|
|
877
883
|
missingRuntimeVersions: Schema.Array(MissingRuntimeVersionBuild)
|
|
878
884
|
});
|
|
879
885
|
|
|
@@ -891,13 +897,8 @@ var BuildsGroup = class extends HttpApiGroup.make("builds").add(HttpApiEndpoint.
|
|
|
891
897
|
platform: Schema.optional(Platform),
|
|
892
898
|
profile: Schema.optional(Schema.String),
|
|
893
899
|
runtimeVersion: Schema.optional(Schema.String),
|
|
894
|
-
...
|
|
895
|
-
})).addSuccess(
|
|
896
|
-
items: Schema.Array(BuildWithArtifact),
|
|
897
|
-
total: Schema.Number,
|
|
898
|
-
page: Schema.Number,
|
|
899
|
-
limit: Schema.Number
|
|
900
|
-
})).annotateContext(OpenApi.annotations({
|
|
900
|
+
...CursorPaginationParams.fields
|
|
901
|
+
})).addSuccess(cursorPageResult(BuildWithArtifact)).annotateContext(OpenApi.annotations({
|
|
901
902
|
title: "List builds",
|
|
902
903
|
description: "List builds for a project with optional filters"
|
|
903
904
|
}))).add(HttpApiEndpoint.get("compatibilityMatrix", "/api/builds/compatibility-matrix").setUrlParams(Schema.Struct({ projectId: Id })).addSuccess(BuildCompatibilityMatrixResult).annotateContext(OpenApi.annotations({
|
|
@@ -952,13 +953,8 @@ var ChannelsGroup = class extends HttpApiGroup.make("channels").add(HttpApiEndpo
|
|
|
952
953
|
description: "Relink channel to a different branch"
|
|
953
954
|
}))).add(HttpApiEndpoint.get("list", "/api/channels").setUrlParams(Schema.Struct({
|
|
954
955
|
projectId: Id,
|
|
955
|
-
...
|
|
956
|
-
})).addSuccess(
|
|
957
|
-
items: Schema.Array(Channel),
|
|
958
|
-
total: Schema.Number,
|
|
959
|
-
page: Schema.Number,
|
|
960
|
-
limit: Schema.Number
|
|
961
|
-
})).annotateContext(OpenApi.annotations({
|
|
956
|
+
...CursorPaginationParams.fields
|
|
957
|
+
})).addSuccess(cursorPageResult(Channel)).annotateContext(OpenApi.annotations({
|
|
962
958
|
title: "List channels",
|
|
963
959
|
description: "List all channels for a project"
|
|
964
960
|
}))).add(HttpApiEndpoint.post("pause")`/api/channels/${idParam$6}/pause`.addSuccess(Channel).annotateContext(OpenApi.annotations({
|
|
@@ -1019,10 +1015,10 @@ const UpdateDeviceBody = Schema.Struct({
|
|
|
1019
1015
|
});
|
|
1020
1016
|
const DeleteDeviceResult = Schema.Struct({ deleted: Schema.Number });
|
|
1021
1017
|
const ListDevicesParams = Schema.Struct({
|
|
1022
|
-
...
|
|
1023
|
-
search: Schema.optional(Schema.String),
|
|
1018
|
+
...CursorPaginationParams.fields,
|
|
1024
1019
|
deviceClass: Schema.optional(DeviceClass),
|
|
1025
|
-
appleTeamId: Schema.optional(Id)
|
|
1020
|
+
appleTeamId: Schema.optional(Id),
|
|
1021
|
+
query: Schema.optional(Schema.String)
|
|
1026
1022
|
});
|
|
1027
1023
|
var DeviceRegistrationRequest = class extends Schema.Class("DeviceRegistrationRequest")({
|
|
1028
1024
|
id: Id,
|
|
@@ -1053,12 +1049,7 @@ const idParam$5 = HttpApiSchema.param("id", Schema.String);
|
|
|
1053
1049
|
var DevicesGroup = class extends HttpApiGroup.make("devices").add(HttpApiEndpoint.post("register", "/api/devices").setPayload(RegisterDeviceBody).addSuccess(Device, { status: 201 }).annotateContext(OpenApi.annotations({
|
|
1054
1050
|
title: "Register device",
|
|
1055
1051
|
description: "Register an Apple device UDID in the caller's active organization"
|
|
1056
|
-
}))).add(HttpApiEndpoint.get("list", "/api/devices").setUrlParams(ListDevicesParams).addSuccess(
|
|
1057
|
-
items: Schema.Array(Device),
|
|
1058
|
-
total: Schema.Number,
|
|
1059
|
-
page: Schema.Number,
|
|
1060
|
-
limit: Schema.Number
|
|
1061
|
-
})).annotateContext(OpenApi.annotations({
|
|
1052
|
+
}))).add(HttpApiEndpoint.get("list", "/api/devices").setUrlParams(ListDevicesParams).addSuccess(cursorPageResult(Device)).annotateContext(OpenApi.annotations({
|
|
1062
1053
|
title: "List devices",
|
|
1063
1054
|
description: "List registered Apple devices in the caller's active organization"
|
|
1064
1055
|
}))).add(HttpApiEndpoint.get("get")`/api/devices/${idParam$5}`.addSuccess(Device).annotateContext(OpenApi.annotations({
|
|
@@ -1141,12 +1132,7 @@ var EnvVarsGroup = class extends HttpApiGroup.make("env-vars").add(HttpApiEndpoi
|
|
|
1141
1132
|
projectId: Id,
|
|
1142
1133
|
environment: Schema.optional(Schema.String),
|
|
1143
1134
|
...PaginationParams.fields
|
|
1144
|
-
})).addSuccess(Schema.Struct({
|
|
1145
|
-
items: Schema.Array(EnvVar),
|
|
1146
|
-
total: Schema.Number,
|
|
1147
|
-
page: Schema.Number,
|
|
1148
|
-
limit: Schema.Number
|
|
1149
|
-
})).annotateContext(OpenApi.annotations({
|
|
1135
|
+
})).addSuccess(Schema.Struct({ items: Schema.Array(EnvVar) })).annotateContext(OpenApi.annotations({
|
|
1150
1136
|
title: "List environment variables",
|
|
1151
1137
|
description: "List environment variables with optional filters"
|
|
1152
1138
|
}))).add(HttpApiEndpoint.get("get")`/api/env-vars/${idParam$4}`.addSuccess(EnvVar).annotateContext(OpenApi.annotations({
|
|
@@ -1265,8 +1251,17 @@ var Project = class extends Schema.Class("Project")({
|
|
|
1265
1251
|
name: Schema.String,
|
|
1266
1252
|
slug: Schema.String,
|
|
1267
1253
|
createdAt: DateTimeString,
|
|
1268
|
-
lastActivityAt: DateTimeString
|
|
1254
|
+
lastActivityAt: DateTimeString,
|
|
1255
|
+
branchCount: Schema.Number,
|
|
1256
|
+
channelCount: Schema.Number,
|
|
1257
|
+
updateCount: Schema.Number
|
|
1269
1258
|
}) {};
|
|
1259
|
+
const ProjectSort = Schema.Literal("lastActivityAt", "name");
|
|
1260
|
+
const ListProjectsParams = Schema.Struct({
|
|
1261
|
+
...PaginationParams.fields,
|
|
1262
|
+
query: Schema.optional(Schema.String),
|
|
1263
|
+
sort: Schema.optional(ProjectSort)
|
|
1264
|
+
});
|
|
1270
1265
|
const CreateProjectBody = Schema.Struct({
|
|
1271
1266
|
name: Schema.String.pipe(Schema.minLength(1)),
|
|
1272
1267
|
slug: Schema.String.pipe(Schema.minLength(1))
|
|
@@ -1281,7 +1276,7 @@ const slugParam = HttpApiSchema.param("slug", Schema.String);
|
|
|
1281
1276
|
var ProjectsGroup = class extends HttpApiGroup.make("projects").add(HttpApiEndpoint.post("create", "/api/projects").setPayload(CreateProjectBody).addSuccess(Project, { status: 201 }).annotateContext(OpenApi.annotations({
|
|
1282
1277
|
title: "Create project",
|
|
1283
1278
|
description: "Create a new project in the caller's active organization"
|
|
1284
|
-
}))).add(HttpApiEndpoint.get("list", "/api/projects").setUrlParams(
|
|
1279
|
+
}))).add(HttpApiEndpoint.get("list", "/api/projects").setUrlParams(ListProjectsParams).addSuccess(Schema.Struct({
|
|
1285
1280
|
items: Schema.Array(Project),
|
|
1286
1281
|
total: Schema.Number,
|
|
1287
1282
|
page: Schema.Number,
|
|
@@ -1380,13 +1375,9 @@ var UpdatesGroup = class extends HttpApiGroup.make("updates").add(HttpApiEndpoin
|
|
|
1380
1375
|
}))).add(HttpApiEndpoint.get("list", "/api/updates").setUrlParams(Schema.Struct({
|
|
1381
1376
|
projectId: Id,
|
|
1382
1377
|
branchId: Schema.optional(Id),
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
total: Schema.Number,
|
|
1387
|
-
page: Schema.Number,
|
|
1388
|
-
limit: Schema.Number
|
|
1389
|
-
})).annotateContext(OpenApi.annotations({
|
|
1378
|
+
platform: Schema.optional(Platform),
|
|
1379
|
+
...CursorPaginationParams.fields
|
|
1380
|
+
})).addSuccess(cursorPageResult(Update)).annotateContext(OpenApi.annotations({
|
|
1390
1381
|
title: "List updates",
|
|
1391
1382
|
description: "List updates for a project, optionally filtered by branch"
|
|
1392
1383
|
}))).add(HttpApiEndpoint.del("deleteGroup")`/api/updates/${groupIdParam}`.addSuccess(DeleteUpdateResult).annotateContext(OpenApi.annotations({
|
|
@@ -1497,7 +1488,7 @@ const AuthStoreLive = Layer.effect(AuthStore, Effect.gen(function* () {
|
|
|
1497
1488
|
//#endregion
|
|
1498
1489
|
//#region src/services/config-store.ts
|
|
1499
1490
|
const DEFAULT_BASE_URL = "https://graph.better-update.dev";
|
|
1500
|
-
const
|
|
1491
|
+
const DEFAULT_WEB_URL = "https://better-update.dev";
|
|
1501
1492
|
var ConfigStoreParseError = class extends Data.TaggedError("ConfigStoreParseError") {};
|
|
1502
1493
|
const normalizeUrl = (value) => value.replace(/\/$/, "");
|
|
1503
1494
|
var ConfigStore = class extends Context.Tag("cli/ConfigStore")() {};
|
|
@@ -1521,12 +1512,12 @@ const ConfigStoreLive = Layer.effect(ConfigStore, Effect.gen(function* () {
|
|
|
1521
1512
|
if (typeof baseUrl === "string") return normalizeUrl(baseUrl);
|
|
1522
1513
|
return DEFAULT_BASE_URL;
|
|
1523
1514
|
}),
|
|
1524
|
-
|
|
1525
|
-
const envUrl = yield* runtime.getEnv("
|
|
1515
|
+
getWebUrl: Effect.gen(function* () {
|
|
1516
|
+
const envUrl = yield* runtime.getEnv("BETTER_UPDATE_WEB_URL");
|
|
1526
1517
|
if (envUrl) return normalizeUrl(envUrl);
|
|
1527
|
-
const
|
|
1528
|
-
if (typeof
|
|
1529
|
-
return
|
|
1518
|
+
const webUrl = (yield* readConfig)?.["webUrl"];
|
|
1519
|
+
if (typeof webUrl === "string") return normalizeUrl(webUrl);
|
|
1520
|
+
return DEFAULT_WEB_URL;
|
|
1530
1521
|
})
|
|
1531
1522
|
};
|
|
1532
1523
|
}));
|
|
@@ -1552,11 +1543,20 @@ const ApiClientLive = Layer.effect(ApiClientService, Effect.gen(function* () {
|
|
|
1552
1543
|
|
|
1553
1544
|
//#endregion
|
|
1554
1545
|
//#region ../../packages/safe-json/src/index.ts
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1546
|
+
const parseJsonResult = (text) => {
|
|
1547
|
+
try {
|
|
1548
|
+
return {
|
|
1549
|
+
ok: true,
|
|
1550
|
+
value: JSON.parse(text)
|
|
1551
|
+
};
|
|
1552
|
+
} catch {
|
|
1553
|
+
return { ok: false };
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
const safeJsonParse = (text) => {
|
|
1557
|
+
const result = parseJsonResult(text);
|
|
1558
|
+
return result.ok ? result.value : null;
|
|
1559
|
+
};
|
|
1560
1560
|
|
|
1561
1561
|
//#endregion
|
|
1562
1562
|
//#region src/services/apple-session-store.ts
|
|
@@ -1894,6 +1894,43 @@ const analyticsCommand = defineCommand({
|
|
|
1894
1894
|
}
|
|
1895
1895
|
});
|
|
1896
1896
|
|
|
1897
|
+
//#endregion
|
|
1898
|
+
//#region src/lib/cli-schemas.ts
|
|
1899
|
+
const RolloutPercentage = Schema.Number.pipe(Schema.int(), Schema.between(1, 100)).annotations({
|
|
1900
|
+
message: () => "Rollout percentage must be between 1 and 100.",
|
|
1901
|
+
identifier: "RolloutPercentage"
|
|
1902
|
+
});
|
|
1903
|
+
const KeyValuePair = Schema.Struct({
|
|
1904
|
+
key: Schema.String,
|
|
1905
|
+
value: Schema.String
|
|
1906
|
+
});
|
|
1907
|
+
const KeyValueFromString = Schema.transformOrFail(Schema.String, KeyValuePair, {
|
|
1908
|
+
strict: true,
|
|
1909
|
+
decode: (input, _options, ast) => {
|
|
1910
|
+
const eqIndex = input.indexOf("=");
|
|
1911
|
+
if (eqIndex <= 0) return ParseResult.fail(new ParseResult.Type(ast, input, "Invalid format. Use KEY=VALUE (e.g. API_KEY=abc123)"));
|
|
1912
|
+
return ParseResult.succeed({
|
|
1913
|
+
key: input.slice(0, eqIndex),
|
|
1914
|
+
value: input.slice(eqIndex + 1)
|
|
1915
|
+
});
|
|
1916
|
+
},
|
|
1917
|
+
encode: ({ key, value }) => ParseResult.succeed(`${key}=${value}`)
|
|
1918
|
+
});
|
|
1919
|
+
const parseRolloutPercentage = (raw, flag) => Effect.try({
|
|
1920
|
+
try: () => Schema.decodeUnknownSync(RolloutPercentage)(Number(raw)),
|
|
1921
|
+
catch: () => new InvalidArgumentError({ message: `--${flag} must be an integer between 1 and 100, got "${raw}".` })
|
|
1922
|
+
});
|
|
1923
|
+
const parseKeyValue = (raw) => Effect.try({
|
|
1924
|
+
try: () => Schema.decodeUnknownSync(KeyValueFromString)(raw),
|
|
1925
|
+
catch: () => new InvalidArgumentError({ message: "Invalid format. Use KEY=VALUE (e.g. API_KEY=abc123)" })
|
|
1926
|
+
});
|
|
1927
|
+
const parseLimit = (raw, defaultValue) => {
|
|
1928
|
+
if (raw === void 0) return Effect.succeed(defaultValue);
|
|
1929
|
+
const parsed = Number(raw);
|
|
1930
|
+
if (!Number.isInteger(parsed) || parsed < 1) return Effect.fail(new InvalidArgumentError({ message: `--limit must be a positive integer, got "${raw}".` }));
|
|
1931
|
+
return Effect.succeed(parsed);
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1897
1934
|
//#endregion
|
|
1898
1935
|
//#region src/commands/audit-logs/list.ts
|
|
1899
1936
|
const listCommand$7 = defineCommand({
|
|
@@ -1902,18 +1939,10 @@ const listCommand$7 = defineCommand({
|
|
|
1902
1939
|
description: "List audit log entries"
|
|
1903
1940
|
},
|
|
1904
1941
|
args: {
|
|
1905
|
-
action: {
|
|
1906
|
-
type: "string",
|
|
1907
|
-
description: "Filter by action"
|
|
1908
|
-
},
|
|
1909
1942
|
"resource-type": {
|
|
1910
1943
|
type: "string",
|
|
1911
1944
|
description: "Filter by resource type"
|
|
1912
1945
|
},
|
|
1913
|
-
"actor-id": {
|
|
1914
|
-
type: "string",
|
|
1915
|
-
description: "Filter by actor ID"
|
|
1916
|
-
},
|
|
1917
1946
|
from: {
|
|
1918
1947
|
type: "string",
|
|
1919
1948
|
description: "ISO timestamp lower bound"
|
|
@@ -1921,20 +1950,23 @@ const listCommand$7 = defineCommand({
|
|
|
1921
1950
|
to: {
|
|
1922
1951
|
type: "string",
|
|
1923
1952
|
description: "ISO timestamp upper bound"
|
|
1953
|
+
},
|
|
1954
|
+
limit: {
|
|
1955
|
+
type: "string",
|
|
1956
|
+
default: "100",
|
|
1957
|
+
description: "Max rows (default 100)"
|
|
1924
1958
|
}
|
|
1925
1959
|
},
|
|
1926
1960
|
run: async ({ args }) => runEffect(Effect.gen(function* () {
|
|
1961
|
+
const limit = yield* parseLimit(args.limit, 100);
|
|
1927
1962
|
const api = yield* apiClient;
|
|
1928
1963
|
const filters = {};
|
|
1929
|
-
if (args.action) filters["action"] = args.action;
|
|
1930
1964
|
if (args["resource-type"]) filters["resourceType"] = args["resource-type"];
|
|
1931
|
-
if (args["actor-id"]) filters["actorId"] = args["actor-id"];
|
|
1932
1965
|
if (args.from) filters["from"] = args.from;
|
|
1933
1966
|
if (args.to) filters["to"] = args.to;
|
|
1934
1967
|
const { items } = yield* api["audit-logs"].list({ urlParams: {
|
|
1935
1968
|
...filters,
|
|
1936
|
-
|
|
1937
|
-
limit: 100
|
|
1969
|
+
limit
|
|
1938
1970
|
} });
|
|
1939
1971
|
if (items.length === 0) {
|
|
1940
1972
|
yield* Console.log("No audit log entries found.");
|
|
@@ -1970,6 +2002,25 @@ const auditLogsCommand = defineCommand({
|
|
|
1970
2002
|
subCommands: { list: listCommand$7 }
|
|
1971
2003
|
});
|
|
1972
2004
|
|
|
2005
|
+
//#endregion
|
|
2006
|
+
//#region src/lib/drain-cursor.ts
|
|
2007
|
+
const PAGE_SIZE = 100;
|
|
2008
|
+
const MAX_PAGES = 100;
|
|
2009
|
+
/**
|
|
2010
|
+
* Drain a cursor-paginated list endpoint into a single array. CLI commands
|
|
2011
|
+
* that resolve names → IDs (e.g. branch lookup) need the full set, not a
|
|
2012
|
+
* page slice.
|
|
2013
|
+
*/
|
|
2014
|
+
const drainCursor = (fetchPage) => {
|
|
2015
|
+
const loop = (accumulator, cursor, pages) => fetchPage(cursor).pipe(Effect.flatMap((page) => {
|
|
2016
|
+
const next = [...accumulator, ...page.items];
|
|
2017
|
+
const { nextCursor } = page;
|
|
2018
|
+
const reachedLimit = pages + 1 >= MAX_PAGES || next.length >= PAGE_SIZE * MAX_PAGES;
|
|
2019
|
+
return nextCursor === null || reachedLimit ? Effect.succeed(next) : loop(next, nextCursor, pages + 1);
|
|
2020
|
+
}));
|
|
2021
|
+
return loop([], void 0, 0);
|
|
2022
|
+
};
|
|
2023
|
+
|
|
1973
2024
|
//#endregion
|
|
1974
2025
|
//#region src/commands/branches.ts
|
|
1975
2026
|
const listCommand$6 = defineCommand({
|
|
@@ -1979,11 +2030,12 @@ const listCommand$6 = defineCommand({
|
|
|
1979
2030
|
},
|
|
1980
2031
|
run: async () => runEffect(Effect.gen(function* () {
|
|
1981
2032
|
const projectId = yield* readProjectId;
|
|
1982
|
-
const
|
|
2033
|
+
const api = yield* apiClient;
|
|
2034
|
+
const items = yield* drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
1983
2035
|
projectId,
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
} });
|
|
2036
|
+
limit: 100,
|
|
2037
|
+
...cursor ? { cursor } : {}
|
|
2038
|
+
} }));
|
|
1987
2039
|
if (items.length === 0) {
|
|
1988
2040
|
yield* Console.log("No branches found.");
|
|
1989
2041
|
return;
|
|
@@ -2166,14 +2218,25 @@ const findAndroidArtifact = ({ projectRoot, format, flavor, buildType, minMtimeM
|
|
|
2166
2218
|
//#endregion
|
|
2167
2219
|
//#region ../../packages/encoding/src/index.ts
|
|
2168
2220
|
const asUint8Array = (data) => data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
2169
|
-
const toBinaryString = (data) =>
|
|
2221
|
+
const toBinaryString = (data) => Array.from(asUint8Array(data), (byte) => String.fromCodePoint(byte)).join("");
|
|
2222
|
+
const padBase64 = (value) => value.padEnd(value.length + (4 - value.length % 4) % 4, "=");
|
|
2223
|
+
const BASE64_PATTERN = /^[A-Za-z0-9+/]*={0,2}$/u;
|
|
2224
|
+
const HEX_PATTERN = /^(?:[0-9A-Fa-f]{2})*$/u;
|
|
2225
|
+
const normalizeBase64 = (value) => {
|
|
2226
|
+
const compact = value.replaceAll(/\s+/gu, "");
|
|
2227
|
+
if (!BASE64_PATTERN.test(compact) || compact.length % 4 === 1) throw new RangeError("Invalid base64 string");
|
|
2228
|
+
return padBase64(compact);
|
|
2229
|
+
};
|
|
2170
2230
|
const toBase64 = (data) => btoa(toBinaryString(data));
|
|
2171
2231
|
const fromBase64 = (str) => {
|
|
2172
|
-
const binary = atob(str);
|
|
2173
|
-
return
|
|
2232
|
+
const binary = atob(normalizeBase64(str));
|
|
2233
|
+
return Uint8Array.from(binary, (char) => char.codePointAt(0) ?? 0);
|
|
2174
2234
|
};
|
|
2175
2235
|
const toBase64Url = (data) => toBase64(data).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
2176
|
-
const fromHex = (hex) =>
|
|
2236
|
+
const fromHex = (hex) => {
|
|
2237
|
+
if (!HEX_PATTERN.test(hex)) throw new RangeError("Invalid hex string");
|
|
2238
|
+
return Uint8Array.from(hex.match(/.{2}/gu) ?? [], (byte) => Number.parseInt(byte, 16));
|
|
2239
|
+
};
|
|
2177
2240
|
|
|
2178
2241
|
//#endregion
|
|
2179
2242
|
//#region src/lib/credentials-downloader.ts
|
|
@@ -2223,9 +2286,9 @@ const downloadIosCredentials = (api, options) => Effect.gen(function* () {
|
|
|
2223
2286
|
message: "Server returned non-iOS credentials for an iOS build request",
|
|
2224
2287
|
hint: bindHint
|
|
2225
2288
|
}));
|
|
2226
|
-
const p12Path =
|
|
2289
|
+
const p12Path = path.join(options.tempDir, "signing.p12");
|
|
2227
2290
|
const profileFilename = `${resolved.provisioningProfile.uuid ?? "profile"}.mobileprovision`;
|
|
2228
|
-
const profilePath =
|
|
2291
|
+
const profilePath = path.join(options.tempDir, profileFilename);
|
|
2229
2292
|
yield* fs.writeFile(p12Path, fromBase64(resolved.distributionCertificate.p12Base64));
|
|
2230
2293
|
yield* fs.writeFile(profilePath, fromBase64(resolved.provisioningProfile.mobileprovisionBase64));
|
|
2231
2294
|
return {
|
|
@@ -2249,7 +2312,7 @@ const downloadAndroidCredentials = (api, options) => Effect.gen(function* () {
|
|
|
2249
2312
|
message: "Server returned non-Android credentials for an Android build request",
|
|
2250
2313
|
hint: androidBindHint
|
|
2251
2314
|
}));
|
|
2252
|
-
const keystorePath =
|
|
2315
|
+
const keystorePath = path.join(options.tempDir, "upload.keystore");
|
|
2253
2316
|
yield* fs.writeFile(keystorePath, fromBase64(resolved.keystore.keystoreBase64));
|
|
2254
2317
|
return {
|
|
2255
2318
|
keystorePath,
|
|
@@ -3283,23 +3346,23 @@ const compatibilityMatrixCommand = defineCommand({
|
|
|
3283
3346
|
run: async () => runEffect(Effect.gen(function* () {
|
|
3284
3347
|
const projectId = yield* readProjectId;
|
|
3285
3348
|
const result = yield* (yield* apiClient).builds.compatibilityMatrix({ urlParams: { projectId } });
|
|
3286
|
-
|
|
3349
|
+
const matrixKeys = Object.keys(result.channelStatusByKey);
|
|
3350
|
+
if (matrixKeys.length === 0 && result.missingRuntimeVersions.length === 0) {
|
|
3287
3351
|
yield* Console.log("No compatibility data found.");
|
|
3288
3352
|
return;
|
|
3289
3353
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3354
|
+
const channelLookup = Object.fromEntries(result.channels.map((channel) => [channel.channelId, channel.channelName]));
|
|
3355
|
+
if (matrixKeys.length > 0) {
|
|
3356
|
+
yield* Console.log("Channel Status by (Platform / Runtime Version):");
|
|
3292
3357
|
yield* printTable([
|
|
3293
|
-
"
|
|
3294
|
-
"
|
|
3295
|
-
"
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
row.channels.map((channel) => channel.channelName).join(", ") || "-"
|
|
3302
|
-
]));
|
|
3358
|
+
"Platform / Runtime",
|
|
3359
|
+
"Channel",
|
|
3360
|
+
"Updates"
|
|
3361
|
+
], matrixKeys.flatMap((key) => (result.channelStatusByKey[key] ?? []).filter((entry) => entry.updateCount > 0).map((entry) => [
|
|
3362
|
+
key,
|
|
3363
|
+
channelLookup[entry.channelId] ?? entry.channelId,
|
|
3364
|
+
String(entry.updateCount)
|
|
3365
|
+
])));
|
|
3303
3366
|
}
|
|
3304
3367
|
if (result.missingRuntimeVersions.length > 0) {
|
|
3305
3368
|
yield* Console.log("\nMissing Runtime Versions:");
|
|
@@ -3389,43 +3452,6 @@ const installLinkCommand = defineCommand({
|
|
|
3389
3452
|
}))
|
|
3390
3453
|
});
|
|
3391
3454
|
|
|
3392
|
-
//#endregion
|
|
3393
|
-
//#region src/lib/cli-schemas.ts
|
|
3394
|
-
const RolloutPercentage = Schema.Number.pipe(Schema.int(), Schema.between(1, 100)).annotations({
|
|
3395
|
-
message: () => "Rollout percentage must be between 1 and 100.",
|
|
3396
|
-
identifier: "RolloutPercentage"
|
|
3397
|
-
});
|
|
3398
|
-
const KeyValuePair = Schema.Struct({
|
|
3399
|
-
key: Schema.String,
|
|
3400
|
-
value: Schema.String
|
|
3401
|
-
});
|
|
3402
|
-
const KeyValueFromString = Schema.transformOrFail(Schema.String, KeyValuePair, {
|
|
3403
|
-
strict: true,
|
|
3404
|
-
decode: (input, _options, ast) => {
|
|
3405
|
-
const eqIndex = input.indexOf("=");
|
|
3406
|
-
if (eqIndex <= 0) return ParseResult.fail(new ParseResult.Type(ast, input, "Invalid format. Use KEY=VALUE (e.g. API_KEY=abc123)"));
|
|
3407
|
-
return ParseResult.succeed({
|
|
3408
|
-
key: input.slice(0, eqIndex),
|
|
3409
|
-
value: input.slice(eqIndex + 1)
|
|
3410
|
-
});
|
|
3411
|
-
},
|
|
3412
|
-
encode: ({ key, value }) => ParseResult.succeed(`${key}=${value}`)
|
|
3413
|
-
});
|
|
3414
|
-
const parseRolloutPercentage = (raw, flag) => Effect.try({
|
|
3415
|
-
try: () => Schema.decodeUnknownSync(RolloutPercentage)(Number(raw)),
|
|
3416
|
-
catch: () => new InvalidArgumentError({ message: `--${flag} must be an integer between 1 and 100, got "${raw}".` })
|
|
3417
|
-
});
|
|
3418
|
-
const parseKeyValue = (raw) => Effect.try({
|
|
3419
|
-
try: () => Schema.decodeUnknownSync(KeyValueFromString)(raw),
|
|
3420
|
-
catch: () => new InvalidArgumentError({ message: "Invalid format. Use KEY=VALUE (e.g. API_KEY=abc123)" })
|
|
3421
|
-
});
|
|
3422
|
-
const parseLimit = (raw, defaultValue) => {
|
|
3423
|
-
if (raw === void 0) return Effect.succeed(defaultValue);
|
|
3424
|
-
const parsed = Number(raw);
|
|
3425
|
-
if (!Number.isInteger(parsed) || parsed < 1) return Effect.fail(new InvalidArgumentError({ message: `--limit must be a positive integer, got "${raw}".` }));
|
|
3426
|
-
return Effect.succeed(parsed);
|
|
3427
|
-
};
|
|
3428
|
-
|
|
3429
3455
|
//#endregion
|
|
3430
3456
|
//#region src/commands/builds/list.ts
|
|
3431
3457
|
const listCommand$5 = defineCommand({
|
|
@@ -3453,7 +3479,6 @@ const listCommand$5 = defineCommand({
|
|
|
3453
3479
|
const { items } = yield* api.builds.list({ urlParams: {
|
|
3454
3480
|
projectId,
|
|
3455
3481
|
...platformFilter,
|
|
3456
|
-
page: 1,
|
|
3457
3482
|
limit
|
|
3458
3483
|
} });
|
|
3459
3484
|
yield* printTable([
|
|
@@ -3660,13 +3685,12 @@ const createCommand$2 = defineCommand({
|
|
|
3660
3685
|
run: async ({ args }) => runEffect(Effect.gen(function* () {
|
|
3661
3686
|
const projectId = yield* readProjectId;
|
|
3662
3687
|
const api = yield* apiClient;
|
|
3663
|
-
const { items: branches } = yield* api.branches.list({ urlParams: {
|
|
3664
|
-
projectId,
|
|
3665
|
-
page: 1,
|
|
3666
|
-
limit: 1e3
|
|
3667
|
-
} });
|
|
3668
3688
|
const branchId = yield* resolveNamedResourceId$1({
|
|
3669
|
-
items: branches
|
|
3689
|
+
items: yield* drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
3690
|
+
projectId,
|
|
3691
|
+
limit: 100,
|
|
3692
|
+
...cursor ? { cursor } : {}
|
|
3693
|
+
} })),
|
|
3670
3694
|
kind: "Branch",
|
|
3671
3695
|
name: args.branch
|
|
3672
3696
|
});
|
|
@@ -3712,15 +3736,15 @@ const listCommand$4 = defineCommand({
|
|
|
3712
3736
|
run: async () => runEffect(Effect.gen(function* () {
|
|
3713
3737
|
const projectId = yield* readProjectId;
|
|
3714
3738
|
const api = yield* apiClient;
|
|
3715
|
-
const [
|
|
3739
|
+
const [items, branches] = yield* Effect.all([drainCursor((cursor) => api.channels.list({ urlParams: {
|
|
3716
3740
|
projectId,
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
} }), api.branches.list({ urlParams: {
|
|
3741
|
+
limit: 100,
|
|
3742
|
+
...cursor ? { cursor } : {}
|
|
3743
|
+
} })), drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
3720
3744
|
projectId,
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
} })]);
|
|
3745
|
+
limit: 100,
|
|
3746
|
+
...cursor ? { cursor } : {}
|
|
3747
|
+
} }))]);
|
|
3724
3748
|
if (items.length === 0) {
|
|
3725
3749
|
yield* Console.log("No channels found.");
|
|
3726
3750
|
return;
|
|
@@ -3826,13 +3850,12 @@ const createCommand$1 = defineCommand({
|
|
|
3826
3850
|
const percentage = yield* parseRolloutPercentage(args.percentage, "percentage");
|
|
3827
3851
|
const projectId = yield* readProjectId;
|
|
3828
3852
|
const api = yield* apiClient;
|
|
3829
|
-
const { items: branches } = yield* api.branches.list({ urlParams: {
|
|
3830
|
-
projectId,
|
|
3831
|
-
page: 1,
|
|
3832
|
-
limit: 1e3
|
|
3833
|
-
} });
|
|
3834
3853
|
const newBranchId = yield* resolveNamedResourceId$1({
|
|
3835
|
-
items: branches
|
|
3854
|
+
items: yield* drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
3855
|
+
projectId,
|
|
3856
|
+
limit: 100,
|
|
3857
|
+
...cursor ? { cursor } : {}
|
|
3858
|
+
} })),
|
|
3836
3859
|
kind: "Branch",
|
|
3837
3860
|
name: args.branch
|
|
3838
3861
|
});
|
|
@@ -3931,13 +3954,12 @@ const updateCommand$1 = defineCommand({
|
|
|
3931
3954
|
run: async ({ args }) => runEffect(Effect.gen(function* () {
|
|
3932
3955
|
const projectId = yield* readProjectId;
|
|
3933
3956
|
const api = yield* apiClient;
|
|
3934
|
-
const { items: branches } = yield* api.branches.list({ urlParams: {
|
|
3935
|
-
projectId,
|
|
3936
|
-
page: 1,
|
|
3937
|
-
limit: 1e3
|
|
3938
|
-
} });
|
|
3939
3957
|
const branchId = yield* resolveNamedResourceId$1({
|
|
3940
|
-
items: branches
|
|
3958
|
+
items: yield* drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
3959
|
+
projectId,
|
|
3960
|
+
limit: 100,
|
|
3961
|
+
...cursor ? { cursor } : {}
|
|
3962
|
+
} })),
|
|
3941
3963
|
kind: "Branch",
|
|
3942
3964
|
name: args.branch
|
|
3943
3965
|
});
|
|
@@ -4890,9 +4912,9 @@ const openBrowser = (url) => Effect.gen(function* () {
|
|
|
4890
4912
|
const browserLogin = Effect.scoped(Effect.gen(function* () {
|
|
4891
4913
|
const configStore = yield* ConfigStore;
|
|
4892
4914
|
const authStore = yield* AuthStore;
|
|
4893
|
-
const
|
|
4915
|
+
const webUrl = yield* configStore.getWebUrl;
|
|
4894
4916
|
const loginServer = yield* Effect.acquireRelease(Effect.sync(createBrowserLoginServer), (server) => Effect.sync(server.stop));
|
|
4895
|
-
const loginUrl = `${
|
|
4917
|
+
const loginUrl = `${webUrl}/auth/cli-login?callbackUrl=${encodeURIComponent(loginServer.callbackUrl)}`;
|
|
4896
4918
|
yield* Console.log("Opening browser for better-update login...");
|
|
4897
4919
|
yield* Console.log("");
|
|
4898
4920
|
yield* openBrowser(loginUrl);
|
|
@@ -4950,12 +4972,37 @@ const logoutCommand = defineCommand({
|
|
|
4950
4972
|
const listCommand$1 = defineCommand({
|
|
4951
4973
|
meta: {
|
|
4952
4974
|
name: "list",
|
|
4953
|
-
description: "List
|
|
4975
|
+
description: "List projects (most recently active first)"
|
|
4954
4976
|
},
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4977
|
+
args: {
|
|
4978
|
+
query: {
|
|
4979
|
+
type: "string",
|
|
4980
|
+
description: "Substring search on name or slug"
|
|
4981
|
+
},
|
|
4982
|
+
sort: {
|
|
4983
|
+
type: "string",
|
|
4984
|
+
description: "Sort key: lastActivityAt (default) or name",
|
|
4985
|
+
default: "lastActivityAt"
|
|
4986
|
+
},
|
|
4987
|
+
limit: {
|
|
4988
|
+
type: "string",
|
|
4989
|
+
description: "Page size (default 50, max 100)",
|
|
4990
|
+
default: "50"
|
|
4991
|
+
},
|
|
4992
|
+
page: {
|
|
4993
|
+
type: "string",
|
|
4994
|
+
description: "1-based page number",
|
|
4995
|
+
default: "1"
|
|
4996
|
+
}
|
|
4997
|
+
},
|
|
4998
|
+
run: async ({ args }) => runEffect(Effect.gen(function* () {
|
|
4999
|
+
const api = yield* apiClient;
|
|
5000
|
+
const sort = args.sort === "name" ? "name" : "lastActivityAt";
|
|
5001
|
+
const { items, total, page } = yield* api.projects.list({ urlParams: {
|
|
5002
|
+
page: Number(args.page),
|
|
5003
|
+
limit: Number(args.limit),
|
|
5004
|
+
sort,
|
|
5005
|
+
...args.query ? { query: args.query } : {}
|
|
4959
5006
|
} });
|
|
4960
5007
|
if (items.length === 0) {
|
|
4961
5008
|
yield* Console.log("No projects found.");
|
|
@@ -4965,13 +5012,14 @@ const listCommand$1 = defineCommand({
|
|
|
4965
5012
|
"ID",
|
|
4966
5013
|
"Name",
|
|
4967
5014
|
"Slug",
|
|
4968
|
-
"
|
|
5015
|
+
"Last activity"
|
|
4969
5016
|
], items.map((project) => [
|
|
4970
5017
|
project.id,
|
|
4971
5018
|
project.name,
|
|
4972
5019
|
project.slug,
|
|
4973
|
-
project.
|
|
5020
|
+
project.lastActivityAt
|
|
4974
5021
|
]));
|
|
5022
|
+
yield* Console.log(`Page ${page} · ${items.length} of ${total} project(s)`);
|
|
4975
5023
|
}))
|
|
4976
5024
|
});
|
|
4977
5025
|
const createCommand = defineCommand({
|
|
@@ -5114,7 +5162,8 @@ const statusCommand = defineCommand({
|
|
|
5114
5162
|
yield* Console.log("");
|
|
5115
5163
|
yield* Console.log("Builds");
|
|
5116
5164
|
yield* Console.log("------");
|
|
5117
|
-
|
|
5165
|
+
const moreSuffix = builds.nextCursor === null ? "" : "+";
|
|
5166
|
+
yield* printKeyValue([["Recent", `${String(builds.items.length)}${moreSuffix}`]]);
|
|
5118
5167
|
}))
|
|
5119
5168
|
});
|
|
5120
5169
|
|
|
@@ -5170,11 +5219,11 @@ const listCommand = defineCommand({
|
|
|
5170
5219
|
const limit = yield* parseLimit(args.limit, 20);
|
|
5171
5220
|
const projectId = yield* readProjectId;
|
|
5172
5221
|
const api = yield* apiClient;
|
|
5173
|
-
const
|
|
5222
|
+
const branches = yield* drainCursor((cursor) => api.branches.list({ urlParams: {
|
|
5174
5223
|
projectId,
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
} });
|
|
5224
|
+
limit: 100,
|
|
5225
|
+
...cursor ? { cursor } : {}
|
|
5226
|
+
} }));
|
|
5178
5227
|
const branchId = args.branch ? yield* resolveNamedResourceId({
|
|
5179
5228
|
items: branches,
|
|
5180
5229
|
kind: "Branch",
|
|
@@ -5183,7 +5232,6 @@ const listCommand = defineCommand({
|
|
|
5183
5232
|
const { items } = yield* api.updates.list({ urlParams: {
|
|
5184
5233
|
projectId,
|
|
5185
5234
|
...branchId === void 0 ? {} : { branchId },
|
|
5186
|
-
page: 1,
|
|
5187
5235
|
limit
|
|
5188
5236
|
} });
|
|
5189
5237
|
if (items.length === 0) {
|
|
@@ -5963,7 +6011,7 @@ const updateCommand = defineCommand({
|
|
|
5963
6011
|
await runMain(defineCommand({
|
|
5964
6012
|
meta: {
|
|
5965
6013
|
name: "better-update",
|
|
5966
|
-
version
|
|
6014
|
+
version,
|
|
5967
6015
|
description: "Publish OTA updates and builds for Expo apps"
|
|
5968
6016
|
},
|
|
5969
6017
|
subCommands: {
|