@gpc-cli/api 1.0.5 → 1.0.7

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.js CHANGED
@@ -1,7 +1,3 @@
1
- // src/http.ts
2
- import { readFile } from "fs/promises";
3
- import { resolve, isAbsolute } from "path";
4
-
5
1
  // src/errors.ts
6
2
  var ApiError = class extends Error {
7
3
  constructor(message, code, statusCode, suggestion) {
@@ -25,6 +21,8 @@ var ApiError = class extends Error {
25
21
  };
26
22
 
27
23
  // src/http.ts
24
+ import { readFile } from "fs/promises";
25
+ import { resolve, isAbsolute } from "path";
28
26
  function sanitizeErrorBody(body) {
29
27
  try {
30
28
  const parsed = JSON.parse(body);
@@ -52,6 +50,7 @@ function validateFilePath(filePath) {
52
50
  }
53
51
  var BASE_URL = "https://androidpublisher.googleapis.com/androidpublisher/v3/applications";
54
52
  var UPLOAD_BASE_URL = "https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications";
53
+ var INTERNAL_SHARING_UPLOAD_BASE_URL = "https://androidpublisher.googleapis.com/upload/internalappsharing/v3/applications";
55
54
  function envInt(name) {
56
55
  const val = process.env[name];
57
56
  if (val === void 0) return void 0;
@@ -227,8 +226,8 @@ function createHttpClient(options) {
227
226
  }
228
227
  throw lastError ?? new ApiError("Request failed", "API_NETWORK_ERROR");
229
228
  }
230
- async function uploadRequest(path, filePath, contentType) {
231
- const url = `${UPLOAD_BASE_URL}${path}`;
229
+ async function uploadRequest(path, filePath, contentType, baseUrl = UPLOAD_BASE_URL) {
230
+ const url = `${baseUrl}${path}`;
232
231
  const safeFilePath = validateFilePath(filePath);
233
232
  const fileBuffer = await readFile(safeFilePath);
234
233
  let token = await options.auth.getAccessToken();
@@ -355,6 +354,40 @@ function createHttpClient(options) {
355
354
  },
356
355
  upload(path, filePath, contentType) {
357
356
  return uploadRequest(path, filePath, contentType);
357
+ },
358
+ uploadInternal(path, filePath, contentType) {
359
+ return uploadRequest(path, filePath, contentType, INTERNAL_SHARING_UPLOAD_BASE_URL);
360
+ },
361
+ async download(path) {
362
+ const url = `${options.baseUrl ?? BASE_URL}${path}`;
363
+ const token = await options.auth.getAccessToken();
364
+ const controller = new AbortController();
365
+ const timer = setTimeout(() => controller.abort(), timeout);
366
+ try {
367
+ const response = await fetch(url, {
368
+ method: "GET",
369
+ headers: {
370
+ Authorization: `Bearer ${token}`,
371
+ "Accept-Encoding": "gzip, deflate",
372
+ Connection: "keep-alive"
373
+ },
374
+ signal: controller.signal,
375
+ keepalive: true
376
+ });
377
+ if (!response.ok) {
378
+ const errorBody = await response.text();
379
+ const { code, suggestion } = mapStatusToError(response.status, errorBody);
380
+ throw new ApiError(
381
+ `GET ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,
382
+ code,
383
+ response.status,
384
+ suggestion
385
+ );
386
+ }
387
+ return await response.arrayBuffer();
388
+ } finally {
389
+ clearTimeout(timer);
390
+ }
358
391
  }
359
392
  };
360
393
  }
@@ -422,7 +455,12 @@ function createApiClient(options) {
422
455
  "application/octet-stream"
423
456
  );
424
457
  if (!data.bundle) {
425
- throw new Error("Upload succeeded but no bundle data returned");
458
+ throw new ApiError(
459
+ "Upload succeeded but no bundle data returned",
460
+ "API_EMPTY_RESPONSE",
461
+ 200,
462
+ "This is unexpected. Retry the upload or contact Google Play support if the issue persists."
463
+ );
426
464
  }
427
465
  return data.bundle;
428
466
  }
@@ -494,7 +532,12 @@ function createApiClient(options) {
494
532
  filePath.endsWith(".png") ? "image/png" : "image/jpeg"
495
533
  );
496
534
  if (!data.image) {
497
- throw new Error("Upload succeeded but no image data returned");
535
+ throw new ApiError(
536
+ "Upload succeeded but no image data returned",
537
+ "API_EMPTY_RESPONSE",
538
+ 200,
539
+ "This is unexpected. Retry the upload or contact Google Play support if the issue persists."
540
+ );
498
541
  }
499
542
  return data.image;
500
543
  },
@@ -518,6 +561,21 @@ function createApiClient(options) {
518
561
  return data;
519
562
  }
520
563
  },
564
+ dataSafety: {
565
+ async get(packageName, editId) {
566
+ const { data } = await http.get(
567
+ `/${packageName}/edits/${editId}/dataSafety`
568
+ );
569
+ return data;
570
+ },
571
+ async update(packageName, editId, body) {
572
+ const { data } = await http.put(
573
+ `/${packageName}/edits/${editId}/dataSafety`,
574
+ body
575
+ );
576
+ return data;
577
+ }
578
+ },
521
579
  reviews: {
522
580
  async list(packageName, options2) {
523
581
  await rateLimit(limiter, "reviewsGet");
@@ -792,10 +850,177 @@ function createApiClient(options) {
792
850
  "application/octet-stream"
793
851
  );
794
852
  if (!data.deobfuscationFile) {
795
- throw new Error("Upload succeeded but no deobfuscation file data returned");
853
+ throw new ApiError(
854
+ "Upload succeeded but no deobfuscation file data returned",
855
+ "API_EMPTY_RESPONSE",
856
+ 200,
857
+ "This is unexpected. Retry the upload or contact Google Play support if the issue persists."
858
+ );
796
859
  }
797
860
  return data.deobfuscationFile;
798
861
  }
862
+ },
863
+ appRecovery: {
864
+ async list(packageName) {
865
+ const { data } = await http.post(
866
+ `/${packageName}/appRecoveries`
867
+ );
868
+ return data.recoveryActions || [];
869
+ },
870
+ async cancel(packageName, appRecoveryId) {
871
+ await http.post(`/${packageName}/appRecovery/${appRecoveryId}:cancel`);
872
+ },
873
+ async deploy(packageName, appRecoveryId) {
874
+ await http.post(`/${packageName}/appRecovery/${appRecoveryId}:deploy`);
875
+ },
876
+ async create(packageName, request) {
877
+ const { data } = await http.post(
878
+ `/${packageName}/appRecoveries`,
879
+ request
880
+ );
881
+ return data;
882
+ },
883
+ async addTargeting(packageName, appRecoveryId, targeting) {
884
+ const { data } = await http.post(
885
+ `/${packageName}/appRecoveries/${appRecoveryId}:addTargeting`,
886
+ targeting
887
+ );
888
+ return data;
889
+ }
890
+ },
891
+ externalTransactions: {
892
+ async create(packageName, body) {
893
+ const { data } = await http.post(
894
+ `/${packageName}/externalTransactions`,
895
+ body
896
+ );
897
+ return data;
898
+ },
899
+ async get(packageName, transactionId) {
900
+ const { data } = await http.get(
901
+ `/${packageName}/externalTransactions/${transactionId}`
902
+ );
903
+ return data;
904
+ },
905
+ async refund(packageName, transactionId, refundData) {
906
+ const { data } = await http.post(
907
+ `/${packageName}/externalTransactions/${transactionId}:refund`,
908
+ refundData
909
+ );
910
+ return data;
911
+ }
912
+ },
913
+ deviceTiers: {
914
+ async list(packageName) {
915
+ const { data } = await http.get(
916
+ `/${packageName}/deviceTierConfigs`
917
+ );
918
+ return data.deviceTierConfigs || [];
919
+ },
920
+ async get(packageName, configId) {
921
+ const { data } = await http.get(
922
+ `/${packageName}/deviceTierConfigs/${configId}`
923
+ );
924
+ return data;
925
+ },
926
+ async create(packageName, config) {
927
+ const { data } = await http.post(
928
+ `/${packageName}/deviceTierConfigs`,
929
+ config
930
+ );
931
+ return data;
932
+ }
933
+ },
934
+ oneTimeProducts: {
935
+ async list(packageName) {
936
+ const { data } = await http.get(
937
+ `/${packageName}/oneTimeProducts`
938
+ );
939
+ return data;
940
+ },
941
+ async get(packageName, productId) {
942
+ const { data } = await http.get(
943
+ `/${packageName}/oneTimeProducts/${productId}`
944
+ );
945
+ return data;
946
+ },
947
+ async create(packageName, body) {
948
+ const { data } = await http.post(
949
+ `/${packageName}/oneTimeProducts`,
950
+ body
951
+ );
952
+ return data;
953
+ },
954
+ async update(packageName, productId, body) {
955
+ const { data } = await http.patch(
956
+ `/${packageName}/oneTimeProducts/${productId}`,
957
+ body
958
+ );
959
+ return data;
960
+ },
961
+ async delete(packageName, productId) {
962
+ await http.delete(`/${packageName}/oneTimeProducts/${productId}`);
963
+ },
964
+ async listOffers(packageName, productId) {
965
+ const { data } = await http.get(
966
+ `/${packageName}/oneTimeProducts/${productId}/offers`
967
+ );
968
+ return data;
969
+ },
970
+ async getOffer(packageName, productId, offerId) {
971
+ const { data } = await http.get(
972
+ `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`
973
+ );
974
+ return data;
975
+ },
976
+ async createOffer(packageName, productId, body) {
977
+ const { data } = await http.post(
978
+ `/${packageName}/oneTimeProducts/${productId}/offers`,
979
+ body
980
+ );
981
+ return data;
982
+ },
983
+ async updateOffer(packageName, productId, offerId, body) {
984
+ const { data } = await http.patch(
985
+ `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`,
986
+ body
987
+ );
988
+ return data;
989
+ },
990
+ async deleteOffer(packageName, productId, offerId) {
991
+ await http.delete(`/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`);
992
+ }
993
+ },
994
+ internalAppSharing: {
995
+ async uploadBundle(packageName, bundlePath) {
996
+ const { data } = await http.uploadInternal(
997
+ `/${packageName}/artifacts/bundle`,
998
+ bundlePath,
999
+ "application/octet-stream"
1000
+ );
1001
+ return data;
1002
+ },
1003
+ async uploadApk(packageName, apkPath) {
1004
+ const { data } = await http.uploadInternal(
1005
+ `/${packageName}/artifacts/apk`,
1006
+ apkPath,
1007
+ "application/vnd.android.package-archive"
1008
+ );
1009
+ return data;
1010
+ }
1011
+ },
1012
+ generatedApks: {
1013
+ async list(packageName, versionCode) {
1014
+ const { data } = await http.get(
1015
+ `/${packageName}/generatedApks/${versionCode}`
1016
+ );
1017
+ return data.generatedApks || [];
1018
+ },
1019
+ async download(packageName, versionCode, id) {
1020
+ return http.download(
1021
+ `/${packageName}/generatedApks/${versionCode}/download/${id}`
1022
+ );
1023
+ }
799
1024
  }
800
1025
  };
801
1026
  }