@gpc-cli/core 0.9.57 → 0.9.59
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/README.md +4 -3
- package/dist/{chunk-QEM7QCBD.js → chunk-IZKB6GBS.js} +50 -29
- package/dist/chunk-IZKB6GBS.js.map +1 -0
- package/dist/index.d.ts +41 -2
- package/dist/index.js +254 -37
- package/dist/index.js.map +1 -1
- package/dist/{releases-LHYBPIUI.js → releases-VFDJ6IX2.js} +2 -2
- package/package.json +3 -3
- package/dist/chunk-QEM7QCBD.js.map +0 -1
- /package/dist/{releases-LHYBPIUI.js.map → releases-VFDJ6IX2.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
GpcError,
|
|
5
5
|
NetworkError,
|
|
6
6
|
applyReleaseNotes,
|
|
7
|
+
commitWithRescue,
|
|
7
8
|
createTrack,
|
|
8
9
|
diffReleases,
|
|
9
10
|
fetchReleaseNotes,
|
|
@@ -14,9 +15,10 @@ import {
|
|
|
14
15
|
updateTrackConfig,
|
|
15
16
|
uploadExternallyHosted,
|
|
16
17
|
uploadRelease,
|
|
18
|
+
validateAndCommit,
|
|
17
19
|
validateUploadFile,
|
|
18
20
|
waitForBundleProcessing
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-IZKB6GBS.js";
|
|
20
22
|
|
|
21
23
|
// src/output.ts
|
|
22
24
|
import process2 from "process";
|
|
@@ -47,6 +49,10 @@ function formatOutput(data, format, redact = true) {
|
|
|
47
49
|
return formatYaml(safe);
|
|
48
50
|
case "markdown":
|
|
49
51
|
return formatMarkdown(safe);
|
|
52
|
+
case "csv":
|
|
53
|
+
return formatCsv(safe);
|
|
54
|
+
case "tsv":
|
|
55
|
+
return formatTsv(safe);
|
|
50
56
|
case "table":
|
|
51
57
|
return formatTable(safe);
|
|
52
58
|
case "junit":
|
|
@@ -221,6 +227,37 @@ function formatMarkdown(data) {
|
|
|
221
227
|
${separator}
|
|
222
228
|
${body}`;
|
|
223
229
|
}
|
|
230
|
+
function escapeCsvField(val) {
|
|
231
|
+
if (val.includes(",") || val.includes('"') || val.includes("\n") || val.includes("\r")) {
|
|
232
|
+
return `"${val.replace(/"/g, '""')}"`;
|
|
233
|
+
}
|
|
234
|
+
return val;
|
|
235
|
+
}
|
|
236
|
+
function formatCsv(data) {
|
|
237
|
+
const rows = toRows(data);
|
|
238
|
+
if (rows.length === 0) return "";
|
|
239
|
+
const firstRow = rows[0];
|
|
240
|
+
if (!firstRow) return "";
|
|
241
|
+
const keys = Object.keys(firstRow);
|
|
242
|
+
if (keys.length === 0) return "";
|
|
243
|
+
const header = keys.map(escapeCsvField).join(",");
|
|
244
|
+
const body = rows.map((row) => keys.map((key) => escapeCsvField(cellValue(row[key]))).join(",")).join("\n");
|
|
245
|
+
return `${header}
|
|
246
|
+
${body}`;
|
|
247
|
+
}
|
|
248
|
+
function formatTsv(data) {
|
|
249
|
+
const rows = toRows(data);
|
|
250
|
+
if (rows.length === 0) return "";
|
|
251
|
+
const firstRow = rows[0];
|
|
252
|
+
if (!firstRow) return "";
|
|
253
|
+
const keys = Object.keys(firstRow);
|
|
254
|
+
if (keys.length === 0) return "";
|
|
255
|
+
const escape = (val) => val.replace(/\t/g, "\\t").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
256
|
+
const header = keys.join(" ");
|
|
257
|
+
const body = rows.map((row) => keys.map((key) => escape(cellValue(row[key]))).join(" ")).join("\n");
|
|
258
|
+
return `${header}
|
|
259
|
+
${body}`;
|
|
260
|
+
}
|
|
224
261
|
function toRows(data) {
|
|
225
262
|
if (Array.isArray(data)) {
|
|
226
263
|
return data.filter(
|
|
@@ -880,10 +917,7 @@ async function updateListing(client, packageName, language, data, commitOptions)
|
|
|
880
917
|
const edit = await client.edits.insert(packageName);
|
|
881
918
|
try {
|
|
882
919
|
const listing = await client.listings.patch(packageName, edit.id, language, data);
|
|
883
|
-
|
|
884
|
-
await client.edits.validate(packageName, edit.id);
|
|
885
|
-
}
|
|
886
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
920
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
887
921
|
return listing;
|
|
888
922
|
} catch (error) {
|
|
889
923
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
@@ -896,10 +930,7 @@ async function deleteListing(client, packageName, language, commitOptions) {
|
|
|
896
930
|
const edit = await client.edits.insert(packageName);
|
|
897
931
|
try {
|
|
898
932
|
await client.listings.delete(packageName, edit.id, language);
|
|
899
|
-
|
|
900
|
-
await client.edits.validate(packageName, edit.id);
|
|
901
|
-
}
|
|
902
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
933
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
903
934
|
} catch (error) {
|
|
904
935
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
905
936
|
});
|
|
@@ -1022,10 +1053,7 @@ ${details}`,
|
|
|
1022
1053
|
const { language, ...data } = listing;
|
|
1023
1054
|
await client.listings.update(packageName, edit.id, language, data);
|
|
1024
1055
|
}
|
|
1025
|
-
|
|
1026
|
-
await client.edits.validate(packageName, edit.id);
|
|
1027
|
-
}
|
|
1028
|
-
await client.edits.commit(packageName, edit.id, options?.commitOptions);
|
|
1056
|
+
await validateAndCommit(client, packageName, edit.id, options?.commitOptions);
|
|
1029
1057
|
return {
|
|
1030
1058
|
updated: localListings.length,
|
|
1031
1059
|
languages: localListings.map((l) => l.language)
|
|
@@ -1066,10 +1094,7 @@ async function uploadImage(client, packageName, language, imageType, filePath, c
|
|
|
1066
1094
|
const edit = await client.edits.insert(packageName);
|
|
1067
1095
|
try {
|
|
1068
1096
|
const image = await client.images.upload(packageName, edit.id, language, imageType, filePath);
|
|
1069
|
-
|
|
1070
|
-
await client.edits.validate(packageName, edit.id);
|
|
1071
|
-
}
|
|
1072
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
1097
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
1073
1098
|
return image;
|
|
1074
1099
|
} catch (error) {
|
|
1075
1100
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
@@ -1082,10 +1107,7 @@ async function deleteImage(client, packageName, language, imageType, imageId, co
|
|
|
1082
1107
|
const edit = await client.edits.insert(packageName);
|
|
1083
1108
|
try {
|
|
1084
1109
|
await client.images.delete(packageName, edit.id, language, imageType, imageId);
|
|
1085
|
-
|
|
1086
|
-
await client.edits.validate(packageName, edit.id);
|
|
1087
|
-
}
|
|
1088
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
1110
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
1089
1111
|
} catch (error) {
|
|
1090
1112
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
1091
1113
|
});
|
|
@@ -1129,7 +1151,7 @@ var ALL_IMAGE_TYPES = [
|
|
|
1129
1151
|
];
|
|
1130
1152
|
async function exportImages(client, packageName, dir, options) {
|
|
1131
1153
|
const { mkdir: mkdir8, writeFile: writeFile9 } = await import("fs/promises");
|
|
1132
|
-
const { join:
|
|
1154
|
+
const { join: join13 } = await import("path");
|
|
1133
1155
|
const edit = await client.edits.insert(packageName);
|
|
1134
1156
|
try {
|
|
1135
1157
|
let languages;
|
|
@@ -1160,7 +1182,7 @@ async function exportImages(client, packageName, dir, options) {
|
|
|
1160
1182
|
const batch = tasks.slice(i, i + concurrency);
|
|
1161
1183
|
const results = await Promise.all(
|
|
1162
1184
|
batch.map(async (task) => {
|
|
1163
|
-
const dirPath =
|
|
1185
|
+
const dirPath = join13(dir, task.language, task.imageType);
|
|
1164
1186
|
await mkdir8(dirPath, { recursive: true });
|
|
1165
1187
|
const response = await fetch(task.url);
|
|
1166
1188
|
if (!response.ok) {
|
|
@@ -1172,7 +1194,7 @@ async function exportImages(client, packageName, dir, options) {
|
|
|
1172
1194
|
);
|
|
1173
1195
|
}
|
|
1174
1196
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
1175
|
-
const filePath =
|
|
1197
|
+
const filePath = join13(dirPath, `${task.index}.png`);
|
|
1176
1198
|
await writeFile9(filePath, buffer);
|
|
1177
1199
|
return buffer.length;
|
|
1178
1200
|
})
|
|
@@ -1198,10 +1220,7 @@ async function updateAppDetails(client, packageName, details, commitOptions) {
|
|
|
1198
1220
|
const edit = await client.edits.insert(packageName);
|
|
1199
1221
|
try {
|
|
1200
1222
|
const result = await client.details.patch(packageName, edit.id, details);
|
|
1201
|
-
|
|
1202
|
-
await client.edits.validate(packageName, edit.id);
|
|
1203
|
-
}
|
|
1204
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
1223
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
1205
1224
|
return result;
|
|
1206
1225
|
} catch (error) {
|
|
1207
1226
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
@@ -1679,6 +1698,7 @@ async function publish(client, packageName, filePath, options) {
|
|
|
1679
1698
|
mappingFile: options.mappingFile,
|
|
1680
1699
|
mappingFileType: options.mappingFileType,
|
|
1681
1700
|
deviceTierConfigId: options.deviceTierConfigId,
|
|
1701
|
+
validateOnly: options.validateOnly,
|
|
1682
1702
|
commitOptions: options.commitOptions
|
|
1683
1703
|
});
|
|
1684
1704
|
return { validation, upload };
|
|
@@ -3202,7 +3222,7 @@ async function handleBreach(event, config, client) {
|
|
|
3202
3222
|
}
|
|
3203
3223
|
case "halt": {
|
|
3204
3224
|
try {
|
|
3205
|
-
const { updateRollout: updateRollout2 } = await import("./releases-
|
|
3225
|
+
const { updateRollout: updateRollout2 } = await import("./releases-VFDJ6IX2.js");
|
|
3206
3226
|
await updateRollout2(client, config.packageName, config.track, "halt");
|
|
3207
3227
|
halted = true;
|
|
3208
3228
|
} catch {
|
|
@@ -3786,10 +3806,7 @@ async function addTesters(client, packageName, track, groupEmails, commitOptions
|
|
|
3786
3806
|
const updated = await client.testers.update(packageName, edit.id, track, {
|
|
3787
3807
|
googleGroups: [...existing]
|
|
3788
3808
|
});
|
|
3789
|
-
|
|
3790
|
-
await client.edits.validate(packageName, edit.id);
|
|
3791
|
-
}
|
|
3792
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
3809
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
3793
3810
|
return updated;
|
|
3794
3811
|
} catch (error) {
|
|
3795
3812
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
@@ -3806,10 +3823,7 @@ async function removeTesters(client, packageName, track, groupEmails, commitOpti
|
|
|
3806
3823
|
const updated = await client.testers.update(packageName, edit.id, track, {
|
|
3807
3824
|
googleGroups: filtered
|
|
3808
3825
|
});
|
|
3809
|
-
|
|
3810
|
-
await client.edits.validate(packageName, edit.id);
|
|
3811
|
-
}
|
|
3812
|
-
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
3826
|
+
await validateAndCommit(client, packageName, edit.id, commitOptions);
|
|
3813
3827
|
return updated;
|
|
3814
3828
|
} catch (error) {
|
|
3815
3829
|
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
@@ -8335,6 +8349,202 @@ function compareFingerprints(a, b) {
|
|
|
8335
8349
|
return normalizeFingerprint(a) === normalizeFingerprint(b);
|
|
8336
8350
|
}
|
|
8337
8351
|
|
|
8352
|
+
// src/utils/hash.ts
|
|
8353
|
+
import { createHash } from "crypto";
|
|
8354
|
+
import { stat as stat9 } from "fs/promises";
|
|
8355
|
+
async function sha256File(filePath) {
|
|
8356
|
+
const hash = createHash("sha256");
|
|
8357
|
+
const { size } = await stat9(filePath);
|
|
8358
|
+
if (size === 0) return hash.digest("hex");
|
|
8359
|
+
const { createReadStream } = await import("fs");
|
|
8360
|
+
const stream = createReadStream(filePath);
|
|
8361
|
+
await new Promise((resolve2, reject) => {
|
|
8362
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
8363
|
+
stream.on("end", resolve2);
|
|
8364
|
+
stream.on("error", reject);
|
|
8365
|
+
});
|
|
8366
|
+
return hash.digest("hex");
|
|
8367
|
+
}
|
|
8368
|
+
|
|
8369
|
+
// src/commands/image-sync.ts
|
|
8370
|
+
import { readdir as readdir7 } from "fs/promises";
|
|
8371
|
+
import { join as join12, extname as extname5 } from "path";
|
|
8372
|
+
import { PlayApiError } from "@gpc-cli/api";
|
|
8373
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg"]);
|
|
8374
|
+
var ALL_IMAGE_TYPES2 = [
|
|
8375
|
+
"icon",
|
|
8376
|
+
"featureGraphic",
|
|
8377
|
+
"tvBanner",
|
|
8378
|
+
"phoneScreenshots",
|
|
8379
|
+
"sevenInchScreenshots",
|
|
8380
|
+
"tenInchScreenshots",
|
|
8381
|
+
"tvScreenshots",
|
|
8382
|
+
"wearScreenshots"
|
|
8383
|
+
];
|
|
8384
|
+
async function scanLocalImages(dir) {
|
|
8385
|
+
try {
|
|
8386
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
8387
|
+
return entries.filter((e) => e.isFile() && IMAGE_EXTENSIONS.has(extname5(e.name).toLowerCase())).map((e) => e.name).sort();
|
|
8388
|
+
} catch {
|
|
8389
|
+
return [];
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
async function scanLanguages(dir) {
|
|
8393
|
+
try {
|
|
8394
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
8395
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
8396
|
+
} catch {
|
|
8397
|
+
return [];
|
|
8398
|
+
}
|
|
8399
|
+
}
|
|
8400
|
+
async function syncImages(client, packageName, dir, options) {
|
|
8401
|
+
const details = [];
|
|
8402
|
+
let uploaded = 0;
|
|
8403
|
+
let skipped = 0;
|
|
8404
|
+
let deleted = 0;
|
|
8405
|
+
const languages = options?.lang ? [options.lang] : await scanLanguages(dir);
|
|
8406
|
+
if (languages.length === 0) {
|
|
8407
|
+
throw new GpcError(
|
|
8408
|
+
`No language directories found in "${dir}"`,
|
|
8409
|
+
"IMAGE_SYNC_EMPTY",
|
|
8410
|
+
1,
|
|
8411
|
+
"The directory should contain subdirectories named by language code (e.g., en-US/) with image type subdirectories inside."
|
|
8412
|
+
);
|
|
8413
|
+
}
|
|
8414
|
+
const imageTypes = options?.type ? [options.type] : ALL_IMAGE_TYPES2;
|
|
8415
|
+
const edit = await client.edits.insert(packageName);
|
|
8416
|
+
try {
|
|
8417
|
+
for (const language of languages) {
|
|
8418
|
+
for (const imageType of imageTypes) {
|
|
8419
|
+
const localDir = join12(dir, language, imageType);
|
|
8420
|
+
const localFiles = await scanLocalImages(localDir);
|
|
8421
|
+
let remoteImages;
|
|
8422
|
+
try {
|
|
8423
|
+
remoteImages = await client.images.list(packageName, edit.id, language, imageType);
|
|
8424
|
+
} catch (error) {
|
|
8425
|
+
if (error instanceof PlayApiError && error.statusCode === 404) {
|
|
8426
|
+
remoteImages = [];
|
|
8427
|
+
} else {
|
|
8428
|
+
throw error;
|
|
8429
|
+
}
|
|
8430
|
+
}
|
|
8431
|
+
const remoteSha256Set = new Set(remoteImages.map((img) => img.sha256.toLowerCase()));
|
|
8432
|
+
const localHashes = /* @__PURE__ */ new Map();
|
|
8433
|
+
for (const file of localFiles) {
|
|
8434
|
+
const hash = await sha256File(join12(localDir, file));
|
|
8435
|
+
localHashes.set(file, hash);
|
|
8436
|
+
}
|
|
8437
|
+
const localSha256Set = new Set(localHashes.values());
|
|
8438
|
+
if (options?.delete) {
|
|
8439
|
+
for (const img of remoteImages) {
|
|
8440
|
+
if (!localSha256Set.has(img.sha256.toLowerCase())) {
|
|
8441
|
+
if (!options?.dryRun) {
|
|
8442
|
+
await client.images.delete(packageName, edit.id, language, imageType, img.id);
|
|
8443
|
+
}
|
|
8444
|
+
deleted++;
|
|
8445
|
+
details.push({
|
|
8446
|
+
language,
|
|
8447
|
+
imageType,
|
|
8448
|
+
file: img.id,
|
|
8449
|
+
action: "delete",
|
|
8450
|
+
reason: "not in local"
|
|
8451
|
+
});
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
}
|
|
8455
|
+
for (const file of localFiles) {
|
|
8456
|
+
const hash = localHashes.get(file);
|
|
8457
|
+
if (remoteSha256Set.has(hash)) {
|
|
8458
|
+
skipped++;
|
|
8459
|
+
details.push({ language, imageType, file, action: "skip", reason: "sha256 match" });
|
|
8460
|
+
} else {
|
|
8461
|
+
if (!options?.dryRun) {
|
|
8462
|
+
const filePath = join12(localDir, file);
|
|
8463
|
+
const check = await validateImage(filePath, imageType);
|
|
8464
|
+
if (!check.valid) {
|
|
8465
|
+
throw new GpcError(
|
|
8466
|
+
`Image validation failed for ${language}/${imageType}/${file}: ${check.errors.join("; ")}`,
|
|
8467
|
+
"IMAGE_INVALID",
|
|
8468
|
+
2,
|
|
8469
|
+
"Check image dimensions, file size, and format."
|
|
8470
|
+
);
|
|
8471
|
+
}
|
|
8472
|
+
await client.images.upload(packageName, edit.id, language, imageType, filePath);
|
|
8473
|
+
}
|
|
8474
|
+
uploaded++;
|
|
8475
|
+
details.push({ language, imageType, file, action: "upload", reason: "new or changed" });
|
|
8476
|
+
}
|
|
8477
|
+
}
|
|
8478
|
+
}
|
|
8479
|
+
}
|
|
8480
|
+
if (options?.dryRun || uploaded === 0 && deleted === 0) {
|
|
8481
|
+
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
8482
|
+
});
|
|
8483
|
+
} else {
|
|
8484
|
+
await validateAndCommit(client, packageName, edit.id, options?.commitOptions);
|
|
8485
|
+
}
|
|
8486
|
+
return {
|
|
8487
|
+
uploaded,
|
|
8488
|
+
skipped,
|
|
8489
|
+
deleted,
|
|
8490
|
+
total: uploaded + skipped + deleted,
|
|
8491
|
+
details
|
|
8492
|
+
};
|
|
8493
|
+
} catch (error) {
|
|
8494
|
+
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
8495
|
+
});
|
|
8496
|
+
throw error;
|
|
8497
|
+
}
|
|
8498
|
+
}
|
|
8499
|
+
|
|
8500
|
+
// src/commands/bundles.ts
|
|
8501
|
+
import { PlayApiError as PlayApiError2 } from "@gpc-cli/api";
|
|
8502
|
+
async function listBundles(client, packageName) {
|
|
8503
|
+
const edit = await client.edits.insert(packageName);
|
|
8504
|
+
try {
|
|
8505
|
+
const bundles = await client.bundles.list(packageName, edit.id);
|
|
8506
|
+
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
8507
|
+
});
|
|
8508
|
+
return bundles;
|
|
8509
|
+
} catch (error) {
|
|
8510
|
+
await client.edits.delete(packageName, edit.id).catch(() => {
|
|
8511
|
+
});
|
|
8512
|
+
throw error;
|
|
8513
|
+
}
|
|
8514
|
+
}
|
|
8515
|
+
async function findBundle(client, packageName, versionCode) {
|
|
8516
|
+
const bundles = await listBundles(client, packageName);
|
|
8517
|
+
return bundles.find((b) => b.versionCode === versionCode) ?? null;
|
|
8518
|
+
}
|
|
8519
|
+
function isRetryableError(error) {
|
|
8520
|
+
if (!(error instanceof PlayApiError2)) return false;
|
|
8521
|
+
const status = error.statusCode;
|
|
8522
|
+
return status === 429 || status === 500 || status === 503 || status === 409;
|
|
8523
|
+
}
|
|
8524
|
+
async function waitForBundle(client, packageName, versionCode, options) {
|
|
8525
|
+
const timeout = options?.timeout ?? 6e5;
|
|
8526
|
+
const interval = options?.interval ?? 15e3;
|
|
8527
|
+
const deadline = Date.now() + timeout;
|
|
8528
|
+
while (Date.now() < deadline) {
|
|
8529
|
+
try {
|
|
8530
|
+
const bundles = await listBundles(client, packageName);
|
|
8531
|
+
const match = bundles.find((b) => b.versionCode === versionCode);
|
|
8532
|
+
if (match) return match;
|
|
8533
|
+
} catch (error) {
|
|
8534
|
+
if (!isRetryableError(error)) throw error;
|
|
8535
|
+
}
|
|
8536
|
+
const remaining = deadline - Date.now();
|
|
8537
|
+
if (remaining <= 0) break;
|
|
8538
|
+
await new Promise((r) => setTimeout(r, Math.min(interval, remaining)));
|
|
8539
|
+
}
|
|
8540
|
+
throw new GpcError(
|
|
8541
|
+
`Bundle version code ${versionCode} not found after ${Math.round(timeout / 1e3)}s`,
|
|
8542
|
+
"BUNDLE_WAIT_TIMEOUT",
|
|
8543
|
+
4,
|
|
8544
|
+
"The bundle may still be processing. Try again with a longer --timeout, or check the Play Console."
|
|
8545
|
+
);
|
|
8546
|
+
}
|
|
8547
|
+
|
|
8338
8548
|
// src/signing-consistency.ts
|
|
8339
8549
|
async function checkSigningConsistency(accessToken, packageName, apiHost = "androidpublisher.googleapis.com") {
|
|
8340
8550
|
const baseUrl = `https://${apiHost}/androidpublisher/v3/applications/${encodeURIComponent(packageName)}`;
|
|
@@ -8577,6 +8787,7 @@ export {
|
|
|
8577
8787
|
checkThreshold,
|
|
8578
8788
|
classifyError,
|
|
8579
8789
|
clearAuditLog,
|
|
8790
|
+
commitWithRescue,
|
|
8580
8791
|
compareBundles,
|
|
8581
8792
|
compareFingerprints,
|
|
8582
8793
|
compareVersionVitals,
|
|
@@ -8631,6 +8842,7 @@ export {
|
|
|
8631
8842
|
fetchAggregateCost,
|
|
8632
8843
|
fetchChangelog,
|
|
8633
8844
|
fetchReleaseNotes,
|
|
8845
|
+
findBundle,
|
|
8634
8846
|
formatChangelogEntry,
|
|
8635
8847
|
formatCustomPayload,
|
|
8636
8848
|
formatDiscordPayload,
|
|
@@ -8697,6 +8909,7 @@ export {
|
|
|
8697
8909
|
lintLocalListings,
|
|
8698
8910
|
listAchievements,
|
|
8699
8911
|
listAuditEvents,
|
|
8912
|
+
listBundles,
|
|
8700
8913
|
listDeviceTiers,
|
|
8701
8914
|
listEvents,
|
|
8702
8915
|
listGeneratedApks,
|
|
@@ -8765,9 +8978,11 @@ export {
|
|
|
8765
8978
|
searchVitalsErrors,
|
|
8766
8979
|
sendNotification,
|
|
8767
8980
|
sendWebhook,
|
|
8981
|
+
sha256File,
|
|
8768
8982
|
sortResults,
|
|
8769
8983
|
startTrain,
|
|
8770
8984
|
statusHasBreach,
|
|
8985
|
+
syncImages,
|
|
8771
8986
|
syncInAppProducts,
|
|
8772
8987
|
topFiles,
|
|
8773
8988
|
trackBreachState,
|
|
@@ -8788,6 +9003,7 @@ export {
|
|
|
8788
9003
|
uploadImage,
|
|
8789
9004
|
uploadInternalSharing,
|
|
8790
9005
|
uploadRelease,
|
|
9006
|
+
validateAndCommit,
|
|
8791
9007
|
validateBundleForApply,
|
|
8792
9008
|
validateImage,
|
|
8793
9009
|
validateLanguageCode,
|
|
@@ -8798,6 +9014,7 @@ export {
|
|
|
8798
9014
|
validateTrackName,
|
|
8799
9015
|
validateUploadFile,
|
|
8800
9016
|
validateVersionCode,
|
|
9017
|
+
waitForBundle,
|
|
8801
9018
|
waitForBundleProcessing,
|
|
8802
9019
|
watchVitalsWithAutoHalt,
|
|
8803
9020
|
wordDiff,
|