@gpc-cli/api 1.0.19 → 1.0.20
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 +34 -28
- package/dist/index.d.ts +2 -2
- package/dist/index.js +42 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,12 +32,12 @@ await client.edits.delete("com.example.app", edit.id);
|
|
|
32
32
|
|
|
33
33
|
## Client Factories
|
|
34
34
|
|
|
35
|
-
| Factory
|
|
36
|
-
|
|
|
37
|
-
| `createApiClient(options)`
|
|
38
|
-
| `createReportingClient(options)` | Vitals, crash rates, ANR, error reporting
|
|
39
|
-
| `createUsersClient(options)`
|
|
40
|
-
| `createHttpClient(options)`
|
|
35
|
+
| Factory | Purpose |
|
|
36
|
+
| -------------------------------- | ------------------------------------------------------------------ |
|
|
37
|
+
| `createApiClient(options)` | Core Play API -- apps, releases, listings, monetization, purchases |
|
|
38
|
+
| `createReportingClient(options)` | Vitals, crash rates, ANR, error reporting |
|
|
39
|
+
| `createUsersClient(options)` | Developer account users and permission grants |
|
|
40
|
+
| `createHttpClient(options)` | Low-level HTTP with auth, retry, and rate limiting |
|
|
41
41
|
|
|
42
42
|
All factories accept `ApiClientOptions`:
|
|
43
43
|
|
|
@@ -45,10 +45,10 @@ All factories accept `ApiClientOptions`:
|
|
|
45
45
|
import type { ApiClientOptions } from "@gpc-cli/api";
|
|
46
46
|
|
|
47
47
|
const options: ApiClientOptions = {
|
|
48
|
-
auth,
|
|
49
|
-
maxRetries: 3,
|
|
50
|
-
timeout: 30_000,
|
|
51
|
-
rateLimiter: undefined,
|
|
48
|
+
auth, // Required: { getAccessToken(): Promise<string> }
|
|
49
|
+
maxRetries: 3, // Default retry count
|
|
50
|
+
timeout: 30_000, // Request timeout in ms
|
|
51
|
+
rateLimiter: undefined, // Optional custom rate limiter
|
|
52
52
|
onRetry: (entry) => console.warn(`Retry #${entry.attempt}: ${entry.error}`),
|
|
53
53
|
};
|
|
54
54
|
```
|
|
@@ -118,12 +118,13 @@ await client.edits.commit("com.example.app", edit.id);
|
|
|
118
118
|
const edit = await client.edits.insert("com.example.app");
|
|
119
119
|
|
|
120
120
|
const screenshots = await client.images.list(
|
|
121
|
-
"com.example.app",
|
|
121
|
+
"com.example.app",
|
|
122
|
+
edit.id,
|
|
123
|
+
"en-US",
|
|
124
|
+
"phoneScreenshots",
|
|
122
125
|
);
|
|
123
126
|
|
|
124
|
-
await client.images.upload(
|
|
125
|
-
"com.example.app", edit.id, "en-US", "featureGraphic", "./feature.png",
|
|
126
|
-
);
|
|
127
|
+
await client.images.upload("com.example.app", edit.id, "en-US", "featureGraphic", "./feature.png");
|
|
127
128
|
|
|
128
129
|
await client.images.deleteAll("com.example.app", edit.id, "en-US", "phoneScreenshots");
|
|
129
130
|
await client.edits.commit("com.example.app", edit.id);
|
|
@@ -145,15 +146,23 @@ await client.subscriptions.deactivateBasePlan("com.example.app", "premium_monthl
|
|
|
145
146
|
|
|
146
147
|
```typescript
|
|
147
148
|
const { subscriptionOffers } = await client.subscriptions.listOffers(
|
|
148
|
-
"com.example.app",
|
|
149
|
+
"com.example.app",
|
|
150
|
+
"premium_monthly",
|
|
151
|
+
"p1m",
|
|
149
152
|
);
|
|
150
153
|
|
|
151
154
|
const offer = await client.subscriptions.getOffer(
|
|
152
|
-
"com.example.app",
|
|
155
|
+
"com.example.app",
|
|
156
|
+
"premium_monthly",
|
|
157
|
+
"p1m",
|
|
158
|
+
"intro_offer",
|
|
153
159
|
);
|
|
154
160
|
|
|
155
161
|
await client.subscriptions.activateOffer(
|
|
156
|
-
"com.example.app",
|
|
162
|
+
"com.example.app",
|
|
163
|
+
"premium_monthly",
|
|
164
|
+
"p1m",
|
|
165
|
+
"intro_offer",
|
|
157
166
|
);
|
|
158
167
|
```
|
|
159
168
|
|
|
@@ -175,9 +184,7 @@ await client.inappproducts.create("com.example.app", {
|
|
|
175
184
|
|
|
176
185
|
```typescript
|
|
177
186
|
// Verify a product purchase
|
|
178
|
-
const purchase = await client.purchases.getProduct(
|
|
179
|
-
"com.example.app", "coins_100", purchaseToken,
|
|
180
|
-
);
|
|
187
|
+
const purchase = await client.purchases.getProduct("com.example.app", "coins_100", purchaseToken);
|
|
181
188
|
|
|
182
189
|
// Acknowledge it
|
|
183
190
|
await client.purchases.acknowledgeProduct("com.example.app", "coins_100", purchaseToken);
|
|
@@ -270,10 +277,9 @@ await client.edits.commit("com.example.app", edit.id);
|
|
|
270
277
|
### Monetization
|
|
271
278
|
|
|
272
279
|
```typescript
|
|
273
|
-
const { convertedRegionPrices } = await client.monetization.convertRegionPrices(
|
|
274
|
-
"
|
|
275
|
-
|
|
276
|
-
);
|
|
280
|
+
const { convertedRegionPrices } = await client.monetization.convertRegionPrices("com.example.app", {
|
|
281
|
+
price: { currencyCode: "USD", units: "9", nanos: 990_000_000 },
|
|
282
|
+
});
|
|
277
283
|
```
|
|
278
284
|
|
|
279
285
|
### Deobfuscation
|
|
@@ -347,10 +353,10 @@ try {
|
|
|
347
353
|
await client.tracks.get("com.example.app", editId, "production");
|
|
348
354
|
} catch (error) {
|
|
349
355
|
if (error instanceof ApiError) {
|
|
350
|
-
console.error(error.code);
|
|
351
|
-
console.error(error.statusCode);
|
|
352
|
-
console.error(error.suggestion);
|
|
353
|
-
console.error(error.toJSON());
|
|
356
|
+
console.error(error.code); // e.g. "API_NOT_FOUND"
|
|
357
|
+
console.error(error.statusCode); // e.g. 404
|
|
358
|
+
console.error(error.suggestion); // actionable fix
|
|
359
|
+
console.error(error.toJSON()); // structured error object
|
|
354
360
|
}
|
|
355
361
|
}
|
|
356
362
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1081,7 +1081,7 @@ declare function paginateParallel<TItem>(fetchPage: (pageToken?: string) => Prom
|
|
|
1081
1081
|
nextPageToken?: string;
|
|
1082
1082
|
}>;
|
|
1083
1083
|
|
|
1084
|
-
declare class
|
|
1084
|
+
declare class PlayApiError extends Error {
|
|
1085
1085
|
readonly code: string;
|
|
1086
1086
|
readonly statusCode?: number | undefined;
|
|
1087
1087
|
readonly suggestion?: string | undefined;
|
|
@@ -1097,4 +1097,4 @@ declare class ApiError extends Error {
|
|
|
1097
1097
|
};
|
|
1098
1098
|
}
|
|
1099
1099
|
|
|
1100
|
-
export { type Achievement, type Anomaly, type AnomalyDetectionResponse, type ApiClientOptions,
|
|
1100
|
+
export { type Achievement, type Anomaly, type AnomalyDetectionResponse, type ApiClientOptions, type ApiResponse, type ApkInfo, type AppDetails, type AppEdit, type AppRecoveriesListResponse, type AppRecoveryAction, type AppRecoveryTargeting, type BasePlan, type BasePlanMigratePricesRequest, type Bundle, type BundleListResponse, type ConvertRegionPricesRequest, type ConvertRegionPricesResponse, type ConvertedRegionPrice, type CountryAvailability, type CreateAppRecoveryActionRequest, type CustomApp, type CustomAppsListResponse, type DataSafety, type DataSafetyDataType, type DataSafetyPurpose, type DeobfuscationFile, type DeobfuscationUploadResponse, type DeveloperComment, type DeveloperPermission, type DeviceGroup, type DeviceSelector, type DeviceTier, type DeviceTierConfig, type DeviceTierConfigsListResponse, type EnterpriseApiClient, type ErrorIssue, type ErrorIssuesResponse, type ErrorReport, type ErrorReportsResponse, type ExternalTransaction, type ExternalTransactionAmount, type ExternalTransactionRefund, type ExternallyHostedApk, type ExternallyHostedApkResponse, type GameEvent, type GamesApiClient, type GeneratedApk, type GeneratedApksPerVersion, type Grant, type GrantsListResponse, type HttpClient, type Image, type ImageType, type ImageUploadResponse, type ImagesDeleteAllResponse, type ImagesListResponse, type InAppProduct, type InAppProductListing, type InAppProductsBatchGetRequest, type InAppProductsBatchUpdateRequest, type InAppProductsBatchUpdateResponse, type InAppProductsListResponse, type InternalAppSharingArtifact, type Leaderboard, type LeaderboardScore, type Listing, type ListingsListResponse, type MetricRow, type MetricSetQuery, type MetricSetResponse, type Money, type OffersListResponse, type OneTimeOffer, type OneTimeOfferRegionalConfig, type OneTimeOffersListResponse, type OneTimeProduct, type OneTimeProductListing, type OneTimeProductsListResponse, type PagedResponse, type PaginateOptions, type PlayApiClient, PlayApiError, type ProductPurchase, type PurchaseOption, type PurchaseOptionsListResponse, RATE_LIMIT_BUCKETS, type RateLimitBucket, type RateLimiter, type RegionalBasePlanConfig, type Release, type ReleaseNote, type ReleaseStatus, type ReportBucket, type ReportType, type ReportingAggregation, type ReportingApiClient, type ReportingDimension, type ReportsListResponse, type RetryLogEntry, type Review, type ReviewComment, type ReviewReplyRequest, type ReviewReplyResponse, type ReviewsListOptions, type ReviewsListResponse, type StatsDimension, type Subscription, type SubscriptionDeferRequest, type SubscriptionDeferResponse, type SubscriptionListing, type SubscriptionOffer, type SubscriptionOfferPhase, type SubscriptionPurchase, type SubscriptionPurchaseLineItem, type SubscriptionPurchaseV2, type SubscriptionsListResponse, type TaxAndComplianceSettings, type Testers, type TokenPagination, type Track, type TrackListResponse, type UploadResponse, type User, type UserComment, type UsersApiClient, type UsersListResponse, type VitalsMetricSet, type VoidedPurchase, type VoidedPurchasesListResponse, createApiClient, createEnterpriseClient, createGamesClient, createHttpClient, createRateLimiter, createReportingClient, createUsersClient, paginate, paginateAll, paginateParallel };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/errors.ts
|
|
2
|
-
var
|
|
2
|
+
var PlayApiError = class extends Error {
|
|
3
3
|
constructor(message, code, statusCode, suggestion) {
|
|
4
4
|
super(message);
|
|
5
5
|
this.code = code;
|
|
6
6
|
this.statusCode = statusCode;
|
|
7
7
|
this.suggestion = suggestion;
|
|
8
|
-
this.name = "
|
|
8
|
+
this.name = "PlayApiError";
|
|
9
9
|
}
|
|
10
10
|
exitCode = 4;
|
|
11
11
|
toJSON() {
|
|
@@ -40,7 +40,7 @@ function sanitizeErrorBody(body) {
|
|
|
40
40
|
function validateFilePath(filePath) {
|
|
41
41
|
const resolved = resolve(filePath);
|
|
42
42
|
if (!isAbsolute(resolved)) {
|
|
43
|
-
throw new
|
|
43
|
+
throw new PlayApiError(
|
|
44
44
|
"Invalid file path",
|
|
45
45
|
"API_INVALID_PATH",
|
|
46
46
|
void 0,
|
|
@@ -48,7 +48,12 @@ function validateFilePath(filePath) {
|
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
if (filePath.includes("\0")) {
|
|
51
|
-
throw new
|
|
51
|
+
throw new PlayApiError(
|
|
52
|
+
"Invalid file path: null bytes not allowed",
|
|
53
|
+
"API_INVALID_PATH",
|
|
54
|
+
void 0,
|
|
55
|
+
"Provide a valid file path without null bytes."
|
|
56
|
+
);
|
|
52
57
|
}
|
|
53
58
|
return resolved;
|
|
54
59
|
}
|
|
@@ -168,7 +173,7 @@ function createHttpClient(options) {
|
|
|
168
173
|
}
|
|
169
174
|
const errorBody = await response.text();
|
|
170
175
|
const { code, suggestion } = mapStatusToError(response.status, errorBody);
|
|
171
|
-
const err = new
|
|
176
|
+
const err = new PlayApiError(
|
|
172
177
|
`${method} ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,
|
|
173
178
|
code,
|
|
174
179
|
response.status,
|
|
@@ -195,11 +200,11 @@ function createHttpClient(options) {
|
|
|
195
200
|
}
|
|
196
201
|
throw err;
|
|
197
202
|
} catch (error) {
|
|
198
|
-
if (error instanceof
|
|
203
|
+
if (error instanceof PlayApiError) {
|
|
199
204
|
throw error;
|
|
200
205
|
}
|
|
201
206
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
202
|
-
const timeoutErr = new
|
|
207
|
+
const timeoutErr = new PlayApiError(
|
|
203
208
|
`${method} ${path} timed out after ${timeout}ms`,
|
|
204
209
|
"API_TIMEOUT",
|
|
205
210
|
void 0,
|
|
@@ -219,7 +224,7 @@ function createHttpClient(options) {
|
|
|
219
224
|
}
|
|
220
225
|
throw timeoutErr;
|
|
221
226
|
}
|
|
222
|
-
const networkErr = new
|
|
227
|
+
const networkErr = new PlayApiError(
|
|
223
228
|
`${method} ${path} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
224
229
|
"API_NETWORK_ERROR",
|
|
225
230
|
void 0,
|
|
@@ -242,7 +247,12 @@ function createHttpClient(options) {
|
|
|
242
247
|
clearTimeout(timer);
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
|
-
throw lastError ?? new
|
|
250
|
+
throw lastError ?? new PlayApiError(
|
|
251
|
+
"Request failed",
|
|
252
|
+
"API_NETWORK_ERROR",
|
|
253
|
+
void 0,
|
|
254
|
+
"Check your network connection and try again. Use --verbose for details."
|
|
255
|
+
);
|
|
246
256
|
}
|
|
247
257
|
function computeUploadTimeout(fileSizeBytes) {
|
|
248
258
|
if (uploadTimeoutExplicit !== void 0) return uploadTimeoutExplicit;
|
|
@@ -284,7 +294,7 @@ function createHttpClient(options) {
|
|
|
284
294
|
}
|
|
285
295
|
const errorBody = await response.text();
|
|
286
296
|
const { code, suggestion } = mapStatusToError(response.status, errorBody);
|
|
287
|
-
const err = new
|
|
297
|
+
const err = new PlayApiError(
|
|
288
298
|
`POST upload ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,
|
|
289
299
|
code,
|
|
290
300
|
response.status,
|
|
@@ -311,12 +321,12 @@ function createHttpClient(options) {
|
|
|
311
321
|
}
|
|
312
322
|
throw err;
|
|
313
323
|
} catch (error) {
|
|
314
|
-
if (error instanceof
|
|
324
|
+
if (error instanceof PlayApiError) {
|
|
315
325
|
throw error;
|
|
316
326
|
}
|
|
317
327
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
318
328
|
const sizeMb = Math.round(fileBuffer.byteLength / (1024 * 1024));
|
|
319
|
-
const timeoutErr = new
|
|
329
|
+
const timeoutErr = new PlayApiError(
|
|
320
330
|
`POST upload ${path} timed out after ${effectiveTimeout}ms (file: ${sizeMb} MB)`,
|
|
321
331
|
"API_TIMEOUT",
|
|
322
332
|
void 0,
|
|
@@ -336,7 +346,7 @@ function createHttpClient(options) {
|
|
|
336
346
|
}
|
|
337
347
|
throw timeoutErr;
|
|
338
348
|
}
|
|
339
|
-
const networkErr = new
|
|
349
|
+
const networkErr = new PlayApiError(
|
|
340
350
|
`POST upload ${path} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
341
351
|
"API_NETWORK_ERROR",
|
|
342
352
|
void 0,
|
|
@@ -359,7 +369,12 @@ function createHttpClient(options) {
|
|
|
359
369
|
clearTimeout(timer);
|
|
360
370
|
}
|
|
361
371
|
}
|
|
362
|
-
throw lastError ?? new
|
|
372
|
+
throw lastError ?? new PlayApiError(
|
|
373
|
+
"Upload request failed",
|
|
374
|
+
"API_NETWORK_ERROR",
|
|
375
|
+
void 0,
|
|
376
|
+
"Check your network connection and try again. Use --verbose for details."
|
|
377
|
+
);
|
|
363
378
|
}
|
|
364
379
|
return {
|
|
365
380
|
get(path, params) {
|
|
@@ -402,7 +417,7 @@ function createHttpClient(options) {
|
|
|
402
417
|
if (!response.ok) {
|
|
403
418
|
const errorBody = await response.text();
|
|
404
419
|
const { code, suggestion } = mapStatusToError(response.status, errorBody);
|
|
405
|
-
throw new
|
|
420
|
+
throw new PlayApiError(
|
|
406
421
|
`GET ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,
|
|
407
422
|
code,
|
|
408
423
|
response.status,
|
|
@@ -480,7 +495,7 @@ function createApiClient(options) {
|
|
|
480
495
|
"application/octet-stream"
|
|
481
496
|
);
|
|
482
497
|
if (!data || !data.versionCode) {
|
|
483
|
-
throw new
|
|
498
|
+
throw new PlayApiError(
|
|
484
499
|
"Upload succeeded but no bundle data returned",
|
|
485
500
|
"API_EMPTY_RESPONSE",
|
|
486
501
|
200,
|
|
@@ -572,7 +587,7 @@ function createApiClient(options) {
|
|
|
572
587
|
filePath.endsWith(".png") ? "image/png" : "image/jpeg"
|
|
573
588
|
);
|
|
574
589
|
if (!data.image) {
|
|
575
|
-
throw new
|
|
590
|
+
throw new PlayApiError(
|
|
576
591
|
"Upload succeeded but no image data returned",
|
|
577
592
|
"API_EMPTY_RESPONSE",
|
|
578
593
|
200,
|
|
@@ -603,16 +618,11 @@ function createApiClient(options) {
|
|
|
603
618
|
},
|
|
604
619
|
dataSafety: {
|
|
605
620
|
async get(packageName) {
|
|
606
|
-
const { data } = await http.get(
|
|
607
|
-
`/${packageName}/dataSafety`
|
|
608
|
-
);
|
|
621
|
+
const { data } = await http.get(`/${packageName}/dataSafety`);
|
|
609
622
|
return data;
|
|
610
623
|
},
|
|
611
624
|
async update(packageName, body) {
|
|
612
|
-
const { data } = await http.put(
|
|
613
|
-
`/${packageName}/dataSafety`,
|
|
614
|
-
body
|
|
615
|
-
);
|
|
625
|
+
const { data } = await http.put(`/${packageName}/dataSafety`, body);
|
|
616
626
|
return data;
|
|
617
627
|
}
|
|
618
628
|
},
|
|
@@ -665,9 +675,7 @@ function createApiClient(options) {
|
|
|
665
675
|
return data;
|
|
666
676
|
},
|
|
667
677
|
async get(packageName, productId) {
|
|
668
|
-
const { data } = await http.get(
|
|
669
|
-
`/${packageName}/subscriptions/${productId}`
|
|
670
|
-
);
|
|
678
|
+
const { data } = await http.get(`/${packageName}/subscriptions/${productId}`);
|
|
671
679
|
return data;
|
|
672
680
|
},
|
|
673
681
|
async create(packageName, body, productId) {
|
|
@@ -702,9 +710,7 @@ function createApiClient(options) {
|
|
|
702
710
|
return data;
|
|
703
711
|
},
|
|
704
712
|
async deleteBasePlan(packageName, productId, basePlanId) {
|
|
705
|
-
await http.delete(
|
|
706
|
-
`/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}`
|
|
707
|
-
);
|
|
713
|
+
await http.delete(`/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}`);
|
|
708
714
|
},
|
|
709
715
|
async migratePrices(packageName, productId, basePlanId, body) {
|
|
710
716
|
const { data } = await http.post(
|
|
@@ -922,7 +928,7 @@ function createApiClient(options) {
|
|
|
922
928
|
"application/octet-stream"
|
|
923
929
|
);
|
|
924
930
|
if (!data.deobfuscationFile) {
|
|
925
|
-
throw new
|
|
931
|
+
throw new PlayApiError(
|
|
926
932
|
"Upload succeeded but no deobfuscation file data returned",
|
|
927
933
|
"API_EMPTY_RESPONSE",
|
|
928
934
|
200,
|
|
@@ -1084,10 +1090,7 @@ function createApiClient(options) {
|
|
|
1084
1090
|
return data;
|
|
1085
1091
|
},
|
|
1086
1092
|
async create(packageName, body) {
|
|
1087
|
-
const { data } = await http.post(
|
|
1088
|
-
`/${packageName}/purchaseOptions`,
|
|
1089
|
-
body
|
|
1090
|
-
);
|
|
1093
|
+
const { data } = await http.post(`/${packageName}/purchaseOptions`, body);
|
|
1091
1094
|
return data;
|
|
1092
1095
|
},
|
|
1093
1096
|
async activate(packageName, purchaseOptionId) {
|
|
@@ -1129,9 +1132,7 @@ function createApiClient(options) {
|
|
|
1129
1132
|
return data.generatedApks || [];
|
|
1130
1133
|
},
|
|
1131
1134
|
async download(packageName, versionCode, id) {
|
|
1132
|
-
return http.download(
|
|
1133
|
-
`/${packageName}/generatedApks/${versionCode}/download/${id}`
|
|
1134
|
-
);
|
|
1135
|
+
return http.download(`/${packageName}/generatedApks/${versionCode}/download/${id}`);
|
|
1135
1136
|
}
|
|
1136
1137
|
}
|
|
1137
1138
|
};
|
|
@@ -1301,16 +1302,11 @@ function createEnterpriseClient(options) {
|
|
|
1301
1302
|
return {
|
|
1302
1303
|
apps: {
|
|
1303
1304
|
async create(organizationId, app) {
|
|
1304
|
-
const { data } = await http.post(
|
|
1305
|
-
`/${organizationId}/apps`,
|
|
1306
|
-
app
|
|
1307
|
-
);
|
|
1305
|
+
const { data } = await http.post(`/${organizationId}/apps`, app);
|
|
1308
1306
|
return data;
|
|
1309
1307
|
},
|
|
1310
1308
|
async list(organizationId) {
|
|
1311
|
-
const { data } = await http.get(
|
|
1312
|
-
`/${organizationId}/apps`
|
|
1313
|
-
);
|
|
1309
|
+
const { data } = await http.get(`/${organizationId}/apps`);
|
|
1314
1310
|
return data;
|
|
1315
1311
|
}
|
|
1316
1312
|
}
|
|
@@ -1431,7 +1427,7 @@ async function paginateParallel(fetchPage, pageTokens, concurrency = 4) {
|
|
|
1431
1427
|
return { items: allItems, nextPageToken: lastNextPageToken };
|
|
1432
1428
|
}
|
|
1433
1429
|
export {
|
|
1434
|
-
|
|
1430
|
+
PlayApiError,
|
|
1435
1431
|
RATE_LIMIT_BUCKETS,
|
|
1436
1432
|
createApiClient,
|
|
1437
1433
|
createEnterpriseClient,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/client.ts","../src/reporting-client.ts","../src/users-client.ts","../src/games-client.ts","../src/enterprise-client.ts","../src/rate-limiter.ts","../src/paginate.ts"],"sourcesContent":["export class ApiError extends Error {\n public readonly exitCode = 4;\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number,\n public readonly suggestion?: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n toJSON() {\n return {\n success: false,\n error: {\n code: this.code,\n message: this.message,\n suggestion: this.suggestion,\n },\n };\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { ApiError } from \"./errors.js\";\nimport type { ApiClientOptions, ApiResponse } from \"./types.js\";\n\n/** Strip HTML tags and collapse whitespace from a string. */\nfunction stripHtml(text: string): string {\n return text\n .replace(/<[^>]*>/g, \" \")\n .replace(/&[a-z]+;/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/** Extract a short, safe error summary from API response body (no tokens/secrets). */\nfunction sanitizeErrorBody(body: string): string {\n try {\n const parsed = JSON.parse(body) as {\n error?: { message?: string; status?: string; code?: number };\n };\n if (parsed?.error?.message) {\n return `${parsed.error.code ?? \"?\"} ${parsed.error.status ?? \"\"}: ${parsed.error.message}`.trim();\n }\n } catch {\n // not JSON — may be HTML error page\n }\n // Strip HTML tags before truncating\n const cleaned = body.startsWith(\"<\") ? stripHtml(body) : body;\n return cleaned.length > 200 ? cleaned.slice(0, 200) + \"...\" : cleaned;\n}\n\n/** Validate upload file path to prevent path traversal. */\nfunction validateFilePath(filePath: string): string {\n const resolved = resolve(filePath);\n if (!isAbsolute(resolved)) {\n throw new ApiError(\n \"Invalid file path\",\n \"API_INVALID_PATH\",\n undefined,\n \"File path must resolve to an absolute path.\",\n );\n }\n // Block obvious traversal patterns in the original input\n if (filePath.includes(\"\\0\")) {\n throw new ApiError(\"Invalid file path: null bytes not allowed\", \"API_INVALID_PATH\", undefined, \"Provide a valid file path without null bytes.\");\n }\n return resolved;\n}\n\nconst BASE_URL = \"https://androidpublisher.googleapis.com/androidpublisher/v3/applications\";\n\nconst UPLOAD_BASE_URL =\n \"https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications\";\n\nconst INTERNAL_SHARING_UPLOAD_BASE_URL =\n \"https://androidpublisher.googleapis.com/upload/internalappsharing/v3/applications\";\n\nexport interface HttpClient {\n get<T>(path: string, params?: Record<string, string>): Promise<ApiResponse<T>>;\n post<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n put<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n patch<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n delete<T>(path: string): Promise<ApiResponse<T>>;\n upload<T>(path: string, filePath: string, contentType: string): Promise<ApiResponse<T>>;\n uploadInternal<T>(path: string, filePath: string, contentType: string): Promise<ApiResponse<T>>;\n download(path: string): Promise<ArrayBuffer>;\n}\n\nfunction envInt(name: string): number | undefined {\n const val = process.env[name];\n if (val === undefined) return undefined;\n const n = Number(val);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction resolveOption(explicit: number | undefined, envName: string, fallback: number): number {\n return explicit ?? envInt(envName) ?? fallback;\n}\n\nfunction mapStatusToError(status: number, body: string): { code: string; suggestion?: string } {\n switch (status) {\n case 400: {\n // Detect FAILED_PRECONDITION: edit has expired\n try {\n const parsed = JSON.parse(body) as { error?: { status?: string; message?: string } };\n if (\n parsed?.error?.status === \"FAILED_PRECONDITION\" &&\n parsed.error.message?.toLowerCase().includes(\"edit\")\n ) {\n return {\n code: \"API_EDIT_EXPIRED\",\n suggestion: \"The edit session has expired. Retry the operation to open a fresh edit.\",\n };\n }\n } catch { /* not JSON */ }\n return { code: \"API_HTTP_400\", suggestion: \"Check request parameters and try again.\" };\n }\n case 401:\n return {\n code: \"API_UNAUTHORIZED\",\n suggestion: \"Check that your access token is valid and not expired.\",\n };\n case 403:\n return {\n code: \"API_FORBIDDEN\",\n suggestion: \"Ensure the service account has the required permissions for this operation.\",\n };\n case 404:\n return {\n code: \"API_NOT_FOUND\",\n suggestion: \"Verify the package name and resource IDs are correct.\",\n };\n case 409:\n return {\n code: \"API_EDIT_CONFLICT\",\n suggestion: \"Another edit may be in progress. Delete the existing edit and retry.\",\n };\n case 429:\n return {\n code: \"API_RATE_LIMITED\",\n suggestion: \"Too many requests. The client will retry automatically.\",\n };\n default:\n if (status >= 500) {\n return {\n code: \"API_SERVER_ERROR\",\n suggestion: \"Google Play API server error. The client will retry automatically.\",\n };\n }\n return { code: `API_HTTP_${status}` };\n }\n}\n\nfunction isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nfunction jitteredDelay(base: number, attempt: number, max: number): number {\n const exponential = base * 2 ** attempt;\n const capped = Math.min(exponential, max);\n return capped * (0.5 + Math.random() * 0.5);\n}\n\nexport function createHttpClient(options: ApiClientOptions): HttpClient {\n const maxRetries = resolveOption(options.maxRetries, \"GPC_MAX_RETRIES\", 3);\n const timeout = resolveOption(options.timeout, \"GPC_TIMEOUT\", 30_000);\n const uploadTimeoutExplicit = options.uploadTimeout ?? envInt(\"GPC_UPLOAD_TIMEOUT\");\n const baseDelay = resolveOption(options.baseDelay, \"GPC_BASE_DELAY\", 1_000);\n const maxDelay = resolveOption(options.maxDelay, \"GPC_MAX_DELAY\", 60_000);\n const onRetry = options.onRetry;\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n params?: Record<string, string>,\n ): Promise<ApiResponse<T>> {\n let url = `${options.baseUrl ?? BASE_URL}${path}`;\n if (params) {\n const search = new URLSearchParams(params);\n url += `?${search.toString()}`;\n }\n\n // Fetch token once before retries — the auth layer handles its own caching and mutex\n let token = await options.auth.getAccessToken();\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = jitteredDelay(baseDelay, attempt - 1, maxDelay);\n await new Promise((r) => setTimeout(r, delay));\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n };\n\n const init: RequestInit = {\n method,\n headers,\n signal: controller.signal,\n keepalive: true,\n };\n\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, init);\n\n if (response.ok) {\n const text = await response.text();\n const data = text ? (JSON.parse(text) as T) : ({} as T);\n return { data, status: response.status };\n }\n\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n\n const err = new ApiError(\n `${method} ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n\n if (isRetryable(response.status) && attempt < maxRetries) {\n lastError = err;\n const delay = jitteredDelay(baseDelay, attempt, maxDelay);\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n status: response.status,\n error: err.message,\n delayMs: Math.round(delay),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n\n // On 401, refresh token once before giving up\n if (response.status === 401 && attempt < maxRetries) {\n token = await options.auth.getAccessToken();\n lastError = err;\n continue;\n }\n\n throw err;\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const timeoutErr = new ApiError(\n `${method} ${path} timed out after ${timeout}ms`,\n \"API_TIMEOUT\",\n undefined,\n \"The request exceeded the configured timeout. Consider increasing the timeout value.\",\n );\n if (attempt < maxRetries) {\n lastError = timeoutErr;\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n error: timeoutErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw timeoutErr;\n }\n\n const networkErr = new ApiError(\n `${method} ${path} failed: ${error instanceof Error ? error.message : String(error)}`,\n \"API_NETWORK_ERROR\",\n undefined,\n \"A network error occurred. Check your internet connection.\",\n );\n if (attempt < maxRetries) {\n lastError = networkErr;\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n error: networkErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw networkErr;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // Should not reach here, but just in case\n throw lastError ?? new ApiError(\"Request failed\", \"API_NETWORK_ERROR\", undefined, \"Check your network connection and try again. Use --verbose for details.\");\n }\n\n /** Calculate upload timeout: explicit value, or auto-scale from file size (1 MB/s minimum throughput + 30s overhead). */\n function computeUploadTimeout(fileSizeBytes: number): number {\n if (uploadTimeoutExplicit !== undefined) return uploadTimeoutExplicit;\n // Base: 30s overhead + 1s per MB (assumes ~1 MB/s minimum upload speed)\n const sizeMb = fileSizeBytes / (1024 * 1024);\n return Math.max(timeout, 30_000 + Math.ceil(sizeMb) * 1_000);\n }\n\n async function uploadRequest<T>(\n path: string,\n filePath: string,\n contentType: string,\n baseUrl: string = UPLOAD_BASE_URL,\n ): Promise<ApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const safeFilePath = validateFilePath(filePath);\n const fileBuffer = await readFile(safeFilePath);\n const effectiveTimeout = computeUploadTimeout(fileBuffer.byteLength);\n\n // Fetch token once before retries\n let token = await options.auth.getAccessToken();\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = jitteredDelay(baseDelay, attempt - 1, maxDelay);\n await new Promise((r) => setTimeout(r, delay));\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": contentType,\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: fileBuffer,\n signal: controller.signal,\n keepalive: true,\n });\n\n if (response.ok) {\n const text = await response.text();\n const data = text ? (JSON.parse(text) as T) : ({} as T);\n return { data, status: response.status };\n }\n\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n\n const err = new ApiError(\n `POST upload ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n\n if (isRetryable(response.status) && attempt < maxRetries) {\n lastError = err;\n const delay = jitteredDelay(baseDelay, attempt, maxDelay);\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n status: response.status,\n error: err.message,\n delayMs: Math.round(delay),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n\n // On 401, refresh token once before giving up\n if (response.status === 401 && attempt < maxRetries) {\n token = await options.auth.getAccessToken();\n lastError = err;\n continue;\n }\n\n throw err;\n } catch (error) {\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const sizeMb = Math.round(fileBuffer.byteLength / (1024 * 1024));\n const timeoutErr = new ApiError(\n `POST upload ${path} timed out after ${effectiveTimeout}ms (file: ${sizeMb} MB)`,\n \"API_TIMEOUT\",\n undefined,\n `Upload timed out. Set GPC_UPLOAD_TIMEOUT=${effectiveTimeout * 2} (ms) or use --timeout to increase.`,\n );\n if (attempt < maxRetries) {\n lastError = timeoutErr;\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n error: timeoutErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw timeoutErr;\n }\n\n const networkErr = new ApiError(\n `POST upload ${path} failed: ${error instanceof Error ? error.message : String(error)}`,\n \"API_NETWORK_ERROR\",\n undefined,\n \"A network error occurred. Check your internet connection.\",\n );\n if (attempt < maxRetries) {\n lastError = networkErr;\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n error: networkErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw networkErr;\n } finally {\n clearTimeout(timer);\n }\n }\n\n throw lastError ?? new ApiError(\"Upload request failed\", \"API_NETWORK_ERROR\", undefined, \"Check your network connection and try again. Use --verbose for details.\");\n }\n\n return {\n get<T>(path: string, params?: Record<string, string>) {\n return request<T>(\"GET\", path, undefined, params);\n },\n post<T>(path: string, body?: unknown) {\n return request<T>(\"POST\", path, body);\n },\n put<T>(path: string, body?: unknown) {\n return request<T>(\"PUT\", path, body);\n },\n patch<T>(path: string, body?: unknown) {\n return request<T>(\"PATCH\", path, body);\n },\n delete<T>(path: string) {\n return request<T>(\"DELETE\", path);\n },\n upload<T>(path: string, filePath: string, contentType: string) {\n return uploadRequest<T>(path, filePath, contentType);\n },\n uploadInternal<T>(path: string, filePath: string, contentType: string) {\n return uploadRequest<T>(path, filePath, contentType, INTERNAL_SHARING_UPLOAD_BASE_URL);\n },\n async download(path: string): Promise<ArrayBuffer> {\n const url = `${options.baseUrl ?? BASE_URL}${path}`;\n const token = await options.auth.getAccessToken();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n },\n signal: controller.signal,\n keepalive: true,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n throw new ApiError(\n `GET ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n }\n\n return await response.arrayBuffer();\n } finally {\n clearTimeout(timer);\n }\n },\n };\n}\n","import { ApiError } from \"./errors.js\";\nimport { createHttpClient } from \"./http.js\";\nimport type { RateLimiter } from \"./rate-limiter.js\";\nimport type {\n ApiClientOptions,\n AppDetails,\n AppEdit,\n AppRecoveriesListResponse,\n AppRecoveryAction,\n AppRecoveryTargeting,\n CreateAppRecoveryActionRequest,\n BasePlanMigratePricesRequest,\n Bundle,\n BundleListResponse,\n ConvertRegionPricesRequest,\n ConvertRegionPricesResponse,\n CountryAvailability,\n DataSafety,\n DeobfuscationFile,\n DeobfuscationUploadResponse,\n DeviceTierConfig,\n DeviceTierConfigsListResponse,\n ExternalTransaction,\n ExternalTransactionRefund,\n ExternallyHostedApk,\n ExternallyHostedApkResponse,\n Image,\n ImageType,\n ImageUploadResponse,\n ImagesDeleteAllResponse,\n ImagesListResponse,\n InAppProduct,\n InAppProductsListResponse,\n Listing,\n ListingsListResponse,\n OffersListResponse,\n ProductPurchase,\n Release,\n ReportsListResponse,\n ReportType,\n Review,\n ReviewReplyRequest,\n ReviewReplyResponse,\n ReviewsListOptions,\n ReviewsListResponse,\n Subscription,\n SubscriptionDeferRequest,\n SubscriptionDeferResponse,\n SubscriptionOffer,\n SubscriptionPurchase,\n SubscriptionPurchaseV2,\n SubscriptionsListResponse,\n Testers,\n Track,\n TrackListResponse,\n VoidedPurchasesListResponse,\n OneTimeProduct,\n OneTimeProductsListResponse,\n OneTimeOffer,\n OneTimeOffersListResponse,\n InternalAppSharingArtifact,\n GeneratedApk,\n GeneratedApksPerVersion,\n PurchaseOption,\n PurchaseOptionsListResponse,\n InAppProductsBatchUpdateRequest,\n InAppProductsBatchUpdateResponse,\n} from \"./types.js\";\n\nexport interface PlayApiClient {\n edits: {\n insert(packageName: string): Promise<AppEdit>;\n get(packageName: string, editId: string): Promise<AppEdit>;\n validate(packageName: string, editId: string): Promise<AppEdit>;\n commit(packageName: string, editId: string): Promise<AppEdit>;\n delete(packageName: string, editId: string): Promise<void>;\n };\n\n details: {\n get(packageName: string, editId: string): Promise<AppDetails>;\n update(packageName: string, editId: string, details: Partial<AppDetails>): Promise<AppDetails>;\n patch(packageName: string, editId: string, partial: Partial<AppDetails>): Promise<AppDetails>;\n };\n\n bundles: {\n list(packageName: string, editId: string): Promise<Bundle[]>;\n upload(packageName: string, editId: string, filePath: string): Promise<Bundle>;\n };\n\n tracks: {\n list(packageName: string, editId: string): Promise<Track[]>;\n get(packageName: string, editId: string, track: string): Promise<Track>;\n create(packageName: string, editId: string, trackName: string): Promise<Track>;\n update(packageName: string, editId: string, track: string, release: Release): Promise<Track>;\n };\n\n apks: {\n addExternallyHosted(\n packageName: string,\n editId: string,\n data: ExternallyHostedApk,\n ): Promise<ExternallyHostedApkResponse>;\n };\n\n listings: {\n list(packageName: string, editId: string): Promise<Listing[]>;\n get(packageName: string, editId: string, language: string): Promise<Listing>;\n update(\n packageName: string,\n editId: string,\n language: string,\n listing: Omit<Listing, \"language\">,\n ): Promise<Listing>;\n patch(\n packageName: string,\n editId: string,\n language: string,\n partial: Partial<Omit<Listing, \"language\">>,\n ): Promise<Listing>;\n delete(packageName: string, editId: string, language: string): Promise<void>;\n deleteAll(packageName: string, editId: string): Promise<void>;\n };\n\n images: {\n list(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n ): Promise<Image[]>;\n upload(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n filePath: string,\n ): Promise<Image>;\n delete(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n imageId: string,\n ): Promise<void>;\n deleteAll(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n ): Promise<Image[]>;\n };\n\n countryAvailability: {\n get(packageName: string, editId: string, track: string): Promise<CountryAvailability>;\n };\n\n dataSafety: {\n get(packageName: string): Promise<DataSafety>;\n update(packageName: string, data: DataSafety): Promise<DataSafety>;\n };\n\n reviews: {\n list(packageName: string, options?: ReviewsListOptions): Promise<ReviewsListResponse>;\n get(packageName: string, reviewId: string, translationLanguage?: string): Promise<Review>;\n reply(packageName: string, reviewId: string, replyText: string): Promise<ReviewReplyResponse>;\n };\n\n subscriptions: {\n list(\n packageName: string,\n options?: { pageToken?: string; pageSize?: number },\n ): Promise<SubscriptionsListResponse>;\n get(packageName: string, productId: string): Promise<Subscription>;\n create(packageName: string, data: Subscription, productId?: string): Promise<Subscription>;\n update(\n packageName: string,\n productId: string,\n data: Subscription,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<Subscription>;\n delete(packageName: string, productId: string): Promise<void>;\n activateBasePlan(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<Subscription>;\n deactivateBasePlan(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<Subscription>;\n deleteBasePlan(packageName: string, productId: string, basePlanId: string): Promise<void>;\n migratePrices(\n packageName: string,\n productId: string,\n basePlanId: string,\n body: BasePlanMigratePricesRequest,\n ): Promise<Subscription>;\n listOffers(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<OffersListResponse>;\n getOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n createOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n data: SubscriptionOffer,\n offerId?: string,\n ): Promise<SubscriptionOffer>;\n updateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n data: SubscriptionOffer,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<SubscriptionOffer>;\n deleteOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<void>;\n activateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n deactivateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n };\n\n inappproducts: {\n list(\n packageName: string,\n options?: { token?: string; maxResults?: number },\n ): Promise<InAppProductsListResponse>;\n get(packageName: string, sku: string): Promise<InAppProduct>;\n create(packageName: string, data: InAppProduct, options?: { autoConvertMissingPrices?: boolean }): Promise<InAppProduct>;\n update(packageName: string, sku: string, data: InAppProduct, options?: { autoConvertMissingPrices?: boolean; allowMissing?: boolean }): Promise<InAppProduct>;\n delete(packageName: string, sku: string): Promise<void>;\n batchUpdate(\n packageName: string,\n requests: InAppProductsBatchUpdateRequest,\n ): Promise<InAppProductsBatchUpdateResponse>;\n batchGet(packageName: string, skus: string[]): Promise<InAppProduct[]>;\n };\n\n purchases: {\n getProduct(packageName: string, productId: string, token: string): Promise<ProductPurchase>;\n acknowledgeProduct(\n packageName: string,\n productId: string,\n token: string,\n body?: { developerPayload?: string },\n ): Promise<void>;\n consumeProduct(packageName: string, productId: string, token: string): Promise<void>;\n getSubscriptionV2(packageName: string, token: string): Promise<SubscriptionPurchaseV2>;\n getSubscriptionV1(\n packageName: string,\n subscriptionId: string,\n token: string,\n ): Promise<SubscriptionPurchase>;\n cancelSubscription(packageName: string, subscriptionId: string, token: string): Promise<void>;\n deferSubscription(\n packageName: string,\n subscriptionId: string,\n token: string,\n body: SubscriptionDeferRequest,\n ): Promise<SubscriptionDeferResponse>;\n revokeSubscriptionV2(packageName: string, token: string): Promise<void>;\n refundSubscriptionV2(packageName: string, token: string): Promise<void>;\n listVoided(\n packageName: string,\n options?: { startTime?: string; endTime?: string; maxResults?: number; token?: string },\n ): Promise<VoidedPurchasesListResponse>;\n };\n\n orders: {\n refund(\n packageName: string,\n orderId: string,\n body?: { fullRefund?: boolean; proratedRefund?: boolean },\n ): Promise<void>;\n };\n\n monetization: {\n convertRegionPrices(\n packageName: string,\n price: ConvertRegionPricesRequest,\n ): Promise<ConvertRegionPricesResponse>;\n };\n\n reports: {\n list(\n packageName: string,\n reportType: ReportType,\n year: number,\n month: number,\n ): Promise<ReportsListResponse>;\n };\n\n testers: {\n get(packageName: string, editId: string, track: string): Promise<Testers>;\n update(packageName: string, editId: string, track: string, testers: Testers): Promise<Testers>;\n };\n\n deobfuscation: {\n upload(\n packageName: string,\n editId: string,\n versionCode: number,\n filePath: string,\n ): Promise<DeobfuscationFile>;\n };\n\n appRecovery: {\n list(packageName: string, versionCode?: number): Promise<AppRecoveryAction[]>;\n cancel(packageName: string, appRecoveryId: string): Promise<void>;\n deploy(packageName: string, appRecoveryId: string): Promise<void>;\n create(packageName: string, request: CreateAppRecoveryActionRequest): Promise<AppRecoveryAction>;\n addTargeting(packageName: string, appRecoveryId: string, targeting: AppRecoveryTargeting): Promise<AppRecoveryAction>;\n };\n\n externalTransactions: {\n create(packageName: string, data: ExternalTransaction): Promise<ExternalTransaction>;\n get(packageName: string, transactionId: string): Promise<ExternalTransaction>;\n refund(\n packageName: string,\n transactionId: string,\n refundData: ExternalTransactionRefund,\n ): Promise<ExternalTransaction>;\n };\n\n deviceTiers: {\n list(packageName: string): Promise<DeviceTierConfig[]>;\n get(packageName: string, configId: string): Promise<DeviceTierConfig>;\n create(packageName: string, config: DeviceTierConfig): Promise<DeviceTierConfig>;\n };\n\n oneTimeProducts: {\n list(packageName: string): Promise<OneTimeProductsListResponse>;\n get(packageName: string, productId: string): Promise<OneTimeProduct>;\n create(packageName: string, product: OneTimeProduct): Promise<OneTimeProduct>;\n update(\n packageName: string,\n productId: string,\n product: Partial<OneTimeProduct>,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<OneTimeProduct>;\n delete(packageName: string, productId: string): Promise<void>;\n listOffers(packageName: string, productId: string): Promise<OneTimeOffersListResponse>;\n getOffer(\n packageName: string,\n productId: string,\n offerId: string,\n ): Promise<OneTimeOffer>;\n createOffer(\n packageName: string,\n productId: string,\n offer: OneTimeOffer,\n ): Promise<OneTimeOffer>;\n updateOffer(\n packageName: string,\n productId: string,\n offerId: string,\n offer: Partial<OneTimeOffer>,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<OneTimeOffer>;\n deleteOffer(\n packageName: string,\n productId: string,\n offerId: string,\n ): Promise<void>;\n };\n\n purchaseOptions: {\n list(packageName: string): Promise<PurchaseOptionsListResponse>;\n get(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n create(packageName: string, data: PurchaseOption): Promise<PurchaseOption>;\n activate(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n deactivate(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n };\n\n internalAppSharing: {\n uploadBundle(packageName: string, bundlePath: string): Promise<InternalAppSharingArtifact>;\n uploadApk(packageName: string, apkPath: string): Promise<InternalAppSharingArtifact>;\n };\n\n generatedApks: {\n list(packageName: string, versionCode: number): Promise<GeneratedApk[]>;\n download(packageName: string, versionCode: number, id: string): Promise<ArrayBuffer>;\n };\n}\n\nasync function rateLimit(limiter: RateLimiter | undefined, bucket: string): Promise<void> {\n if (limiter) await limiter.acquire(bucket);\n}\n\nexport function createApiClient(options: ApiClientOptions): PlayApiClient {\n const http = createHttpClient(options);\n const limiter = options.rateLimiter || undefined;\n\n return {\n edits: {\n async insert(packageName) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits`);\n return data;\n },\n\n async get(packageName, editId) {\n const { data } = await http.get<AppEdit>(`/${packageName}/edits/${editId}`);\n return data;\n },\n\n async validate(packageName, editId) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits/${editId}:validate`);\n return data;\n },\n\n async commit(packageName, editId) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits/${editId}:commit`);\n return data;\n },\n\n async delete(packageName, editId) {\n await http.delete(`/${packageName}/edits/${editId}`);\n },\n },\n\n details: {\n async get(packageName, editId) {\n const { data } = await http.get<AppDetails>(`/${packageName}/edits/${editId}/details`);\n return data;\n },\n\n async update(packageName, editId, details) {\n const { data } = await http.put<AppDetails>(\n `/${packageName}/edits/${editId}/details`,\n details,\n );\n return data;\n },\n\n async patch(packageName, editId, partial) {\n const { data } = await http.patch<AppDetails>(\n `/${packageName}/edits/${editId}/details`,\n partial,\n );\n return data;\n },\n },\n\n bundles: {\n async list(packageName, editId) {\n const { data } = await http.get<BundleListResponse>(\n `/${packageName}/edits/${editId}/bundles`,\n );\n return data.bundles;\n },\n\n async upload(packageName, editId, filePath) {\n const { data } = await http.upload<Bundle>(\n `/${packageName}/edits/${editId}/bundles`,\n filePath,\n \"application/octet-stream\",\n );\n if (!data || !data.versionCode) {\n throw new ApiError(\n \"Upload succeeded but no bundle data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data;\n },\n },\n\n tracks: {\n async list(packageName, editId) {\n const { data } = await http.get<TrackListResponse>(\n `/${packageName}/edits/${editId}/tracks`,\n );\n return data.tracks;\n },\n\n async get(packageName, editId, track) {\n const { data } = await http.get<Track>(`/${packageName}/edits/${editId}/tracks/${track}`);\n return data;\n },\n\n async create(packageName, editId, trackName) {\n const { data } = await http.post<Track>(`/${packageName}/edits/${editId}/tracks`, {\n track: trackName,\n });\n return data;\n },\n\n async update(packageName, editId, track, release) {\n const { data } = await http.put<Track>(`/${packageName}/edits/${editId}/tracks/${track}`, {\n track,\n releases: [release],\n });\n return data;\n },\n },\n\n apks: {\n async addExternallyHosted(packageName, editId, apkData) {\n const { data } = await http.post<ExternallyHostedApkResponse>(\n `/${packageName}/edits/${editId}/apks/externallyHosted`,\n { externallyHostedApk: apkData },\n );\n return data;\n },\n },\n\n listings: {\n async list(packageName, editId) {\n const { data } = await http.get<ListingsListResponse>(\n `/${packageName}/edits/${editId}/listings`,\n );\n return data.listings || [];\n },\n\n async get(packageName, editId, language) {\n const { data } = await http.get<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n );\n return data;\n },\n\n async update(packageName, editId, language, listing) {\n const { data } = await http.put<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n listing,\n );\n return data;\n },\n\n async patch(packageName, editId, language, partial) {\n const { data } = await http.patch<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n partial,\n );\n return data;\n },\n\n async delete(packageName, editId, language) {\n await http.delete(`/${packageName}/edits/${editId}/listings/${language}`);\n },\n\n async deleteAll(packageName, editId) {\n await http.delete(`/${packageName}/edits/${editId}/listings`);\n },\n },\n\n images: {\n async list(packageName, editId, language, imageType) {\n const { data } = await http.get<ImagesListResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n );\n return data.images || [];\n },\n\n async upload(packageName, editId, language, imageType, filePath) {\n const { data } = await http.upload<ImageUploadResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n filePath,\n filePath.endsWith(\".png\") ? \"image/png\" : \"image/jpeg\",\n );\n if (!data.image) {\n throw new ApiError(\n \"Upload succeeded but no image data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data.image;\n },\n\n async delete(packageName, editId, language, imageType, imageId) {\n await http.delete(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}/${imageId}`,\n );\n },\n\n async deleteAll(packageName, editId, language, imageType) {\n const { data } = await http.delete<ImagesDeleteAllResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n );\n return data.deleted || [];\n },\n },\n\n countryAvailability: {\n async get(packageName, editId, track) {\n const { data } = await http.get<CountryAvailability>(\n `/${packageName}/edits/${editId}/countryAvailability/${track}`,\n );\n return data;\n },\n },\n\n dataSafety: {\n async get(packageName) {\n const { data } = await http.get<DataSafety>(\n `/${packageName}/dataSafety`,\n );\n return data;\n },\n\n async update(packageName, body) {\n const { data } = await http.put<DataSafety>(\n `/${packageName}/dataSafety`,\n body,\n );\n return data;\n },\n },\n\n reviews: {\n async list(packageName, options?) {\n await rateLimit(limiter, \"reviewsGet\");\n const params: Record<string, string> = {};\n if (options?.token) params[\"token\"] = options.token;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n if (options?.translationLanguage)\n params[\"translationLanguage\"] = options.translationLanguage;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<ReviewsListResponse>(\n `/${packageName}/reviews`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, reviewId, translationLanguage?) {\n await rateLimit(limiter, \"reviewsGet\");\n const params: Record<string, string> = {};\n if (translationLanguage) params[\"translationLanguage\"] = translationLanguage;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<Review>(\n `/${packageName}/reviews/${reviewId}`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async reply(packageName, reviewId, replyText) {\n await rateLimit(limiter, \"reviewsPost\");\n const body: ReviewReplyRequest = { replyText };\n const { data } = await http.post<ReviewReplyResponse>(\n `/${packageName}/reviews/${reviewId}:reply`,\n body,\n );\n return data;\n },\n },\n\n subscriptions: {\n async list(packageName, options?) {\n const params: Record<string, string> = {};\n if (options?.pageToken) params[\"pageToken\"] = options.pageToken;\n if (options?.pageSize) params[\"pageSize\"] = String(options.pageSize);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<SubscriptionsListResponse>(\n `/${packageName}/subscriptions`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, productId) {\n const { data } = await http.get<Subscription>(\n `/${packageName}/subscriptions/${productId}`,\n );\n return data;\n },\n\n async create(packageName, body, productId?) {\n const params: Record<string, string> = {};\n if (productId) params[\"productId\"] = productId;\n params[\"regionsVersion.version\"] = \"2022/02\";\n const path = `/${packageName}/subscriptions?${new URLSearchParams(params).toString()}`;\n const { data } = await http.post<Subscription>(path, body);\n return data;\n },\n\n async update(packageName, productId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<Subscription>(path, body);\n return data;\n },\n\n async delete(packageName, productId) {\n await http.delete(`/${packageName}/subscriptions/${productId}`);\n },\n\n async activateBasePlan(packageName, productId, basePlanId) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:activate`,\n );\n return data;\n },\n\n async deactivateBasePlan(packageName, productId, basePlanId) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:deactivate`,\n );\n return data;\n },\n\n async deleteBasePlan(packageName, productId, basePlanId) {\n await http.delete(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}`,\n );\n },\n\n async migratePrices(packageName, productId, basePlanId, body) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:migratePrices`,\n body,\n );\n return data;\n },\n\n async listOffers(packageName, productId, basePlanId) {\n const { data } = await http.get<OffersListResponse>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers`,\n );\n return data;\n },\n\n async getOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.get<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}`,\n );\n return data;\n },\n\n async createOffer(packageName, productId, basePlanId, body, offerId?) {\n const params: Record<string, string> = {};\n if (offerId) params[\"offerId\"] = offerId;\n params[\"regionsVersion.version\"] = \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers?${new URLSearchParams(params).toString()}`;\n const { data } = await http.post<SubscriptionOffer>(path, body);\n return data;\n },\n\n async updateOffer(packageName, productId, basePlanId, offerId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<SubscriptionOffer>(path, body);\n return data;\n },\n\n async deleteOffer(packageName, productId, basePlanId, offerId) {\n await http.delete(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}`,\n );\n },\n\n async activateOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.post<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}:activate`,\n );\n return data;\n },\n\n async deactivateOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.post<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}:deactivate`,\n );\n return data;\n },\n },\n\n inappproducts: {\n async list(packageName, options?) {\n const params: Record<string, string> = {};\n if (options?.token) params[\"token\"] = options.token;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<InAppProductsListResponse>(\n `/${packageName}/inappproducts`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, sku) {\n const { data } = await http.get<InAppProduct>(`/${packageName}/inappproducts/${sku}`);\n return data;\n },\n\n async create(packageName, body, options?) {\n const params: Record<string, string> = {};\n if (options?.autoConvertMissingPrices) params[\"autoConvertMissingPrices\"] = \"true\";\n const hasParams = Object.keys(params).length > 0;\n const path = hasParams\n ? `/${packageName}/inappproducts?${new URLSearchParams(params).toString()}`\n : `/${packageName}/inappproducts`;\n const { data } = await http.post<InAppProduct>(path, body);\n return data;\n },\n\n async update(packageName, sku, body, options?) {\n const params: Record<string, string> = {};\n if (options?.autoConvertMissingPrices) params[\"autoConvertMissingPrices\"] = \"true\";\n if (options?.allowMissing) params[\"allowMissing\"] = \"true\";\n const hasParams = Object.keys(params).length > 0;\n const path = hasParams\n ? `/${packageName}/inappproducts/${sku}?${new URLSearchParams(params).toString()}`\n : `/${packageName}/inappproducts/${sku}`;\n const { data } = await http.put<InAppProduct>(path, body);\n return data;\n },\n\n async delete(packageName, sku) {\n await http.delete(`/${packageName}/inappproducts/${sku}`);\n },\n\n async batchUpdate(packageName, requests) {\n const { data } = await http.post<InAppProductsBatchUpdateResponse>(\n `/${packageName}/inappproducts:batchUpdate`,\n requests,\n );\n return data;\n },\n\n async batchGet(packageName, skus) {\n const params: Record<string, string> = {};\n if (skus.length > 0) {\n params[\"sku\"] = skus.join(\",\");\n }\n const { data } = await http.get<{ inappproduct: InAppProduct[] }>(\n `/${packageName}/inappproducts:batchGet`,\n Object.keys(params).length > 0 ? params : undefined,\n );\n return data.inappproduct || [];\n },\n },\n\n purchases: {\n async getProduct(packageName, productId, token) {\n const { data } = await http.get<ProductPurchase>(\n `/${packageName}/purchases/products/${productId}/tokens/${token}`,\n );\n return data;\n },\n\n async acknowledgeProduct(packageName, productId, token, body?) {\n await http.post(\n `/${packageName}/purchases/products/${productId}/tokens/${token}:acknowledge`,\n body,\n );\n },\n\n async consumeProduct(packageName, productId, token) {\n await http.post(`/${packageName}/purchases/products/${productId}/tokens/${token}:consume`);\n },\n\n async getSubscriptionV2(packageName, token) {\n const { data } = await http.get<SubscriptionPurchaseV2>(\n `/${packageName}/purchases/subscriptionsv2/tokens/${token}`,\n );\n return data;\n },\n\n async getSubscriptionV1(packageName, subscriptionId, token) {\n const { data } = await http.get<SubscriptionPurchase>(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}`,\n );\n return data;\n },\n\n async cancelSubscription(packageName, subscriptionId, token) {\n await http.post(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}:cancel`,\n );\n },\n\n async deferSubscription(packageName, subscriptionId, token, body) {\n const { data } = await http.post<SubscriptionDeferResponse>(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}:defer`,\n body,\n );\n return data;\n },\n\n async revokeSubscriptionV2(packageName, token) {\n await http.post(`/${packageName}/purchases/subscriptionsv2/tokens/${token}:revoke`);\n },\n\n async refundSubscriptionV2(packageName, token) {\n await http.post(`/${packageName}/purchases/subscriptionsv2/tokens/${token}:refund`);\n },\n\n async listVoided(packageName, options?) {\n await rateLimit(limiter, \"voidedBurst\");\n await rateLimit(limiter, \"voidedDaily\");\n const params: Record<string, string> = {};\n if (options?.startTime) params[\"startTime\"] = options.startTime;\n if (options?.endTime) params[\"endTime\"] = options.endTime;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n if (options?.token) params[\"token\"] = options.token;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<VoidedPurchasesListResponse>(\n `/${packageName}/purchases/voidedpurchases`,\n hasParams ? params : undefined,\n );\n return data;\n },\n },\n\n orders: {\n async refund(packageName, orderId, body?) {\n await http.post(`/${packageName}/orders/${orderId}:refund`, body);\n },\n },\n\n monetization: {\n async convertRegionPrices(packageName, price) {\n const { data } = await http.post<ConvertRegionPricesResponse>(\n `/${packageName}/pricing:convertRegionPrices`,\n price,\n );\n return data;\n },\n },\n\n reports: {\n async list(packageName, reportType, year, month) {\n const monthStr = String(month).padStart(2, \"0\");\n const { data } = await http.get<ReportsListResponse>(\n `/${packageName}/reports/${reportType}/${year}/${monthStr}`,\n );\n return data;\n },\n },\n\n testers: {\n async get(packageName, editId, track) {\n const { data } = await http.get<Testers>(\n `/${packageName}/edits/${editId}/testers/${track}`,\n );\n return data;\n },\n\n async update(packageName, editId, track, testersData) {\n const { data } = await http.put<Testers>(\n `/${packageName}/edits/${editId}/testers/${track}`,\n testersData,\n );\n return data;\n },\n },\n\n deobfuscation: {\n async upload(packageName, editId, versionCode, filePath) {\n const { data } = await http.upload<DeobfuscationUploadResponse>(\n `/${packageName}/edits/${editId}/apks/${versionCode}/deobfuscationFiles/proguard`,\n filePath,\n \"application/octet-stream\",\n );\n if (!data.deobfuscationFile) {\n throw new ApiError(\n \"Upload succeeded but no deobfuscation file data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data.deobfuscationFile;\n },\n },\n\n appRecovery: {\n async list(packageName, versionCode?) {\n const params: Record<string, string> = {};\n if (versionCode !== undefined) params[\"versionCode\"] = String(versionCode);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<AppRecoveriesListResponse>(\n `/${packageName}/appRecoveries`,\n hasParams ? params : undefined,\n );\n return data.recoveryActions || [];\n },\n\n async cancel(packageName, appRecoveryId) {\n await http.post(`/${packageName}/appRecovery/${appRecoveryId}:cancel`);\n },\n\n async deploy(packageName, appRecoveryId) {\n await http.post(`/${packageName}/appRecovery/${appRecoveryId}:deploy`);\n },\n\n async create(packageName, request) {\n const { data } = await http.post<AppRecoveryAction>(\n `/${packageName}/appRecoveries`,\n request,\n );\n return data;\n },\n\n async addTargeting(packageName, appRecoveryId, targeting) {\n const { data } = await http.post<AppRecoveryAction>(\n `/${packageName}/appRecoveries/${appRecoveryId}:addTargeting`,\n targeting,\n );\n return data;\n },\n },\n\n externalTransactions: {\n async create(packageName, body) {\n const { data } = await http.post<ExternalTransaction>(\n `/${packageName}/externalTransactions`,\n body,\n );\n return data;\n },\n\n async get(packageName, transactionId) {\n const { data } = await http.get<ExternalTransaction>(\n `/${packageName}/externalTransactions/${transactionId}`,\n );\n return data;\n },\n\n async refund(packageName, transactionId, refundData) {\n const { data } = await http.post<ExternalTransaction>(\n `/${packageName}/externalTransactions/${transactionId}:refund`,\n refundData,\n );\n return data;\n },\n },\n\n deviceTiers: {\n async list(packageName) {\n const { data } = await http.get<DeviceTierConfigsListResponse>(\n `/${packageName}/deviceTierConfigs`,\n );\n return data.deviceTierConfigs || [];\n },\n\n async get(packageName, configId) {\n const { data } = await http.get<DeviceTierConfig>(\n `/${packageName}/deviceTierConfigs/${configId}`,\n );\n return data;\n },\n\n async create(packageName, config) {\n const { data } = await http.post<DeviceTierConfig>(\n `/${packageName}/deviceTierConfigs`,\n config,\n );\n return data;\n },\n },\n\n oneTimeProducts: {\n async list(packageName) {\n const { data } = await http.get<OneTimeProductsListResponse>(\n `/${packageName}/oneTimeProducts`,\n );\n return data;\n },\n\n async get(packageName, productId) {\n const { data } = await http.get<OneTimeProduct>(\n `/${packageName}/oneTimeProducts/${productId}`,\n );\n return data;\n },\n\n async create(packageName, body) {\n const params = new URLSearchParams({ \"regionsVersion.version\": \"2022/02\" });\n const { data } = await http.post<OneTimeProduct>(\n `/${packageName}/oneTimeProducts?${params.toString()}`,\n body,\n );\n return data;\n },\n\n async update(packageName, productId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/oneTimeProducts/${productId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<OneTimeProduct>(path, body);\n return data;\n },\n\n async delete(packageName, productId) {\n await http.delete(`/${packageName}/oneTimeProducts/${productId}`);\n },\n\n async listOffers(packageName, productId) {\n const { data } = await http.get<OneTimeOffersListResponse>(\n `/${packageName}/oneTimeProducts/${productId}/offers`,\n );\n return data;\n },\n\n async getOffer(packageName, productId, offerId) {\n const { data } = await http.get<OneTimeOffer>(\n `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`,\n );\n return data;\n },\n\n async createOffer(packageName, productId, body) {\n const { data } = await http.post<OneTimeOffer>(\n `/${packageName}/oneTimeProducts/${productId}/offers`,\n body,\n );\n return data;\n },\n\n async updateOffer(packageName, productId, offerId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<OneTimeOffer>(path, body);\n return data;\n },\n\n async deleteOffer(packageName, productId, offerId) {\n await http.delete(`/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`);\n },\n },\n\n purchaseOptions: {\n async list(packageName) {\n const { data } = await http.get<PurchaseOptionsListResponse>(\n `/${packageName}/purchaseOptions`,\n );\n return data;\n },\n\n async get(packageName, purchaseOptionId) {\n const { data } = await http.get<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}`,\n );\n return data;\n },\n\n async create(packageName, body) {\n const { data } = await http.post<PurchaseOption>(\n `/${packageName}/purchaseOptions`,\n body,\n );\n return data;\n },\n\n async activate(packageName, purchaseOptionId) {\n const { data } = await http.post<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}:activate`,\n );\n return data;\n },\n\n async deactivate(packageName, purchaseOptionId) {\n const { data } = await http.post<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}:deactivate`,\n );\n return data;\n },\n },\n\n internalAppSharing: {\n async uploadBundle(packageName, bundlePath) {\n const { data } = await http.uploadInternal<InternalAppSharingArtifact>(\n `/${packageName}/artifacts/bundle`,\n bundlePath,\n \"application/octet-stream\",\n );\n return data;\n },\n\n async uploadApk(packageName, apkPath) {\n const { data } = await http.uploadInternal<InternalAppSharingArtifact>(\n `/${packageName}/artifacts/apk`,\n apkPath,\n \"application/vnd.android.package-archive\",\n );\n return data;\n },\n },\n\n generatedApks: {\n async list(packageName, versionCode) {\n const { data } = await http.get<GeneratedApksPerVersion>(\n `/${packageName}/generatedApks/${versionCode}`,\n );\n return data.generatedApks || [];\n },\n\n async download(packageName, versionCode, id) {\n return http.download(\n `/${packageName}/generatedApks/${versionCode}/download/${id}`,\n );\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type {\n AnomalyDetectionResponse,\n ApiClientOptions,\n ErrorIssuesResponse,\n ErrorReportsResponse,\n MetricSetQuery,\n MetricSetResponse,\n VitalsMetricSet,\n} from \"./types.js\";\n\nconst REPORTING_BASE_URL = \"https://playdeveloperreporting.googleapis.com/v1beta1\";\n\nexport interface ReportingApiClient {\n queryMetricSet(\n packageName: string,\n metricSet: VitalsMetricSet,\n query: MetricSetQuery,\n ): Promise<MetricSetResponse>;\n\n getAnomalies(packageName: string): Promise<AnomalyDetectionResponse>;\n\n searchErrorIssues(\n packageName: string,\n filter?: string,\n pageSize?: number,\n pageToken?: string,\n ): Promise<ErrorIssuesResponse>;\n\n searchErrorReports(\n packageName: string,\n issueName: string,\n pageSize?: number,\n pageToken?: string,\n ): Promise<ErrorReportsResponse>;\n}\n\nexport function createReportingClient(options: ApiClientOptions): ReportingApiClient {\n const http = createHttpClient({ ...options, baseUrl: REPORTING_BASE_URL });\n\n return {\n async queryMetricSet(packageName, metricSet, query) {\n const { data } = await http.post<MetricSetResponse>(\n `/apps/${packageName}/${metricSet}:query`,\n query,\n );\n return data;\n },\n\n async getAnomalies(packageName) {\n const { data } = await http.get<AnomalyDetectionResponse>(`/apps/${packageName}/anomalies`);\n return data;\n },\n\n async searchErrorIssues(packageName, filter?, pageSize?, pageToken?) {\n const params: Record<string, string> = {};\n if (filter) params[\"filter\"] = filter;\n if (pageSize) params[\"pageSize\"] = String(pageSize);\n if (pageToken) params[\"pageToken\"] = pageToken;\n const { data } = await http.get<ErrorIssuesResponse>(\n `/apps/${packageName}/errorIssues:search`,\n params,\n );\n return data;\n },\n\n async searchErrorReports(packageName, issueName, pageSize?, pageToken?) {\n const params: Record<string, string> = {};\n if (pageSize) params[\"pageSize\"] = String(pageSize);\n if (pageToken) params[\"pageToken\"] = pageToken;\n const { data } = await http.get<ErrorReportsResponse>(\n `/apps/${packageName}/errorIssues/${issueName}/reports`,\n params,\n );\n return data;\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions, User, UsersListResponse, Grant } from \"./types.js\";\n\nconst USERS_BASE_URL = \"https://androidpublisher.googleapis.com/androidpublisher/v3/developers\";\n\nexport interface GrantsListResponse {\n grants: Grant[];\n nextPageToken?: string;\n}\n\nexport interface UsersApiClient {\n list(\n developerId: string,\n options?: { pageToken?: string; pageSize?: number },\n ): Promise<UsersListResponse>;\n\n get(developerId: string, userId: string): Promise<User>;\n\n create(developerId: string, user: Partial<User>): Promise<User>;\n\n update(\n developerId: string,\n userId: string,\n user: Partial<User>,\n updateMask?: string,\n ): Promise<User>;\n\n delete(developerId: string, userId: string): Promise<void>;\n\n grants: {\n list(developerId: string, email: string): Promise<GrantsListResponse>;\n create(developerId: string, email: string, grant: Partial<Grant>): Promise<Grant>;\n patch(\n developerId: string,\n email: string,\n packageName: string,\n grant: Partial<Grant>,\n updateMask?: string,\n ): Promise<Grant>;\n delete(developerId: string, email: string, packageName: string): Promise<void>;\n };\n}\n\nexport function createUsersClient(options: ApiClientOptions): UsersApiClient {\n const http = createHttpClient({ ...options, baseUrl: USERS_BASE_URL });\n\n return {\n async list(developerId, listOptions?) {\n const params: Record<string, string> = {};\n if (listOptions?.pageToken) params[\"pageToken\"] = listOptions.pageToken;\n if (listOptions?.pageSize) params[\"pageSize\"] = String(listOptions.pageSize);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<UsersListResponse>(\n `/${developerId}/users`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(developerId, userId) {\n const { data } = await http.get<User>(`/${developerId}/users/${userId}`);\n return data;\n },\n\n async create(developerId, user) {\n const { data } = await http.post<User>(`/${developerId}/users`, user);\n return data;\n },\n\n async update(developerId, userId, user, updateMask?) {\n let path = `/${developerId}/users/${userId}`;\n if (updateMask) {\n path += `?updateMask=${encodeURIComponent(updateMask).replace(/%2C/gi, \",\")}`;\n }\n const { data } = await http.patch<User>(path, user);\n return data;\n },\n\n async delete(developerId, userId) {\n await http.delete(`/${developerId}/users/${userId}`);\n },\n\n grants: {\n async list(developerId, email) {\n const { data } = await http.get<GrantsListResponse>(\n `/${developerId}/users/${encodeURIComponent(email)}/grants`,\n );\n return data;\n },\n\n async create(developerId, email, grant) {\n const { data } = await http.post<Grant>(\n `/${developerId}/users/${encodeURIComponent(email)}/grants`,\n grant,\n );\n return data;\n },\n\n async patch(developerId, email, packageName, grant, updateMask?) {\n let path = `/${developerId}/users/${encodeURIComponent(email)}/grants/${encodeURIComponent(packageName)}`;\n if (updateMask) {\n path += `?updateMask=${encodeURIComponent(updateMask)}`;\n }\n const { data } = await http.patch<Grant>(path, grant);\n return data;\n },\n\n async delete(developerId, email, packageName) {\n await http.delete(\n `/${developerId}/users/${encodeURIComponent(email)}/grants/${encodeURIComponent(packageName)}`,\n );\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions } from \"./types.js\";\n\nconst GAMES_BASE_URL = \"https://games.googleapis.com/games/v1\";\n\nexport interface Leaderboard {\n id: string;\n name: string;\n order: string;\n iconUrl?: string;\n}\n\nexport interface LeaderboardScore {\n leaderboardId: string;\n scoreValue: string;\n formattedScore: string;\n writeTimestamp?: string;\n tag?: string;\n}\n\nexport interface Achievement {\n id: string;\n name: string;\n description: string;\n state: \"REVEALED\" | \"HIDDEN\" | \"UNLOCKED\";\n currentSteps?: number;\n totalSteps?: number;\n experiencePoints?: number;\n formattedCurrentStepsString?: string;\n}\n\nexport interface GameEvent {\n definitionId: string;\n numEvents: string;\n formattedNumEvents: string;\n kind?: string;\n}\n\nexport interface GamesApiClient {\n leaderboards: {\n list(packageName: string): Promise<{ items?: Leaderboard[]; nextPageToken?: string }>;\n get(packageName: string, leaderboardId: string): Promise<Leaderboard>;\n getScores(\n packageName: string,\n leaderboardId: string,\n collection: string,\n timeSpan: string,\n ): Promise<{ items?: LeaderboardScore[] }>;\n };\n achievements: {\n list(packageName: string): Promise<{ items?: Achievement[]; nextPageToken?: string }>;\n reveal(packageName: string, achievementId: string): Promise<{ currentState: string }>;\n };\n events: {\n list(packageName: string): Promise<{ items?: GameEvent[]; nextPageToken?: string }>;\n };\n}\n\nexport function createGamesClient(options: ApiClientOptions): GamesApiClient {\n const http = createHttpClient({ ...options, baseUrl: GAMES_BASE_URL });\n\n return {\n leaderboards: {\n async list(packageName) {\n const { data } = await http.get<{ items?: Leaderboard[]; nextPageToken?: string }>(\n `/leaderboards?applicationId=${packageName}`,\n );\n return data;\n },\n async get(packageName, leaderboardId) {\n const { data } = await http.get<Leaderboard>(\n `/leaderboards/${leaderboardId}?applicationId=${packageName}`,\n );\n return data;\n },\n async getScores(packageName, leaderboardId, collection, timeSpan) {\n const { data } = await http.get<{ items?: LeaderboardScore[] }>(\n `/leaderboards/${leaderboardId}/scores/${collection}?timeSpan=${timeSpan}&applicationId=${packageName}`,\n );\n return data;\n },\n },\n achievements: {\n async list(packageName) {\n const { data } = await http.get<{ items?: Achievement[]; nextPageToken?: string }>(\n `/achievements?applicationId=${packageName}`,\n );\n return data;\n },\n async reveal(packageName, achievementId) {\n const { data } = await http.post<{ currentState: string }>(\n `/achievements/${achievementId}/reveal?applicationId=${packageName}`,\n {},\n );\n return data;\n },\n },\n events: {\n async list(packageName) {\n const { data } = await http.get<{ items?: GameEvent[]; nextPageToken?: string }>(\n `/events?applicationId=${packageName}`,\n );\n return data;\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions } from \"./types.js\";\n\nconst ENTERPRISE_BASE_URL = \"https://playcustomapp.googleapis.com/playcustomapp/v1/organizations\";\n\nexport interface CustomApp {\n packageName?: string;\n title: string;\n languageCode?: string;\n organizations?: Array<{ organizationId: string; organizationName?: string }>;\n}\n\nexport interface CustomAppsListResponse {\n customApps?: CustomApp[];\n nextPageToken?: string;\n}\n\nexport interface EnterpriseApiClient {\n apps: {\n create(\n organizationId: string,\n app: Partial<CustomApp>,\n ): Promise<CustomApp>;\n list(organizationId: string): Promise<CustomAppsListResponse>;\n };\n}\n\nexport function createEnterpriseClient(options: ApiClientOptions): EnterpriseApiClient {\n const http = createHttpClient({ ...options, baseUrl: ENTERPRISE_BASE_URL });\n\n return {\n apps: {\n async create(organizationId, app) {\n const { data } = await http.post<CustomApp>(\n `/${organizationId}/apps`,\n app,\n );\n return data;\n },\n async list(organizationId) {\n const { data } = await http.get<CustomAppsListResponse>(\n `/${organizationId}/apps`,\n );\n return data;\n },\n },\n };\n}\n","export interface RateLimitBucket {\n name: string;\n maxTokens: number;\n refillRate: number;\n refillIntervalMs: number;\n}\n\nexport interface RateLimiter {\n acquire(bucket: string): Promise<void>;\n}\n\ninterface BucketState {\n tokens: number;\n lastRefillTime: number;\n config: RateLimitBucket;\n}\n\nexport const RATE_LIMIT_BUCKETS: Record<string, RateLimitBucket> = {\n default: { name: \"default\", maxTokens: 200, refillRate: 200, refillIntervalMs: 1_000 },\n reviewsGet: { name: \"reviewsGet\", maxTokens: 200, refillRate: 200, refillIntervalMs: 3_600_000 },\n reviewsPost: {\n name: \"reviewsPost\",\n maxTokens: 2_000,\n refillRate: 2_000,\n refillIntervalMs: 86_400_000,\n },\n voidedBurst: { name: \"voidedBurst\", maxTokens: 30, refillRate: 30, refillIntervalMs: 30_000 },\n voidedDaily: {\n name: \"voidedDaily\",\n maxTokens: 6_000,\n refillRate: 6_000,\n refillIntervalMs: 86_400_000,\n },\n};\n\nexport function createRateLimiter(buckets?: RateLimitBucket[]): RateLimiter {\n const states = new Map<string, BucketState>();\n\n if (buckets) {\n for (const bucket of buckets) {\n states.set(bucket.name, {\n tokens: bucket.maxTokens,\n lastRefillTime: Date.now(),\n config: bucket,\n });\n }\n }\n\n return {\n async acquire(bucket: string): Promise<void> {\n const state = states.get(bucket);\n if (!state) return;\n\n const now = Date.now();\n const elapsed = now - state.lastRefillTime;\n const refill = Math.floor(\n (elapsed / state.config.refillIntervalMs) * state.config.refillRate,\n );\n\n if (refill > 0) {\n state.tokens = Math.min(state.config.maxTokens, state.tokens + refill);\n state.lastRefillTime = now;\n }\n\n if (state.tokens > 0) {\n state.tokens--;\n return;\n }\n\n const tokensNeeded = 1;\n const waitMs = Math.ceil(\n (tokensNeeded / state.config.refillRate) * state.config.refillIntervalMs,\n );\n await new Promise((r) => setTimeout(r, waitMs));\n\n // Recalculate refill based on actual elapsed time since last refill\n const afterWait = Date.now();\n const totalElapsed = afterWait - state.lastRefillTime;\n const newTokens = Math.floor(\n (totalElapsed / state.config.refillIntervalMs) * state.config.refillRate,\n );\n state.tokens = Math.min(state.config.maxTokens, newTokens) - 1;\n state.lastRefillTime = afterWait;\n },\n };\n}\n","export interface PaginateOptions {\n limit?: number;\n startPageToken?: string;\n}\n\nexport async function* paginate<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n options?: PaginateOptions,\n): AsyncGenerator<TItem[], void, unknown> {\n let pageToken = options?.startPageToken;\n let collected = 0;\n const limit = options?.limit;\n\n for (;;) {\n if (limit !== undefined && collected >= limit) break;\n\n const page = await fetchPage(pageToken);\n const items = page.items;\n\n if (items.length === 0) break;\n\n if (limit !== undefined) {\n const remaining = limit - collected;\n if (items.length > remaining) {\n yield items.slice(0, remaining);\n return;\n }\n }\n\n yield items;\n collected += items.length;\n pageToken = page.nextPageToken;\n\n if (!pageToken) break;\n }\n}\n\nexport async function paginateAll<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n options?: PaginateOptions,\n): Promise<{ items: TItem[]; nextPageToken?: string }> {\n const allItems: TItem[] = [];\n let lastPageToken: string | undefined;\n const limit = options?.limit;\n\n for await (const items of paginate(fetchPage, options)) {\n allItems.push(...items);\n if (limit !== undefined && allItems.length >= limit) break;\n }\n\n // If we stopped due to limit, try to get the next page token for resumption\n if (limit !== undefined && allItems.length >= limit) {\n lastPageToken = undefined; // Already truncated by paginate\n }\n\n return { items: allItems, nextPageToken: lastPageToken };\n}\n\n/**\n * Fetch multiple known pages in parallel.\n * Useful when page tokens are predictable or when pre-fetching subsequent pages\n * after an initial sequential fetch reveals the token pattern.\n *\n * @param fetchPage - Function that fetches a page given a token\n * @param pageTokens - Array of page tokens to fetch concurrently\n * @param concurrency - Max concurrent requests (default: 4)\n */\nexport async function paginateParallel<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n pageTokens: string[],\n concurrency = 4,\n): Promise<{ items: TItem[]; nextPageToken?: string }> {\n const allItems: TItem[] = [];\n let lastNextPageToken: string | undefined;\n\n // Process in batches of `concurrency`\n for (let i = 0; i < pageTokens.length; i += concurrency) {\n const batch = pageTokens.slice(i, i + concurrency);\n const results = await Promise.all(batch.map((token) => fetchPage(token)));\n\n for (const result of results) {\n allItems.push(...result.items);\n if (result.nextPageToken) {\n lastNextPageToken = result.nextPageToken;\n }\n }\n }\n\n return { items: allItems, nextPageToken: lastNextPageToken };\n}\n"],"mappings":"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","names":["options"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/client.ts","../src/reporting-client.ts","../src/users-client.ts","../src/games-client.ts","../src/enterprise-client.ts","../src/rate-limiter.ts","../src/paginate.ts"],"sourcesContent":["export class PlayApiError extends Error {\n public readonly exitCode = 4;\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number,\n public readonly suggestion?: string,\n ) {\n super(message);\n this.name = \"PlayApiError\";\n }\n toJSON() {\n return {\n success: false,\n error: {\n code: this.code,\n message: this.message,\n suggestion: this.suggestion,\n },\n };\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { PlayApiError } from \"./errors.js\";\nimport type { ApiClientOptions, ApiResponse } from \"./types.js\";\n\n/** Strip HTML tags and collapse whitespace from a string. */\nfunction stripHtml(text: string): string {\n return text\n .replace(/<[^>]*>/g, \" \")\n .replace(/&[a-z]+;/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/** Extract a short, safe error summary from API response body (no tokens/secrets). */\nfunction sanitizeErrorBody(body: string): string {\n try {\n const parsed = JSON.parse(body) as {\n error?: { message?: string; status?: string; code?: number };\n };\n if (parsed?.error?.message) {\n return `${parsed.error.code ?? \"?\"} ${parsed.error.status ?? \"\"}: ${parsed.error.message}`.trim();\n }\n } catch {\n // not JSON — may be HTML error page\n }\n // Strip HTML tags before truncating\n const cleaned = body.startsWith(\"<\") ? stripHtml(body) : body;\n return cleaned.length > 200 ? cleaned.slice(0, 200) + \"...\" : cleaned;\n}\n\n/** Validate upload file path to prevent path traversal. */\nfunction validateFilePath(filePath: string): string {\n const resolved = resolve(filePath);\n if (!isAbsolute(resolved)) {\n throw new PlayApiError(\n \"Invalid file path\",\n \"API_INVALID_PATH\",\n undefined,\n \"File path must resolve to an absolute path.\",\n );\n }\n // Block obvious traversal patterns in the original input\n if (filePath.includes(\"\\0\")) {\n throw new PlayApiError(\n \"Invalid file path: null bytes not allowed\",\n \"API_INVALID_PATH\",\n undefined,\n \"Provide a valid file path without null bytes.\",\n );\n }\n return resolved;\n}\n\nconst BASE_URL = \"https://androidpublisher.googleapis.com/androidpublisher/v3/applications\";\n\nconst UPLOAD_BASE_URL =\n \"https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications\";\n\nconst INTERNAL_SHARING_UPLOAD_BASE_URL =\n \"https://androidpublisher.googleapis.com/upload/internalappsharing/v3/applications\";\n\nexport interface HttpClient {\n get<T>(path: string, params?: Record<string, string>): Promise<ApiResponse<T>>;\n post<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n put<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n patch<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;\n delete<T>(path: string): Promise<ApiResponse<T>>;\n upload<T>(path: string, filePath: string, contentType: string): Promise<ApiResponse<T>>;\n uploadInternal<T>(path: string, filePath: string, contentType: string): Promise<ApiResponse<T>>;\n download(path: string): Promise<ArrayBuffer>;\n}\n\nfunction envInt(name: string): number | undefined {\n const val = process.env[name];\n if (val === undefined) return undefined;\n const n = Number(val);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction resolveOption(explicit: number | undefined, envName: string, fallback: number): number {\n return explicit ?? envInt(envName) ?? fallback;\n}\n\nfunction mapStatusToError(status: number, body: string): { code: string; suggestion?: string } {\n switch (status) {\n case 400: {\n // Detect FAILED_PRECONDITION: edit has expired\n try {\n const parsed = JSON.parse(body) as { error?: { status?: string; message?: string } };\n if (\n parsed?.error?.status === \"FAILED_PRECONDITION\" &&\n parsed.error.message?.toLowerCase().includes(\"edit\")\n ) {\n return {\n code: \"API_EDIT_EXPIRED\",\n suggestion: \"The edit session has expired. Retry the operation to open a fresh edit.\",\n };\n }\n } catch {\n /* not JSON */\n }\n return { code: \"API_HTTP_400\", suggestion: \"Check request parameters and try again.\" };\n }\n case 401:\n return {\n code: \"API_UNAUTHORIZED\",\n suggestion: \"Check that your access token is valid and not expired.\",\n };\n case 403:\n return {\n code: \"API_FORBIDDEN\",\n suggestion: \"Ensure the service account has the required permissions for this operation.\",\n };\n case 404:\n return {\n code: \"API_NOT_FOUND\",\n suggestion: \"Verify the package name and resource IDs are correct.\",\n };\n case 409:\n return {\n code: \"API_EDIT_CONFLICT\",\n suggestion: \"Another edit may be in progress. Delete the existing edit and retry.\",\n };\n case 429:\n return {\n code: \"API_RATE_LIMITED\",\n suggestion: \"Too many requests. The client will retry automatically.\",\n };\n default:\n if (status >= 500) {\n return {\n code: \"API_SERVER_ERROR\",\n suggestion: \"Google Play API server error. The client will retry automatically.\",\n };\n }\n return { code: `API_HTTP_${status}` };\n }\n}\n\nfunction isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nfunction jitteredDelay(base: number, attempt: number, max: number): number {\n const exponential = base * 2 ** attempt;\n const capped = Math.min(exponential, max);\n return capped * (0.5 + Math.random() * 0.5);\n}\n\nexport function createHttpClient(options: ApiClientOptions): HttpClient {\n const maxRetries = resolveOption(options.maxRetries, \"GPC_MAX_RETRIES\", 3);\n const timeout = resolveOption(options.timeout, \"GPC_TIMEOUT\", 30_000);\n const uploadTimeoutExplicit = options.uploadTimeout ?? envInt(\"GPC_UPLOAD_TIMEOUT\");\n const baseDelay = resolveOption(options.baseDelay, \"GPC_BASE_DELAY\", 1_000);\n const maxDelay = resolveOption(options.maxDelay, \"GPC_MAX_DELAY\", 60_000);\n const onRetry = options.onRetry;\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n params?: Record<string, string>,\n ): Promise<ApiResponse<T>> {\n let url = `${options.baseUrl ?? BASE_URL}${path}`;\n if (params) {\n const search = new URLSearchParams(params);\n url += `?${search.toString()}`;\n }\n\n // Fetch token once before retries — the auth layer handles its own caching and mutex\n let token = await options.auth.getAccessToken();\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = jitteredDelay(baseDelay, attempt - 1, maxDelay);\n await new Promise((r) => setTimeout(r, delay));\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n };\n\n const init: RequestInit = {\n method,\n headers,\n signal: controller.signal,\n keepalive: true,\n };\n\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, init);\n\n if (response.ok) {\n const text = await response.text();\n const data = text ? (JSON.parse(text) as T) : ({} as T);\n return { data, status: response.status };\n }\n\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n\n const err = new PlayApiError(\n `${method} ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n\n if (isRetryable(response.status) && attempt < maxRetries) {\n lastError = err;\n const delay = jitteredDelay(baseDelay, attempt, maxDelay);\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n status: response.status,\n error: err.message,\n delayMs: Math.round(delay),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n\n // On 401, refresh token once before giving up\n if (response.status === 401 && attempt < maxRetries) {\n token = await options.auth.getAccessToken();\n lastError = err;\n continue;\n }\n\n throw err;\n } catch (error) {\n if (error instanceof PlayApiError) {\n throw error;\n }\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const timeoutErr = new PlayApiError(\n `${method} ${path} timed out after ${timeout}ms`,\n \"API_TIMEOUT\",\n undefined,\n \"The request exceeded the configured timeout. Consider increasing the timeout value.\",\n );\n if (attempt < maxRetries) {\n lastError = timeoutErr;\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n error: timeoutErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw timeoutErr;\n }\n\n const networkErr = new PlayApiError(\n `${method} ${path} failed: ${error instanceof Error ? error.message : String(error)}`,\n \"API_NETWORK_ERROR\",\n undefined,\n \"A network error occurred. Check your internet connection.\",\n );\n if (attempt < maxRetries) {\n lastError = networkErr;\n onRetry?.({\n attempt: attempt + 1,\n method,\n path,\n error: networkErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw networkErr;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // Should not reach here, but just in case\n throw (\n lastError ??\n new PlayApiError(\n \"Request failed\",\n \"API_NETWORK_ERROR\",\n undefined,\n \"Check your network connection and try again. Use --verbose for details.\",\n )\n );\n }\n\n /** Calculate upload timeout: explicit value, or auto-scale from file size (1 MB/s minimum throughput + 30s overhead). */\n function computeUploadTimeout(fileSizeBytes: number): number {\n if (uploadTimeoutExplicit !== undefined) return uploadTimeoutExplicit;\n // Base: 30s overhead + 1s per MB (assumes ~1 MB/s minimum upload speed)\n const sizeMb = fileSizeBytes / (1024 * 1024);\n return Math.max(timeout, 30_000 + Math.ceil(sizeMb) * 1_000);\n }\n\n async function uploadRequest<T>(\n path: string,\n filePath: string,\n contentType: string,\n baseUrl: string = UPLOAD_BASE_URL,\n ): Promise<ApiResponse<T>> {\n const url = `${baseUrl}${path}`;\n const safeFilePath = validateFilePath(filePath);\n const fileBuffer = await readFile(safeFilePath);\n const effectiveTimeout = computeUploadTimeout(fileBuffer.byteLength);\n\n // Fetch token once before retries\n let token = await options.auth.getAccessToken();\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = jitteredDelay(baseDelay, attempt - 1, maxDelay);\n await new Promise((r) => setTimeout(r, delay));\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), effectiveTimeout);\n\n try {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": contentType,\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: fileBuffer,\n signal: controller.signal,\n keepalive: true,\n });\n\n if (response.ok) {\n const text = await response.text();\n const data = text ? (JSON.parse(text) as T) : ({} as T);\n return { data, status: response.status };\n }\n\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n\n const err = new PlayApiError(\n `POST upload ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n\n if (isRetryable(response.status) && attempt < maxRetries) {\n lastError = err;\n const delay = jitteredDelay(baseDelay, attempt, maxDelay);\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n status: response.status,\n error: err.message,\n delayMs: Math.round(delay),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n\n // On 401, refresh token once before giving up\n if (response.status === 401 && attempt < maxRetries) {\n token = await options.auth.getAccessToken();\n lastError = err;\n continue;\n }\n\n throw err;\n } catch (error) {\n if (error instanceof PlayApiError) {\n throw error;\n }\n\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const sizeMb = Math.round(fileBuffer.byteLength / (1024 * 1024));\n const timeoutErr = new PlayApiError(\n `POST upload ${path} timed out after ${effectiveTimeout}ms (file: ${sizeMb} MB)`,\n \"API_TIMEOUT\",\n undefined,\n `Upload timed out. Set GPC_UPLOAD_TIMEOUT=${effectiveTimeout * 2} (ms) or use --timeout to increase.`,\n );\n if (attempt < maxRetries) {\n lastError = timeoutErr;\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n error: timeoutErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw timeoutErr;\n }\n\n const networkErr = new PlayApiError(\n `POST upload ${path} failed: ${error instanceof Error ? error.message : String(error)}`,\n \"API_NETWORK_ERROR\",\n undefined,\n \"A network error occurred. Check your internet connection.\",\n );\n if (attempt < maxRetries) {\n lastError = networkErr;\n onRetry?.({\n attempt: attempt + 1,\n method: \"POST\",\n path: `upload ${path}`,\n error: networkErr.message,\n delayMs: Math.round(jitteredDelay(baseDelay, attempt, maxDelay)),\n timestamp: new Date().toISOString(),\n });\n continue;\n }\n throw networkErr;\n } finally {\n clearTimeout(timer);\n }\n }\n\n throw (\n lastError ??\n new PlayApiError(\n \"Upload request failed\",\n \"API_NETWORK_ERROR\",\n undefined,\n \"Check your network connection and try again. Use --verbose for details.\",\n )\n );\n }\n\n return {\n get<T>(path: string, params?: Record<string, string>) {\n return request<T>(\"GET\", path, undefined, params);\n },\n post<T>(path: string, body?: unknown) {\n return request<T>(\"POST\", path, body);\n },\n put<T>(path: string, body?: unknown) {\n return request<T>(\"PUT\", path, body);\n },\n patch<T>(path: string, body?: unknown) {\n return request<T>(\"PATCH\", path, body);\n },\n delete<T>(path: string) {\n return request<T>(\"DELETE\", path);\n },\n upload<T>(path: string, filePath: string, contentType: string) {\n return uploadRequest<T>(path, filePath, contentType);\n },\n uploadInternal<T>(path: string, filePath: string, contentType: string) {\n return uploadRequest<T>(path, filePath, contentType, INTERNAL_SHARING_UPLOAD_BASE_URL);\n },\n async download(path: string): Promise<ArrayBuffer> {\n const url = `${options.baseUrl ?? BASE_URL}${path}`;\n const token = await options.auth.getAccessToken();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Accept-Encoding\": \"gzip, deflate\",\n Connection: \"keep-alive\",\n },\n signal: controller.signal,\n keepalive: true,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n const { code, suggestion } = mapStatusToError(response.status, errorBody);\n throw new PlayApiError(\n `GET ${path} failed with status ${response.status}: ${sanitizeErrorBody(errorBody)}`,\n code,\n response.status,\n suggestion,\n );\n }\n\n return await response.arrayBuffer();\n } finally {\n clearTimeout(timer);\n }\n },\n };\n}\n","import { PlayApiError } from \"./errors.js\";\nimport { createHttpClient } from \"./http.js\";\nimport type { RateLimiter } from \"./rate-limiter.js\";\nimport type {\n ApiClientOptions,\n AppDetails,\n AppEdit,\n AppRecoveriesListResponse,\n AppRecoveryAction,\n AppRecoveryTargeting,\n CreateAppRecoveryActionRequest,\n BasePlanMigratePricesRequest,\n Bundle,\n BundleListResponse,\n ConvertRegionPricesRequest,\n ConvertRegionPricesResponse,\n CountryAvailability,\n DataSafety,\n DeobfuscationFile,\n DeobfuscationUploadResponse,\n DeviceTierConfig,\n DeviceTierConfigsListResponse,\n ExternalTransaction,\n ExternalTransactionRefund,\n ExternallyHostedApk,\n ExternallyHostedApkResponse,\n Image,\n ImageType,\n ImageUploadResponse,\n ImagesDeleteAllResponse,\n ImagesListResponse,\n InAppProduct,\n InAppProductsListResponse,\n Listing,\n ListingsListResponse,\n OffersListResponse,\n ProductPurchase,\n Release,\n ReportsListResponse,\n ReportType,\n Review,\n ReviewReplyRequest,\n ReviewReplyResponse,\n ReviewsListOptions,\n ReviewsListResponse,\n Subscription,\n SubscriptionDeferRequest,\n SubscriptionDeferResponse,\n SubscriptionOffer,\n SubscriptionPurchase,\n SubscriptionPurchaseV2,\n SubscriptionsListResponse,\n Testers,\n Track,\n TrackListResponse,\n VoidedPurchasesListResponse,\n OneTimeProduct,\n OneTimeProductsListResponse,\n OneTimeOffer,\n OneTimeOffersListResponse,\n InternalAppSharingArtifact,\n GeneratedApk,\n GeneratedApksPerVersion,\n PurchaseOption,\n PurchaseOptionsListResponse,\n InAppProductsBatchUpdateRequest,\n InAppProductsBatchUpdateResponse,\n} from \"./types.js\";\n\nexport interface PlayApiClient {\n edits: {\n insert(packageName: string): Promise<AppEdit>;\n get(packageName: string, editId: string): Promise<AppEdit>;\n validate(packageName: string, editId: string): Promise<AppEdit>;\n commit(packageName: string, editId: string): Promise<AppEdit>;\n delete(packageName: string, editId: string): Promise<void>;\n };\n\n details: {\n get(packageName: string, editId: string): Promise<AppDetails>;\n update(packageName: string, editId: string, details: Partial<AppDetails>): Promise<AppDetails>;\n patch(packageName: string, editId: string, partial: Partial<AppDetails>): Promise<AppDetails>;\n };\n\n bundles: {\n list(packageName: string, editId: string): Promise<Bundle[]>;\n upload(packageName: string, editId: string, filePath: string): Promise<Bundle>;\n };\n\n tracks: {\n list(packageName: string, editId: string): Promise<Track[]>;\n get(packageName: string, editId: string, track: string): Promise<Track>;\n create(packageName: string, editId: string, trackName: string): Promise<Track>;\n update(packageName: string, editId: string, track: string, release: Release): Promise<Track>;\n };\n\n apks: {\n addExternallyHosted(\n packageName: string,\n editId: string,\n data: ExternallyHostedApk,\n ): Promise<ExternallyHostedApkResponse>;\n };\n\n listings: {\n list(packageName: string, editId: string): Promise<Listing[]>;\n get(packageName: string, editId: string, language: string): Promise<Listing>;\n update(\n packageName: string,\n editId: string,\n language: string,\n listing: Omit<Listing, \"language\">,\n ): Promise<Listing>;\n patch(\n packageName: string,\n editId: string,\n language: string,\n partial: Partial<Omit<Listing, \"language\">>,\n ): Promise<Listing>;\n delete(packageName: string, editId: string, language: string): Promise<void>;\n deleteAll(packageName: string, editId: string): Promise<void>;\n };\n\n images: {\n list(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n ): Promise<Image[]>;\n upload(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n filePath: string,\n ): Promise<Image>;\n delete(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n imageId: string,\n ): Promise<void>;\n deleteAll(\n packageName: string,\n editId: string,\n language: string,\n imageType: ImageType,\n ): Promise<Image[]>;\n };\n\n countryAvailability: {\n get(packageName: string, editId: string, track: string): Promise<CountryAvailability>;\n };\n\n dataSafety: {\n get(packageName: string): Promise<DataSafety>;\n update(packageName: string, data: DataSafety): Promise<DataSafety>;\n };\n\n reviews: {\n list(packageName: string, options?: ReviewsListOptions): Promise<ReviewsListResponse>;\n get(packageName: string, reviewId: string, translationLanguage?: string): Promise<Review>;\n reply(packageName: string, reviewId: string, replyText: string): Promise<ReviewReplyResponse>;\n };\n\n subscriptions: {\n list(\n packageName: string,\n options?: { pageToken?: string; pageSize?: number },\n ): Promise<SubscriptionsListResponse>;\n get(packageName: string, productId: string): Promise<Subscription>;\n create(packageName: string, data: Subscription, productId?: string): Promise<Subscription>;\n update(\n packageName: string,\n productId: string,\n data: Subscription,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<Subscription>;\n delete(packageName: string, productId: string): Promise<void>;\n activateBasePlan(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<Subscription>;\n deactivateBasePlan(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<Subscription>;\n deleteBasePlan(packageName: string, productId: string, basePlanId: string): Promise<void>;\n migratePrices(\n packageName: string,\n productId: string,\n basePlanId: string,\n body: BasePlanMigratePricesRequest,\n ): Promise<Subscription>;\n listOffers(\n packageName: string,\n productId: string,\n basePlanId: string,\n ): Promise<OffersListResponse>;\n getOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n createOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n data: SubscriptionOffer,\n offerId?: string,\n ): Promise<SubscriptionOffer>;\n updateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n data: SubscriptionOffer,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<SubscriptionOffer>;\n deleteOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<void>;\n activateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n deactivateOffer(\n packageName: string,\n productId: string,\n basePlanId: string,\n offerId: string,\n ): Promise<SubscriptionOffer>;\n };\n\n inappproducts: {\n list(\n packageName: string,\n options?: { token?: string; maxResults?: number },\n ): Promise<InAppProductsListResponse>;\n get(packageName: string, sku: string): Promise<InAppProduct>;\n create(\n packageName: string,\n data: InAppProduct,\n options?: { autoConvertMissingPrices?: boolean },\n ): Promise<InAppProduct>;\n update(\n packageName: string,\n sku: string,\n data: InAppProduct,\n options?: { autoConvertMissingPrices?: boolean; allowMissing?: boolean },\n ): Promise<InAppProduct>;\n delete(packageName: string, sku: string): Promise<void>;\n batchUpdate(\n packageName: string,\n requests: InAppProductsBatchUpdateRequest,\n ): Promise<InAppProductsBatchUpdateResponse>;\n batchGet(packageName: string, skus: string[]): Promise<InAppProduct[]>;\n };\n\n purchases: {\n getProduct(packageName: string, productId: string, token: string): Promise<ProductPurchase>;\n acknowledgeProduct(\n packageName: string,\n productId: string,\n token: string,\n body?: { developerPayload?: string },\n ): Promise<void>;\n consumeProduct(packageName: string, productId: string, token: string): Promise<void>;\n getSubscriptionV2(packageName: string, token: string): Promise<SubscriptionPurchaseV2>;\n getSubscriptionV1(\n packageName: string,\n subscriptionId: string,\n token: string,\n ): Promise<SubscriptionPurchase>;\n cancelSubscription(packageName: string, subscriptionId: string, token: string): Promise<void>;\n deferSubscription(\n packageName: string,\n subscriptionId: string,\n token: string,\n body: SubscriptionDeferRequest,\n ): Promise<SubscriptionDeferResponse>;\n revokeSubscriptionV2(packageName: string, token: string): Promise<void>;\n refundSubscriptionV2(packageName: string, token: string): Promise<void>;\n listVoided(\n packageName: string,\n options?: { startTime?: string; endTime?: string; maxResults?: number; token?: string },\n ): Promise<VoidedPurchasesListResponse>;\n };\n\n orders: {\n refund(\n packageName: string,\n orderId: string,\n body?: { fullRefund?: boolean; proratedRefund?: boolean },\n ): Promise<void>;\n };\n\n monetization: {\n convertRegionPrices(\n packageName: string,\n price: ConvertRegionPricesRequest,\n ): Promise<ConvertRegionPricesResponse>;\n };\n\n reports: {\n list(\n packageName: string,\n reportType: ReportType,\n year: number,\n month: number,\n ): Promise<ReportsListResponse>;\n };\n\n testers: {\n get(packageName: string, editId: string, track: string): Promise<Testers>;\n update(packageName: string, editId: string, track: string, testers: Testers): Promise<Testers>;\n };\n\n deobfuscation: {\n upload(\n packageName: string,\n editId: string,\n versionCode: number,\n filePath: string,\n ): Promise<DeobfuscationFile>;\n };\n\n appRecovery: {\n list(packageName: string, versionCode?: number): Promise<AppRecoveryAction[]>;\n cancel(packageName: string, appRecoveryId: string): Promise<void>;\n deploy(packageName: string, appRecoveryId: string): Promise<void>;\n create(\n packageName: string,\n request: CreateAppRecoveryActionRequest,\n ): Promise<AppRecoveryAction>;\n addTargeting(\n packageName: string,\n appRecoveryId: string,\n targeting: AppRecoveryTargeting,\n ): Promise<AppRecoveryAction>;\n };\n\n externalTransactions: {\n create(packageName: string, data: ExternalTransaction): Promise<ExternalTransaction>;\n get(packageName: string, transactionId: string): Promise<ExternalTransaction>;\n refund(\n packageName: string,\n transactionId: string,\n refundData: ExternalTransactionRefund,\n ): Promise<ExternalTransaction>;\n };\n\n deviceTiers: {\n list(packageName: string): Promise<DeviceTierConfig[]>;\n get(packageName: string, configId: string): Promise<DeviceTierConfig>;\n create(packageName: string, config: DeviceTierConfig): Promise<DeviceTierConfig>;\n };\n\n oneTimeProducts: {\n list(packageName: string): Promise<OneTimeProductsListResponse>;\n get(packageName: string, productId: string): Promise<OneTimeProduct>;\n create(packageName: string, product: OneTimeProduct): Promise<OneTimeProduct>;\n update(\n packageName: string,\n productId: string,\n product: Partial<OneTimeProduct>,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<OneTimeProduct>;\n delete(packageName: string, productId: string): Promise<void>;\n listOffers(packageName: string, productId: string): Promise<OneTimeOffersListResponse>;\n getOffer(packageName: string, productId: string, offerId: string): Promise<OneTimeOffer>;\n createOffer(packageName: string, productId: string, offer: OneTimeOffer): Promise<OneTimeOffer>;\n updateOffer(\n packageName: string,\n productId: string,\n offerId: string,\n offer: Partial<OneTimeOffer>,\n updateMask?: string,\n regionsVersion?: string,\n ): Promise<OneTimeOffer>;\n deleteOffer(packageName: string, productId: string, offerId: string): Promise<void>;\n };\n\n purchaseOptions: {\n list(packageName: string): Promise<PurchaseOptionsListResponse>;\n get(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n create(packageName: string, data: PurchaseOption): Promise<PurchaseOption>;\n activate(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n deactivate(packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;\n };\n\n internalAppSharing: {\n uploadBundle(packageName: string, bundlePath: string): Promise<InternalAppSharingArtifact>;\n uploadApk(packageName: string, apkPath: string): Promise<InternalAppSharingArtifact>;\n };\n\n generatedApks: {\n list(packageName: string, versionCode: number): Promise<GeneratedApk[]>;\n download(packageName: string, versionCode: number, id: string): Promise<ArrayBuffer>;\n };\n}\n\nasync function rateLimit(limiter: RateLimiter | undefined, bucket: string): Promise<void> {\n if (limiter) await limiter.acquire(bucket);\n}\n\nexport function createApiClient(options: ApiClientOptions): PlayApiClient {\n const http = createHttpClient(options);\n const limiter = options.rateLimiter || undefined;\n\n return {\n edits: {\n async insert(packageName) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits`);\n return data;\n },\n\n async get(packageName, editId) {\n const { data } = await http.get<AppEdit>(`/${packageName}/edits/${editId}`);\n return data;\n },\n\n async validate(packageName, editId) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits/${editId}:validate`);\n return data;\n },\n\n async commit(packageName, editId) {\n const { data } = await http.post<AppEdit>(`/${packageName}/edits/${editId}:commit`);\n return data;\n },\n\n async delete(packageName, editId) {\n await http.delete(`/${packageName}/edits/${editId}`);\n },\n },\n\n details: {\n async get(packageName, editId) {\n const { data } = await http.get<AppDetails>(`/${packageName}/edits/${editId}/details`);\n return data;\n },\n\n async update(packageName, editId, details) {\n const { data } = await http.put<AppDetails>(\n `/${packageName}/edits/${editId}/details`,\n details,\n );\n return data;\n },\n\n async patch(packageName, editId, partial) {\n const { data } = await http.patch<AppDetails>(\n `/${packageName}/edits/${editId}/details`,\n partial,\n );\n return data;\n },\n },\n\n bundles: {\n async list(packageName, editId) {\n const { data } = await http.get<BundleListResponse>(\n `/${packageName}/edits/${editId}/bundles`,\n );\n return data.bundles;\n },\n\n async upload(packageName, editId, filePath) {\n const { data } = await http.upload<Bundle>(\n `/${packageName}/edits/${editId}/bundles`,\n filePath,\n \"application/octet-stream\",\n );\n if (!data || !data.versionCode) {\n throw new PlayApiError(\n \"Upload succeeded but no bundle data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data;\n },\n },\n\n tracks: {\n async list(packageName, editId) {\n const { data } = await http.get<TrackListResponse>(\n `/${packageName}/edits/${editId}/tracks`,\n );\n return data.tracks;\n },\n\n async get(packageName, editId, track) {\n const { data } = await http.get<Track>(`/${packageName}/edits/${editId}/tracks/${track}`);\n return data;\n },\n\n async create(packageName, editId, trackName) {\n const { data } = await http.post<Track>(`/${packageName}/edits/${editId}/tracks`, {\n track: trackName,\n });\n return data;\n },\n\n async update(packageName, editId, track, release) {\n const { data } = await http.put<Track>(`/${packageName}/edits/${editId}/tracks/${track}`, {\n track,\n releases: [release],\n });\n return data;\n },\n },\n\n apks: {\n async addExternallyHosted(packageName, editId, apkData) {\n const { data } = await http.post<ExternallyHostedApkResponse>(\n `/${packageName}/edits/${editId}/apks/externallyHosted`,\n { externallyHostedApk: apkData },\n );\n return data;\n },\n },\n\n listings: {\n async list(packageName, editId) {\n const { data } = await http.get<ListingsListResponse>(\n `/${packageName}/edits/${editId}/listings`,\n );\n return data.listings || [];\n },\n\n async get(packageName, editId, language) {\n const { data } = await http.get<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n );\n return data;\n },\n\n async update(packageName, editId, language, listing) {\n const { data } = await http.put<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n listing,\n );\n return data;\n },\n\n async patch(packageName, editId, language, partial) {\n const { data } = await http.patch<Listing>(\n `/${packageName}/edits/${editId}/listings/${language}`,\n partial,\n );\n return data;\n },\n\n async delete(packageName, editId, language) {\n await http.delete(`/${packageName}/edits/${editId}/listings/${language}`);\n },\n\n async deleteAll(packageName, editId) {\n await http.delete(`/${packageName}/edits/${editId}/listings`);\n },\n },\n\n images: {\n async list(packageName, editId, language, imageType) {\n const { data } = await http.get<ImagesListResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n );\n return data.images || [];\n },\n\n async upload(packageName, editId, language, imageType, filePath) {\n const { data } = await http.upload<ImageUploadResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n filePath,\n filePath.endsWith(\".png\") ? \"image/png\" : \"image/jpeg\",\n );\n if (!data.image) {\n throw new PlayApiError(\n \"Upload succeeded but no image data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data.image;\n },\n\n async delete(packageName, editId, language, imageType, imageId) {\n await http.delete(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}/${imageId}`,\n );\n },\n\n async deleteAll(packageName, editId, language, imageType) {\n const { data } = await http.delete<ImagesDeleteAllResponse>(\n `/${packageName}/edits/${editId}/listings/${language}/${imageType}`,\n );\n return data.deleted || [];\n },\n },\n\n countryAvailability: {\n async get(packageName, editId, track) {\n const { data } = await http.get<CountryAvailability>(\n `/${packageName}/edits/${editId}/countryAvailability/${track}`,\n );\n return data;\n },\n },\n\n dataSafety: {\n async get(packageName) {\n const { data } = await http.get<DataSafety>(`/${packageName}/dataSafety`);\n return data;\n },\n\n async update(packageName, body) {\n const { data } = await http.put<DataSafety>(`/${packageName}/dataSafety`, body);\n return data;\n },\n },\n\n reviews: {\n async list(packageName, options?) {\n await rateLimit(limiter, \"reviewsGet\");\n const params: Record<string, string> = {};\n if (options?.token) params[\"token\"] = options.token;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n if (options?.translationLanguage)\n params[\"translationLanguage\"] = options.translationLanguage;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<ReviewsListResponse>(\n `/${packageName}/reviews`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, reviewId, translationLanguage?) {\n await rateLimit(limiter, \"reviewsGet\");\n const params: Record<string, string> = {};\n if (translationLanguage) params[\"translationLanguage\"] = translationLanguage;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<Review>(\n `/${packageName}/reviews/${reviewId}`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async reply(packageName, reviewId, replyText) {\n await rateLimit(limiter, \"reviewsPost\");\n const body: ReviewReplyRequest = { replyText };\n const { data } = await http.post<ReviewReplyResponse>(\n `/${packageName}/reviews/${reviewId}:reply`,\n body,\n );\n return data;\n },\n },\n\n subscriptions: {\n async list(packageName, options?) {\n const params: Record<string, string> = {};\n if (options?.pageToken) params[\"pageToken\"] = options.pageToken;\n if (options?.pageSize) params[\"pageSize\"] = String(options.pageSize);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<SubscriptionsListResponse>(\n `/${packageName}/subscriptions`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, productId) {\n const { data } = await http.get<Subscription>(`/${packageName}/subscriptions/${productId}`);\n return data;\n },\n\n async create(packageName, body, productId?) {\n const params: Record<string, string> = {};\n if (productId) params[\"productId\"] = productId;\n params[\"regionsVersion.version\"] = \"2022/02\";\n const path = `/${packageName}/subscriptions?${new URLSearchParams(params).toString()}`;\n const { data } = await http.post<Subscription>(path, body);\n return data;\n },\n\n async update(packageName, productId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<Subscription>(path, body);\n return data;\n },\n\n async delete(packageName, productId) {\n await http.delete(`/${packageName}/subscriptions/${productId}`);\n },\n\n async activateBasePlan(packageName, productId, basePlanId) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:activate`,\n );\n return data;\n },\n\n async deactivateBasePlan(packageName, productId, basePlanId) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:deactivate`,\n );\n return data;\n },\n\n async deleteBasePlan(packageName, productId, basePlanId) {\n await http.delete(`/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}`);\n },\n\n async migratePrices(packageName, productId, basePlanId, body) {\n const { data } = await http.post<Subscription>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}:migratePrices`,\n body,\n );\n return data;\n },\n\n async listOffers(packageName, productId, basePlanId) {\n const { data } = await http.get<OffersListResponse>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers`,\n );\n return data;\n },\n\n async getOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.get<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}`,\n );\n return data;\n },\n\n async createOffer(packageName, productId, basePlanId, body, offerId?) {\n const params: Record<string, string> = {};\n if (offerId) params[\"offerId\"] = offerId;\n params[\"regionsVersion.version\"] = \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers?${new URLSearchParams(params).toString()}`;\n const { data } = await http.post<SubscriptionOffer>(path, body);\n return data;\n },\n\n async updateOffer(\n packageName,\n productId,\n basePlanId,\n offerId,\n body,\n updateMask?,\n regionsVersion?,\n ) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<SubscriptionOffer>(path, body);\n return data;\n },\n\n async deleteOffer(packageName, productId, basePlanId, offerId) {\n await http.delete(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}`,\n );\n },\n\n async activateOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.post<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}:activate`,\n );\n return data;\n },\n\n async deactivateOffer(packageName, productId, basePlanId, offerId) {\n const { data } = await http.post<SubscriptionOffer>(\n `/${packageName}/subscriptions/${productId}/basePlans/${basePlanId}/offers/${offerId}:deactivate`,\n );\n return data;\n },\n },\n\n inappproducts: {\n async list(packageName, options?) {\n const params: Record<string, string> = {};\n if (options?.token) params[\"token\"] = options.token;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<InAppProductsListResponse>(\n `/${packageName}/inappproducts`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(packageName, sku) {\n const { data } = await http.get<InAppProduct>(`/${packageName}/inappproducts/${sku}`);\n return data;\n },\n\n async create(packageName, body, options?) {\n const params: Record<string, string> = {};\n if (options?.autoConvertMissingPrices) params[\"autoConvertMissingPrices\"] = \"true\";\n const hasParams = Object.keys(params).length > 0;\n const path = hasParams\n ? `/${packageName}/inappproducts?${new URLSearchParams(params).toString()}`\n : `/${packageName}/inappproducts`;\n const { data } = await http.post<InAppProduct>(path, body);\n return data;\n },\n\n async update(packageName, sku, body, options?) {\n const params: Record<string, string> = {};\n if (options?.autoConvertMissingPrices) params[\"autoConvertMissingPrices\"] = \"true\";\n if (options?.allowMissing) params[\"allowMissing\"] = \"true\";\n const hasParams = Object.keys(params).length > 0;\n const path = hasParams\n ? `/${packageName}/inappproducts/${sku}?${new URLSearchParams(params).toString()}`\n : `/${packageName}/inappproducts/${sku}`;\n const { data } = await http.put<InAppProduct>(path, body);\n return data;\n },\n\n async delete(packageName, sku) {\n await http.delete(`/${packageName}/inappproducts/${sku}`);\n },\n\n async batchUpdate(packageName, requests) {\n const { data } = await http.post<InAppProductsBatchUpdateResponse>(\n `/${packageName}/inappproducts:batchUpdate`,\n requests,\n );\n return data;\n },\n\n async batchGet(packageName, skus) {\n const params: Record<string, string> = {};\n if (skus.length > 0) {\n params[\"sku\"] = skus.join(\",\");\n }\n const { data } = await http.get<{ inappproduct: InAppProduct[] }>(\n `/${packageName}/inappproducts:batchGet`,\n Object.keys(params).length > 0 ? params : undefined,\n );\n return data.inappproduct || [];\n },\n },\n\n purchases: {\n async getProduct(packageName, productId, token) {\n const { data } = await http.get<ProductPurchase>(\n `/${packageName}/purchases/products/${productId}/tokens/${token}`,\n );\n return data;\n },\n\n async acknowledgeProduct(packageName, productId, token, body?) {\n await http.post(\n `/${packageName}/purchases/products/${productId}/tokens/${token}:acknowledge`,\n body,\n );\n },\n\n async consumeProduct(packageName, productId, token) {\n await http.post(`/${packageName}/purchases/products/${productId}/tokens/${token}:consume`);\n },\n\n async getSubscriptionV2(packageName, token) {\n const { data } = await http.get<SubscriptionPurchaseV2>(\n `/${packageName}/purchases/subscriptionsv2/tokens/${token}`,\n );\n return data;\n },\n\n async getSubscriptionV1(packageName, subscriptionId, token) {\n const { data } = await http.get<SubscriptionPurchase>(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}`,\n );\n return data;\n },\n\n async cancelSubscription(packageName, subscriptionId, token) {\n await http.post(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}:cancel`,\n );\n },\n\n async deferSubscription(packageName, subscriptionId, token, body) {\n const { data } = await http.post<SubscriptionDeferResponse>(\n `/${packageName}/purchases/subscriptions/${subscriptionId}/tokens/${token}:defer`,\n body,\n );\n return data;\n },\n\n async revokeSubscriptionV2(packageName, token) {\n await http.post(`/${packageName}/purchases/subscriptionsv2/tokens/${token}:revoke`);\n },\n\n async refundSubscriptionV2(packageName, token) {\n await http.post(`/${packageName}/purchases/subscriptionsv2/tokens/${token}:refund`);\n },\n\n async listVoided(packageName, options?) {\n await rateLimit(limiter, \"voidedBurst\");\n await rateLimit(limiter, \"voidedDaily\");\n const params: Record<string, string> = {};\n if (options?.startTime) params[\"startTime\"] = options.startTime;\n if (options?.endTime) params[\"endTime\"] = options.endTime;\n if (options?.maxResults) params[\"maxResults\"] = String(options.maxResults);\n if (options?.token) params[\"token\"] = options.token;\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<VoidedPurchasesListResponse>(\n `/${packageName}/purchases/voidedpurchases`,\n hasParams ? params : undefined,\n );\n return data;\n },\n },\n\n orders: {\n async refund(packageName, orderId, body?) {\n await http.post(`/${packageName}/orders/${orderId}:refund`, body);\n },\n },\n\n monetization: {\n async convertRegionPrices(packageName, price) {\n const { data } = await http.post<ConvertRegionPricesResponse>(\n `/${packageName}/pricing:convertRegionPrices`,\n price,\n );\n return data;\n },\n },\n\n reports: {\n async list(packageName, reportType, year, month) {\n const monthStr = String(month).padStart(2, \"0\");\n const { data } = await http.get<ReportsListResponse>(\n `/${packageName}/reports/${reportType}/${year}/${monthStr}`,\n );\n return data;\n },\n },\n\n testers: {\n async get(packageName, editId, track) {\n const { data } = await http.get<Testers>(\n `/${packageName}/edits/${editId}/testers/${track}`,\n );\n return data;\n },\n\n async update(packageName, editId, track, testersData) {\n const { data } = await http.put<Testers>(\n `/${packageName}/edits/${editId}/testers/${track}`,\n testersData,\n );\n return data;\n },\n },\n\n deobfuscation: {\n async upload(packageName, editId, versionCode, filePath) {\n const { data } = await http.upload<DeobfuscationUploadResponse>(\n `/${packageName}/edits/${editId}/apks/${versionCode}/deobfuscationFiles/proguard`,\n filePath,\n \"application/octet-stream\",\n );\n if (!data.deobfuscationFile) {\n throw new PlayApiError(\n \"Upload succeeded but no deobfuscation file data returned\",\n \"API_EMPTY_RESPONSE\",\n 200,\n \"This is unexpected. Retry the upload or contact Google Play support if the issue persists.\",\n );\n }\n return data.deobfuscationFile;\n },\n },\n\n appRecovery: {\n async list(packageName, versionCode?) {\n const params: Record<string, string> = {};\n if (versionCode !== undefined) params[\"versionCode\"] = String(versionCode);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<AppRecoveriesListResponse>(\n `/${packageName}/appRecoveries`,\n hasParams ? params : undefined,\n );\n return data.recoveryActions || [];\n },\n\n async cancel(packageName, appRecoveryId) {\n await http.post(`/${packageName}/appRecovery/${appRecoveryId}:cancel`);\n },\n\n async deploy(packageName, appRecoveryId) {\n await http.post(`/${packageName}/appRecovery/${appRecoveryId}:deploy`);\n },\n\n async create(packageName, request) {\n const { data } = await http.post<AppRecoveryAction>(\n `/${packageName}/appRecoveries`,\n request,\n );\n return data;\n },\n\n async addTargeting(packageName, appRecoveryId, targeting) {\n const { data } = await http.post<AppRecoveryAction>(\n `/${packageName}/appRecoveries/${appRecoveryId}:addTargeting`,\n targeting,\n );\n return data;\n },\n },\n\n externalTransactions: {\n async create(packageName, body) {\n const { data } = await http.post<ExternalTransaction>(\n `/${packageName}/externalTransactions`,\n body,\n );\n return data;\n },\n\n async get(packageName, transactionId) {\n const { data } = await http.get<ExternalTransaction>(\n `/${packageName}/externalTransactions/${transactionId}`,\n );\n return data;\n },\n\n async refund(packageName, transactionId, refundData) {\n const { data } = await http.post<ExternalTransaction>(\n `/${packageName}/externalTransactions/${transactionId}:refund`,\n refundData,\n );\n return data;\n },\n },\n\n deviceTiers: {\n async list(packageName) {\n const { data } = await http.get<DeviceTierConfigsListResponse>(\n `/${packageName}/deviceTierConfigs`,\n );\n return data.deviceTierConfigs || [];\n },\n\n async get(packageName, configId) {\n const { data } = await http.get<DeviceTierConfig>(\n `/${packageName}/deviceTierConfigs/${configId}`,\n );\n return data;\n },\n\n async create(packageName, config) {\n const { data } = await http.post<DeviceTierConfig>(\n `/${packageName}/deviceTierConfigs`,\n config,\n );\n return data;\n },\n },\n\n oneTimeProducts: {\n async list(packageName) {\n const { data } = await http.get<OneTimeProductsListResponse>(\n `/${packageName}/oneTimeProducts`,\n );\n return data;\n },\n\n async get(packageName, productId) {\n const { data } = await http.get<OneTimeProduct>(\n `/${packageName}/oneTimeProducts/${productId}`,\n );\n return data;\n },\n\n async create(packageName, body) {\n const params = new URLSearchParams({ \"regionsVersion.version\": \"2022/02\" });\n const { data } = await http.post<OneTimeProduct>(\n `/${packageName}/oneTimeProducts?${params.toString()}`,\n body,\n );\n return data;\n },\n\n async update(packageName, productId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/oneTimeProducts/${productId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<OneTimeProduct>(path, body);\n return data;\n },\n\n async delete(packageName, productId) {\n await http.delete(`/${packageName}/oneTimeProducts/${productId}`);\n },\n\n async listOffers(packageName, productId) {\n const { data } = await http.get<OneTimeOffersListResponse>(\n `/${packageName}/oneTimeProducts/${productId}/offers`,\n );\n return data;\n },\n\n async getOffer(packageName, productId, offerId) {\n const { data } = await http.get<OneTimeOffer>(\n `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`,\n );\n return data;\n },\n\n async createOffer(packageName, productId, body) {\n const { data } = await http.post<OneTimeOffer>(\n `/${packageName}/oneTimeProducts/${productId}/offers`,\n body,\n );\n return data;\n },\n\n async updateOffer(packageName, productId, offerId, body, updateMask?, regionsVersion?) {\n const params: Record<string, string> = {};\n if (updateMask) params[\"updateMask\"] = updateMask;\n params[\"regionsVersion.version\"] = regionsVersion || \"2022/02\";\n const path = `/${packageName}/oneTimeProducts/${productId}/offers/${offerId}?${new URLSearchParams(params).toString()}`;\n const { data } = await http.patch<OneTimeOffer>(path, body);\n return data;\n },\n\n async deleteOffer(packageName, productId, offerId) {\n await http.delete(`/${packageName}/oneTimeProducts/${productId}/offers/${offerId}`);\n },\n },\n\n purchaseOptions: {\n async list(packageName) {\n const { data } = await http.get<PurchaseOptionsListResponse>(\n `/${packageName}/purchaseOptions`,\n );\n return data;\n },\n\n async get(packageName, purchaseOptionId) {\n const { data } = await http.get<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}`,\n );\n return data;\n },\n\n async create(packageName, body) {\n const { data } = await http.post<PurchaseOption>(`/${packageName}/purchaseOptions`, body);\n return data;\n },\n\n async activate(packageName, purchaseOptionId) {\n const { data } = await http.post<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}:activate`,\n );\n return data;\n },\n\n async deactivate(packageName, purchaseOptionId) {\n const { data } = await http.post<PurchaseOption>(\n `/${packageName}/purchaseOptions/${purchaseOptionId}:deactivate`,\n );\n return data;\n },\n },\n\n internalAppSharing: {\n async uploadBundle(packageName, bundlePath) {\n const { data } = await http.uploadInternal<InternalAppSharingArtifact>(\n `/${packageName}/artifacts/bundle`,\n bundlePath,\n \"application/octet-stream\",\n );\n return data;\n },\n\n async uploadApk(packageName, apkPath) {\n const { data } = await http.uploadInternal<InternalAppSharingArtifact>(\n `/${packageName}/artifacts/apk`,\n apkPath,\n \"application/vnd.android.package-archive\",\n );\n return data;\n },\n },\n\n generatedApks: {\n async list(packageName, versionCode) {\n const { data } = await http.get<GeneratedApksPerVersion>(\n `/${packageName}/generatedApks/${versionCode}`,\n );\n return data.generatedApks || [];\n },\n\n async download(packageName, versionCode, id) {\n return http.download(`/${packageName}/generatedApks/${versionCode}/download/${id}`);\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type {\n AnomalyDetectionResponse,\n ApiClientOptions,\n ErrorIssuesResponse,\n ErrorReportsResponse,\n MetricSetQuery,\n MetricSetResponse,\n VitalsMetricSet,\n} from \"./types.js\";\n\nconst REPORTING_BASE_URL = \"https://playdeveloperreporting.googleapis.com/v1beta1\";\n\nexport interface ReportingApiClient {\n queryMetricSet(\n packageName: string,\n metricSet: VitalsMetricSet,\n query: MetricSetQuery,\n ): Promise<MetricSetResponse>;\n\n getAnomalies(packageName: string): Promise<AnomalyDetectionResponse>;\n\n searchErrorIssues(\n packageName: string,\n filter?: string,\n pageSize?: number,\n pageToken?: string,\n ): Promise<ErrorIssuesResponse>;\n\n searchErrorReports(\n packageName: string,\n issueName: string,\n pageSize?: number,\n pageToken?: string,\n ): Promise<ErrorReportsResponse>;\n}\n\nexport function createReportingClient(options: ApiClientOptions): ReportingApiClient {\n const http = createHttpClient({ ...options, baseUrl: REPORTING_BASE_URL });\n\n return {\n async queryMetricSet(packageName, metricSet, query) {\n const { data } = await http.post<MetricSetResponse>(\n `/apps/${packageName}/${metricSet}:query`,\n query,\n );\n return data;\n },\n\n async getAnomalies(packageName) {\n const { data } = await http.get<AnomalyDetectionResponse>(`/apps/${packageName}/anomalies`);\n return data;\n },\n\n async searchErrorIssues(packageName, filter?, pageSize?, pageToken?) {\n const params: Record<string, string> = {};\n if (filter) params[\"filter\"] = filter;\n if (pageSize) params[\"pageSize\"] = String(pageSize);\n if (pageToken) params[\"pageToken\"] = pageToken;\n const { data } = await http.get<ErrorIssuesResponse>(\n `/apps/${packageName}/errorIssues:search`,\n params,\n );\n return data;\n },\n\n async searchErrorReports(packageName, issueName, pageSize?, pageToken?) {\n const params: Record<string, string> = {};\n if (pageSize) params[\"pageSize\"] = String(pageSize);\n if (pageToken) params[\"pageToken\"] = pageToken;\n const { data } = await http.get<ErrorReportsResponse>(\n `/apps/${packageName}/errorIssues/${issueName}/reports`,\n params,\n );\n return data;\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions, User, UsersListResponse, Grant } from \"./types.js\";\n\nconst USERS_BASE_URL = \"https://androidpublisher.googleapis.com/androidpublisher/v3/developers\";\n\nexport interface GrantsListResponse {\n grants: Grant[];\n nextPageToken?: string;\n}\n\nexport interface UsersApiClient {\n list(\n developerId: string,\n options?: { pageToken?: string; pageSize?: number },\n ): Promise<UsersListResponse>;\n\n get(developerId: string, userId: string): Promise<User>;\n\n create(developerId: string, user: Partial<User>): Promise<User>;\n\n update(\n developerId: string,\n userId: string,\n user: Partial<User>,\n updateMask?: string,\n ): Promise<User>;\n\n delete(developerId: string, userId: string): Promise<void>;\n\n grants: {\n list(developerId: string, email: string): Promise<GrantsListResponse>;\n create(developerId: string, email: string, grant: Partial<Grant>): Promise<Grant>;\n patch(\n developerId: string,\n email: string,\n packageName: string,\n grant: Partial<Grant>,\n updateMask?: string,\n ): Promise<Grant>;\n delete(developerId: string, email: string, packageName: string): Promise<void>;\n };\n}\n\nexport function createUsersClient(options: ApiClientOptions): UsersApiClient {\n const http = createHttpClient({ ...options, baseUrl: USERS_BASE_URL });\n\n return {\n async list(developerId, listOptions?) {\n const params: Record<string, string> = {};\n if (listOptions?.pageToken) params[\"pageToken\"] = listOptions.pageToken;\n if (listOptions?.pageSize) params[\"pageSize\"] = String(listOptions.pageSize);\n const hasParams = Object.keys(params).length > 0;\n const { data } = await http.get<UsersListResponse>(\n `/${developerId}/users`,\n hasParams ? params : undefined,\n );\n return data;\n },\n\n async get(developerId, userId) {\n const { data } = await http.get<User>(`/${developerId}/users/${userId}`);\n return data;\n },\n\n async create(developerId, user) {\n const { data } = await http.post<User>(`/${developerId}/users`, user);\n return data;\n },\n\n async update(developerId, userId, user, updateMask?) {\n let path = `/${developerId}/users/${userId}`;\n if (updateMask) {\n path += `?updateMask=${encodeURIComponent(updateMask).replace(/%2C/gi, \",\")}`;\n }\n const { data } = await http.patch<User>(path, user);\n return data;\n },\n\n async delete(developerId, userId) {\n await http.delete(`/${developerId}/users/${userId}`);\n },\n\n grants: {\n async list(developerId, email) {\n const { data } = await http.get<GrantsListResponse>(\n `/${developerId}/users/${encodeURIComponent(email)}/grants`,\n );\n return data;\n },\n\n async create(developerId, email, grant) {\n const { data } = await http.post<Grant>(\n `/${developerId}/users/${encodeURIComponent(email)}/grants`,\n grant,\n );\n return data;\n },\n\n async patch(developerId, email, packageName, grant, updateMask?) {\n let path = `/${developerId}/users/${encodeURIComponent(email)}/grants/${encodeURIComponent(packageName)}`;\n if (updateMask) {\n path += `?updateMask=${encodeURIComponent(updateMask)}`;\n }\n const { data } = await http.patch<Grant>(path, grant);\n return data;\n },\n\n async delete(developerId, email, packageName) {\n await http.delete(\n `/${developerId}/users/${encodeURIComponent(email)}/grants/${encodeURIComponent(packageName)}`,\n );\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions } from \"./types.js\";\n\nconst GAMES_BASE_URL = \"https://games.googleapis.com/games/v1\";\n\nexport interface Leaderboard {\n id: string;\n name: string;\n order: string;\n iconUrl?: string;\n}\n\nexport interface LeaderboardScore {\n leaderboardId: string;\n scoreValue: string;\n formattedScore: string;\n writeTimestamp?: string;\n tag?: string;\n}\n\nexport interface Achievement {\n id: string;\n name: string;\n description: string;\n state: \"REVEALED\" | \"HIDDEN\" | \"UNLOCKED\";\n currentSteps?: number;\n totalSteps?: number;\n experiencePoints?: number;\n formattedCurrentStepsString?: string;\n}\n\nexport interface GameEvent {\n definitionId: string;\n numEvents: string;\n formattedNumEvents: string;\n kind?: string;\n}\n\nexport interface GamesApiClient {\n leaderboards: {\n list(packageName: string): Promise<{ items?: Leaderboard[]; nextPageToken?: string }>;\n get(packageName: string, leaderboardId: string): Promise<Leaderboard>;\n getScores(\n packageName: string,\n leaderboardId: string,\n collection: string,\n timeSpan: string,\n ): Promise<{ items?: LeaderboardScore[] }>;\n };\n achievements: {\n list(packageName: string): Promise<{ items?: Achievement[]; nextPageToken?: string }>;\n reveal(packageName: string, achievementId: string): Promise<{ currentState: string }>;\n };\n events: {\n list(packageName: string): Promise<{ items?: GameEvent[]; nextPageToken?: string }>;\n };\n}\n\nexport function createGamesClient(options: ApiClientOptions): GamesApiClient {\n const http = createHttpClient({ ...options, baseUrl: GAMES_BASE_URL });\n\n return {\n leaderboards: {\n async list(packageName) {\n const { data } = await http.get<{ items?: Leaderboard[]; nextPageToken?: string }>(\n `/leaderboards?applicationId=${packageName}`,\n );\n return data;\n },\n async get(packageName, leaderboardId) {\n const { data } = await http.get<Leaderboard>(\n `/leaderboards/${leaderboardId}?applicationId=${packageName}`,\n );\n return data;\n },\n async getScores(packageName, leaderboardId, collection, timeSpan) {\n const { data } = await http.get<{ items?: LeaderboardScore[] }>(\n `/leaderboards/${leaderboardId}/scores/${collection}?timeSpan=${timeSpan}&applicationId=${packageName}`,\n );\n return data;\n },\n },\n achievements: {\n async list(packageName) {\n const { data } = await http.get<{ items?: Achievement[]; nextPageToken?: string }>(\n `/achievements?applicationId=${packageName}`,\n );\n return data;\n },\n async reveal(packageName, achievementId) {\n const { data } = await http.post<{ currentState: string }>(\n `/achievements/${achievementId}/reveal?applicationId=${packageName}`,\n {},\n );\n return data;\n },\n },\n events: {\n async list(packageName) {\n const { data } = await http.get<{ items?: GameEvent[]; nextPageToken?: string }>(\n `/events?applicationId=${packageName}`,\n );\n return data;\n },\n },\n };\n}\n","import { createHttpClient } from \"./http.js\";\nimport type { ApiClientOptions } from \"./types.js\";\n\nconst ENTERPRISE_BASE_URL = \"https://playcustomapp.googleapis.com/playcustomapp/v1/organizations\";\n\nexport interface CustomApp {\n packageName?: string;\n title: string;\n languageCode?: string;\n organizations?: Array<{ organizationId: string; organizationName?: string }>;\n}\n\nexport interface CustomAppsListResponse {\n customApps?: CustomApp[];\n nextPageToken?: string;\n}\n\nexport interface EnterpriseApiClient {\n apps: {\n create(organizationId: string, app: Partial<CustomApp>): Promise<CustomApp>;\n list(organizationId: string): Promise<CustomAppsListResponse>;\n };\n}\n\nexport function createEnterpriseClient(options: ApiClientOptions): EnterpriseApiClient {\n const http = createHttpClient({ ...options, baseUrl: ENTERPRISE_BASE_URL });\n\n return {\n apps: {\n async create(organizationId, app) {\n const { data } = await http.post<CustomApp>(`/${organizationId}/apps`, app);\n return data;\n },\n async list(organizationId) {\n const { data } = await http.get<CustomAppsListResponse>(`/${organizationId}/apps`);\n return data;\n },\n },\n };\n}\n","export interface RateLimitBucket {\n name: string;\n maxTokens: number;\n refillRate: number;\n refillIntervalMs: number;\n}\n\nexport interface RateLimiter {\n acquire(bucket: string): Promise<void>;\n}\n\ninterface BucketState {\n tokens: number;\n lastRefillTime: number;\n config: RateLimitBucket;\n}\n\nexport const RATE_LIMIT_BUCKETS: Record<string, RateLimitBucket> = {\n default: { name: \"default\", maxTokens: 200, refillRate: 200, refillIntervalMs: 1_000 },\n reviewsGet: { name: \"reviewsGet\", maxTokens: 200, refillRate: 200, refillIntervalMs: 3_600_000 },\n reviewsPost: {\n name: \"reviewsPost\",\n maxTokens: 2_000,\n refillRate: 2_000,\n refillIntervalMs: 86_400_000,\n },\n voidedBurst: { name: \"voidedBurst\", maxTokens: 30, refillRate: 30, refillIntervalMs: 30_000 },\n voidedDaily: {\n name: \"voidedDaily\",\n maxTokens: 6_000,\n refillRate: 6_000,\n refillIntervalMs: 86_400_000,\n },\n};\n\nexport function createRateLimiter(buckets?: RateLimitBucket[]): RateLimiter {\n const states = new Map<string, BucketState>();\n\n if (buckets) {\n for (const bucket of buckets) {\n states.set(bucket.name, {\n tokens: bucket.maxTokens,\n lastRefillTime: Date.now(),\n config: bucket,\n });\n }\n }\n\n return {\n async acquire(bucket: string): Promise<void> {\n const state = states.get(bucket);\n if (!state) return;\n\n const now = Date.now();\n const elapsed = now - state.lastRefillTime;\n const refill = Math.floor(\n (elapsed / state.config.refillIntervalMs) * state.config.refillRate,\n );\n\n if (refill > 0) {\n state.tokens = Math.min(state.config.maxTokens, state.tokens + refill);\n state.lastRefillTime = now;\n }\n\n if (state.tokens > 0) {\n state.tokens--;\n return;\n }\n\n const tokensNeeded = 1;\n const waitMs = Math.ceil(\n (tokensNeeded / state.config.refillRate) * state.config.refillIntervalMs,\n );\n await new Promise((r) => setTimeout(r, waitMs));\n\n // Recalculate refill based on actual elapsed time since last refill\n const afterWait = Date.now();\n const totalElapsed = afterWait - state.lastRefillTime;\n const newTokens = Math.floor(\n (totalElapsed / state.config.refillIntervalMs) * state.config.refillRate,\n );\n state.tokens = Math.min(state.config.maxTokens, newTokens) - 1;\n state.lastRefillTime = afterWait;\n },\n };\n}\n","export interface PaginateOptions {\n limit?: number;\n startPageToken?: string;\n}\n\nexport async function* paginate<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n options?: PaginateOptions,\n): AsyncGenerator<TItem[], void, unknown> {\n let pageToken = options?.startPageToken;\n let collected = 0;\n const limit = options?.limit;\n\n for (;;) {\n if (limit !== undefined && collected >= limit) break;\n\n const page = await fetchPage(pageToken);\n const items = page.items;\n\n if (items.length === 0) break;\n\n if (limit !== undefined) {\n const remaining = limit - collected;\n if (items.length > remaining) {\n yield items.slice(0, remaining);\n return;\n }\n }\n\n yield items;\n collected += items.length;\n pageToken = page.nextPageToken;\n\n if (!pageToken) break;\n }\n}\n\nexport async function paginateAll<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n options?: PaginateOptions,\n): Promise<{ items: TItem[]; nextPageToken?: string }> {\n const allItems: TItem[] = [];\n let lastPageToken: string | undefined;\n const limit = options?.limit;\n\n for await (const items of paginate(fetchPage, options)) {\n allItems.push(...items);\n if (limit !== undefined && allItems.length >= limit) break;\n }\n\n // If we stopped due to limit, try to get the next page token for resumption\n if (limit !== undefined && allItems.length >= limit) {\n lastPageToken = undefined; // Already truncated by paginate\n }\n\n return { items: allItems, nextPageToken: lastPageToken };\n}\n\n/**\n * Fetch multiple known pages in parallel.\n * Useful when page tokens are predictable or when pre-fetching subsequent pages\n * after an initial sequential fetch reveals the token pattern.\n *\n * @param fetchPage - Function that fetches a page given a token\n * @param pageTokens - Array of page tokens to fetch concurrently\n * @param concurrency - Max concurrent requests (default: 4)\n */\nexport async function paginateParallel<TItem>(\n fetchPage: (pageToken?: string) => Promise<{ items: TItem[]; nextPageToken?: string }>,\n pageTokens: string[],\n concurrency = 4,\n): Promise<{ items: TItem[]; nextPageToken?: string }> {\n const allItems: TItem[] = [];\n let lastNextPageToken: string | undefined;\n\n // Process in batches of `concurrency`\n for (let i = 0; i < pageTokens.length; i += concurrency) {\n const batch = pageTokens.slice(i, i + concurrency);\n const results = await Promise.all(batch.map((token) => fetchPage(token)));\n\n for (const result of results) {\n allItems.push(...result.items);\n if (result.nextPageToken) {\n lastNextPageToken = result.nextPageToken;\n }\n }\n }\n\n return { items: allItems, nextPageToken: lastNextPageToken };\n}\n"],"mappings":"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","names":["options"]}
|