kappmaker 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +481 -33
- package/dist/cli.js +146 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/adapty-setup.js +5 -4
- package/dist/commands/adapty-setup.js.map +1 -1
- package/dist/commands/android-release-build.d.ts +7 -0
- package/dist/commands/android-release-build.js +51 -0
- package/dist/commands/android-release-build.js.map +1 -0
- package/dist/commands/config.js +11 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/create-appstore-app.js +18 -1
- package/dist/commands/create-appstore-app.js.map +1 -1
- package/dist/commands/create-logo.js +16 -5
- package/dist/commands/create-logo.js.map +1 -1
- package/dist/commands/create-play-app.d.ts +2 -0
- package/dist/commands/create-play-app.js +399 -0
- package/dist/commands/create-play-app.js.map +1 -0
- package/dist/commands/create.js +138 -64
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/enhance.js +12 -4
- package/dist/commands/enhance.js.map +1 -1
- package/dist/commands/fastlane-configure.d.ts +1 -0
- package/dist/commands/fastlane-configure.js +9 -0
- package/dist/commands/fastlane-configure.js.map +1 -0
- package/dist/commands/generate-keystore.d.ts +7 -0
- package/dist/commands/generate-keystore.js +14 -0
- package/dist/commands/generate-keystore.js.map +1 -0
- package/dist/commands/generate-screenshots.js +22 -7
- package/dist/commands/generate-screenshots.js.map +1 -1
- package/dist/commands/gpc.d.ts +29 -0
- package/dist/commands/gpc.js +174 -0
- package/dist/commands/gpc.js.map +1 -0
- package/dist/commands/publish.d.ts +10 -0
- package/dist/commands/publish.js +38 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/refactor.d.ts +9 -0
- package/dist/commands/refactor.js +9 -0
- package/dist/commands/refactor.js.map +1 -0
- package/dist/commands/remove-bg.js +12 -4
- package/dist/commands/remove-bg.js.map +1 -1
- package/dist/commands/translate-screenshots.js +22 -8
- package/dist/commands/translate-screenshots.js.map +1 -1
- package/dist/commands/update-version.d.ts +5 -0
- package/dist/commands/update-version.js +21 -0
- package/dist/commands/update-version.js.map +1 -0
- package/dist/services/asc-monetization.service.js +39 -29
- package/dist/services/asc-monetization.service.js.map +1 -1
- package/dist/services/asc.service.d.ts +1 -1
- package/dist/services/asc.service.js +94 -12
- package/dist/services/asc.service.js.map +1 -1
- package/dist/services/fastlane-setup.service.d.ts +1 -0
- package/dist/services/fastlane-setup.service.js +50 -0
- package/dist/services/fastlane-setup.service.js.map +1 -0
- package/dist/services/fastlane.service.js +20 -8
- package/dist/services/fastlane.service.js.map +1 -1
- package/dist/services/firebase.service.js +48 -18
- package/dist/services/firebase.service.js.map +1 -1
- package/dist/services/gpc-data-safety.service.d.ts +11 -0
- package/dist/services/gpc-data-safety.service.js +160 -0
- package/dist/services/gpc-data-safety.service.js.map +1 -0
- package/dist/services/gpc-monetization.service.d.ts +18 -0
- package/dist/services/gpc-monetization.service.js +244 -0
- package/dist/services/gpc-monetization.service.js.map +1 -0
- package/dist/services/gpc.service.d.ts +87 -0
- package/dist/services/gpc.service.js +338 -0
- package/dist/services/gpc.service.js.map +1 -0
- package/dist/services/gradle.service.d.ts +0 -3
- package/dist/services/gradle.service.js +0 -24
- package/dist/services/gradle.service.js.map +1 -1
- package/dist/services/keystore.service.d.ts +6 -0
- package/dist/services/keystore.service.js +44 -0
- package/dist/services/keystore.service.js.map +1 -0
- package/dist/services/publish.service.d.ts +10 -0
- package/dist/services/publish.service.js +59 -0
- package/dist/services/publish.service.js.map +1 -0
- package/dist/services/refactor.service.d.ts +3 -0
- package/dist/services/refactor.service.js +207 -0
- package/dist/services/refactor.service.js.map +1 -0
- package/dist/services/version.service.d.ts +10 -0
- package/dist/services/version.service.js +75 -0
- package/dist/services/version.service.js.map +1 -0
- package/dist/templates/Fastfile.txt +209 -0
- package/dist/templates/data-safety-template.json +5483 -0
- package/dist/templates/googleplay-config.json +71 -0
- package/dist/types/googleplay.d.ts +113 -0
- package/dist/types/googleplay.js +2 -0
- package/dist/types/googleplay.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.js +5 -0
- package/dist/utils/config.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpc-data-safety.service.js","sourceRoot":"","sources":["../../src/services/gpc-data-safety.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GooglePlaySubscription, GooglePlayInAppProduct } from '../types/googleplay.js';
|
|
2
|
+
interface Money {
|
|
3
|
+
currencyCode: string;
|
|
4
|
+
units: string;
|
|
5
|
+
nanos: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convert a human-readable price like "6.99" into the Google Play money
|
|
9
|
+
* representation: { currencyCode, units, nanos }. Nanos are billionths,
|
|
10
|
+
* so "6.99" becomes { units: "6", nanos: 990000000 }.
|
|
11
|
+
*/
|
|
12
|
+
export declare function priceToMoney(price: string, currencyCode: string): Money;
|
|
13
|
+
export declare function listSubscriptions(packageName: string): Promise<Set<string>>;
|
|
14
|
+
export declare function setupSubscriptions(packageName: string, subscriptions: GooglePlaySubscription[], playDefaultLanguage: string): Promise<void>;
|
|
15
|
+
export declare function activateBasePlan(packageName: string, productId: string, basePlanId: string): Promise<void>;
|
|
16
|
+
export declare function listInAppProducts(packageName: string): Promise<Set<string>>;
|
|
17
|
+
export declare function setupInAppProducts(packageName: string, products: GooglePlayInAppProduct[]): Promise<void>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { apiRequest } from './gpc.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert a human-readable price like "6.99" into the Google Play money
|
|
5
|
+
* representation: { currencyCode, units, nanos }. Nanos are billionths,
|
|
6
|
+
* so "6.99" becomes { units: "6", nanos: 990000000 }.
|
|
7
|
+
*/
|
|
8
|
+
export function priceToMoney(price, currencyCode) {
|
|
9
|
+
const [wholeRaw, fractionRaw = ''] = price.trim().split('.');
|
|
10
|
+
const whole = wholeRaw.replace(/^-/, '') || '0';
|
|
11
|
+
// Pad or truncate fractional part to 9 digits (nanos)
|
|
12
|
+
const fractionPadded = (fractionRaw + '000000000').slice(0, 9);
|
|
13
|
+
const nanos = Number(fractionPadded) || 0;
|
|
14
|
+
return {
|
|
15
|
+
currencyCode,
|
|
16
|
+
units: whole,
|
|
17
|
+
nanos: price.startsWith('-') ? -nanos : nanos,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function buildRegionalConfigs(prices) {
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const p of prices) {
|
|
23
|
+
out[p.region_code] = {
|
|
24
|
+
newSubscriberAvailability: true,
|
|
25
|
+
price: priceToMoney(p.price, p.currency_code),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
export async function listSubscriptions(packageName) {
|
|
31
|
+
const result = await apiRequest({
|
|
32
|
+
method: 'GET',
|
|
33
|
+
path: `/applications/${encodeURIComponent(packageName)}/subscriptions`,
|
|
34
|
+
label: 'Looking up existing subscriptions',
|
|
35
|
+
allowFailure: true,
|
|
36
|
+
});
|
|
37
|
+
if (!result.ok || !result.data?.subscriptions)
|
|
38
|
+
return new Set();
|
|
39
|
+
return new Set(result.data.subscriptions.map((s) => s.productId));
|
|
40
|
+
}
|
|
41
|
+
export async function setupSubscriptions(packageName, subscriptions, playDefaultLanguage) {
|
|
42
|
+
if (subscriptions.length === 0) {
|
|
43
|
+
logger.info('No subscriptions configured, skipping.');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const existing = await listSubscriptions(packageName);
|
|
47
|
+
for (const sub of subscriptions) {
|
|
48
|
+
if (existing.has(sub.product_id)) {
|
|
49
|
+
logger.info(`Subscription "${sub.product_id}" already exists, skipping create.`);
|
|
50
|
+
// Still (best-effort) try to activate any base plans that aren't active.
|
|
51
|
+
for (const basePlan of sub.base_plans) {
|
|
52
|
+
await activateBasePlan(packageName, sub.product_id, basePlan.base_plan_id);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
await createSubscriptionWithBasePlans(packageName, sub, playDefaultLanguage);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Google Play's new monetization API ties pricing regions to a "regionsVersion"
|
|
60
|
+
// — bump this constant if Google publishes a newer region catalog.
|
|
61
|
+
const REGIONS_VERSION = '2022/02';
|
|
62
|
+
async function createSubscriptionWithBasePlans(packageName, sub, playDefaultLanguage) {
|
|
63
|
+
// Play rejects subscriptions that don't have a listing in the app's current
|
|
64
|
+
// default language. If the config's listings don't cover it, clone the first
|
|
65
|
+
// entry with the Play default language tacked on.
|
|
66
|
+
const listings = [...sub.listings];
|
|
67
|
+
const hasDefault = listings.some((l) => l.locale === playDefaultLanguage);
|
|
68
|
+
if (!hasDefault && listings.length > 0) {
|
|
69
|
+
const first = listings[0];
|
|
70
|
+
listings.unshift({
|
|
71
|
+
locale: playDefaultLanguage,
|
|
72
|
+
title: first.title,
|
|
73
|
+
description: first.description,
|
|
74
|
+
benefits: first.benefits,
|
|
75
|
+
});
|
|
76
|
+
logger.info(`Cloned "${first.locale}" listing to "${playDefaultLanguage}" (Play default language).`);
|
|
77
|
+
}
|
|
78
|
+
// Create subscription + base plans in a single call. The new monetization API
|
|
79
|
+
// requires productId and regionsVersion.version as QUERY PARAMETERS (not body)
|
|
80
|
+
// — passing productId in the body triggers "Product ID must be specified".
|
|
81
|
+
const body = {
|
|
82
|
+
packageName,
|
|
83
|
+
productId: sub.product_id,
|
|
84
|
+
listings: listings.map((l) => ({
|
|
85
|
+
languageCode: l.locale,
|
|
86
|
+
title: l.title,
|
|
87
|
+
description: l.description ?? '',
|
|
88
|
+
benefits: l.benefits ?? [],
|
|
89
|
+
})),
|
|
90
|
+
basePlans: sub.base_plans.map((bp) => buildBasePlanBody(bp)),
|
|
91
|
+
};
|
|
92
|
+
const result = await apiRequest({
|
|
93
|
+
method: 'POST',
|
|
94
|
+
path: `/applications/${encodeURIComponent(packageName)}/subscriptions`,
|
|
95
|
+
query: {
|
|
96
|
+
productId: sub.product_id,
|
|
97
|
+
'regionsVersion.version': REGIONS_VERSION,
|
|
98
|
+
},
|
|
99
|
+
body,
|
|
100
|
+
label: `Creating subscription: ${sub.product_id}`,
|
|
101
|
+
allowFailure: true,
|
|
102
|
+
});
|
|
103
|
+
if (!result.ok) {
|
|
104
|
+
logger.warn(`Could not create subscription ${sub.product_id}. Skipping its base plans.`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// 2. Activate each base plan so it's available to buyers
|
|
108
|
+
for (const basePlan of sub.base_plans) {
|
|
109
|
+
await activateBasePlan(packageName, sub.product_id, basePlan.base_plan_id);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function buildBasePlanBody(basePlan) {
|
|
113
|
+
const body = {
|
|
114
|
+
basePlanId: basePlan.base_plan_id,
|
|
115
|
+
state: 'DRAFT', // activated in a separate call
|
|
116
|
+
autoRenewingBasePlanType: {
|
|
117
|
+
billingPeriodDuration: basePlan.billing_period,
|
|
118
|
+
resubscribeState: 'RESUBSCRIBE_STATE_ACTIVE',
|
|
119
|
+
...(basePlan.grace_period ? { gracePeriodDuration: basePlan.grace_period } : {}),
|
|
120
|
+
},
|
|
121
|
+
regionalConfigs: Object.entries(buildRegionalConfigs(basePlan.regional_configs)).map(([region, cfg]) => ({
|
|
122
|
+
regionCode: region,
|
|
123
|
+
newSubscriberAvailability: cfg.newSubscriberAvailability,
|
|
124
|
+
price: cfg.price,
|
|
125
|
+
})),
|
|
126
|
+
};
|
|
127
|
+
return body;
|
|
128
|
+
}
|
|
129
|
+
export async function activateBasePlan(packageName, productId, basePlanId) {
|
|
130
|
+
await apiRequest({
|
|
131
|
+
method: 'POST',
|
|
132
|
+
path: `/applications/${encodeURIComponent(packageName)}/subscriptions/${encodeURIComponent(productId)}/basePlans/${encodeURIComponent(basePlanId)}:activate`,
|
|
133
|
+
body: {},
|
|
134
|
+
label: `Activating base plan ${productId}/${basePlanId}`,
|
|
135
|
+
allowFailure: true,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
export async function listInAppProducts(packageName) {
|
|
139
|
+
const existing = new Set();
|
|
140
|
+
let pageToken;
|
|
141
|
+
do {
|
|
142
|
+
const result = await apiRequest({
|
|
143
|
+
method: 'GET',
|
|
144
|
+
path: `/applications/${encodeURIComponent(packageName)}/oneTimeProducts`,
|
|
145
|
+
query: pageToken ? { pageToken } : undefined,
|
|
146
|
+
label: 'Looking up existing one-time products',
|
|
147
|
+
allowFailure: true,
|
|
148
|
+
});
|
|
149
|
+
if (!result.ok)
|
|
150
|
+
return existing;
|
|
151
|
+
for (const p of result.data?.oneTimeProducts ?? []) {
|
|
152
|
+
existing.add(p.productId);
|
|
153
|
+
}
|
|
154
|
+
pageToken = result.data?.nextPageToken;
|
|
155
|
+
} while (pageToken);
|
|
156
|
+
return existing;
|
|
157
|
+
}
|
|
158
|
+
export async function setupInAppProducts(packageName, products) {
|
|
159
|
+
if (products.length === 0) {
|
|
160
|
+
logger.info('No one-time in-app products configured, skipping.');
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const existing = await listInAppProducts(packageName);
|
|
164
|
+
for (const product of products) {
|
|
165
|
+
if (existing.has(product.sku)) {
|
|
166
|
+
logger.info(`One-time product "${product.sku}" already exists, skipping.`);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
await createInAppProduct(packageName, product);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function createInAppProduct(packageName, product) {
|
|
173
|
+
const listings = product.listings.map((loc) => ({
|
|
174
|
+
languageCode: loc.locale,
|
|
175
|
+
title: loc.title,
|
|
176
|
+
description: loc.description ?? '',
|
|
177
|
+
}));
|
|
178
|
+
// Build one purchase option with regional pricing from the config.
|
|
179
|
+
// We default to a single "default" purchase option covering the base price
|
|
180
|
+
// and any per-region overrides the user supplied.
|
|
181
|
+
const allPrices = [product.default_price, ...(product.prices ?? [])];
|
|
182
|
+
// Dedupe by region — if the user listed the same region twice, last wins.
|
|
183
|
+
const byRegion = new Map();
|
|
184
|
+
for (const p of allPrices)
|
|
185
|
+
byRegion.set(p.region_code, p);
|
|
186
|
+
const regionalPricingAndAvailabilityConfigs = Array.from(byRegion.values()).map((p) => ({
|
|
187
|
+
regionCode: p.region_code,
|
|
188
|
+
price: priceToMoney(p.price, p.currency_code),
|
|
189
|
+
availability: 'AVAILABLE',
|
|
190
|
+
}));
|
|
191
|
+
const body = {
|
|
192
|
+
packageName,
|
|
193
|
+
productId: product.sku,
|
|
194
|
+
listings,
|
|
195
|
+
purchaseOptions: [
|
|
196
|
+
{
|
|
197
|
+
purchaseOptionId: 'default',
|
|
198
|
+
buyOption: { legacyCompatible: true },
|
|
199
|
+
regionalPricingAndAvailabilityConfigs,
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
};
|
|
203
|
+
// Note: patch path is lowercase `onetimeproducts` even though list/get use
|
|
204
|
+
// camelCase `oneTimeProducts`. Matches Google's v3 discovery document.
|
|
205
|
+
const result = await apiRequest({
|
|
206
|
+
method: 'PATCH',
|
|
207
|
+
path: `/applications/${encodeURIComponent(packageName)}/onetimeproducts/${encodeURIComponent(product.sku)}`,
|
|
208
|
+
query: {
|
|
209
|
+
allowMissing: 'true',
|
|
210
|
+
'regionsVersion.version': REGIONS_VERSION,
|
|
211
|
+
updateMask: 'listings,purchaseOptions',
|
|
212
|
+
},
|
|
213
|
+
body,
|
|
214
|
+
label: `Creating one-time product: ${product.sku}`,
|
|
215
|
+
allowFailure: true,
|
|
216
|
+
});
|
|
217
|
+
if (!result.ok) {
|
|
218
|
+
logger.warn(`Could not create one-time product ${product.sku}.`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
// New purchase options land in DRAFT state — activate so buyers can see it.
|
|
222
|
+
await activatePurchaseOption(packageName, product.sku, 'default');
|
|
223
|
+
}
|
|
224
|
+
async function activatePurchaseOption(packageName, productId, purchaseOptionId) {
|
|
225
|
+
await apiRequest({
|
|
226
|
+
method: 'POST',
|
|
227
|
+
path: `/applications/${encodeURIComponent(packageName)}/oneTimeProducts/${encodeURIComponent(productId)}/purchaseOptions:batchUpdateStates`,
|
|
228
|
+
body: {
|
|
229
|
+
requests: [
|
|
230
|
+
{
|
|
231
|
+
activatePurchaseOptionRequest: {
|
|
232
|
+
packageName,
|
|
233
|
+
productId,
|
|
234
|
+
purchaseOptionId,
|
|
235
|
+
latencyTolerance: 'PRODUCT_UPDATE_LATENCY_TOLERANCE_LATENCY_SENSITIVE',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
label: `Activating purchase option ${productId}/${purchaseOptionId}`,
|
|
241
|
+
allowFailure: true,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=gpc-monetization.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpc-monetization.service.js","sourceRoot":"","sources":["../../src/services/gpc-monetization.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { GooglePlayAppDetails, GooglePlayListing } from '../types/googleplay.js';
|
|
2
|
+
export declare const PLAY_CONSOLE_URL = "https://play.google.com/console/u/0/developers";
|
|
3
|
+
export declare function getAccessToken(): Promise<string>;
|
|
4
|
+
export interface ApiRequestOptions {
|
|
5
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
6
|
+
path: string;
|
|
7
|
+
query?: Record<string, string | undefined>;
|
|
8
|
+
body?: unknown;
|
|
9
|
+
/** Swallow non-2xx responses and return null instead of exiting. */
|
|
10
|
+
allowFailure?: boolean;
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ApiResponse<T> {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
status: number;
|
|
16
|
+
data: T | null;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function apiRequest<T = unknown>(options: ApiRequestOptions): Promise<ApiResponse<T>>;
|
|
20
|
+
/**
|
|
21
|
+
* Probe whether an app exists on Play Console WITHOUT starting an edit.
|
|
22
|
+
* Uses GET /subscriptions (the new monetization API) which is read-only and
|
|
23
|
+
* works on apps that have been migrated to the new publishing API. The older
|
|
24
|
+
* `/inappproducts` endpoint returns 403 "Please migrate to the new publishing
|
|
25
|
+
* API" for such apps, so we avoid it here.
|
|
26
|
+
*
|
|
27
|
+
* Returns true on 200, false on 404, exits fatal on any other error.
|
|
28
|
+
*/
|
|
29
|
+
export declare function checkAppExists(packageName: string): Promise<boolean>;
|
|
30
|
+
export declare function validateServiceAccount(): Promise<void>;
|
|
31
|
+
export interface AppEdit {
|
|
32
|
+
id: string;
|
|
33
|
+
expiryTimeSeconds?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function insertEdit(packageName: string): Promise<string>;
|
|
36
|
+
export declare function commitEdit(packageName: string, editId: string): Promise<void>;
|
|
37
|
+
export declare function deleteEdit(packageName: string, editId: string): Promise<void>;
|
|
38
|
+
export interface PlayAppDetails {
|
|
39
|
+
defaultLanguage?: string;
|
|
40
|
+
contactWebsite?: string;
|
|
41
|
+
contactEmail?: string;
|
|
42
|
+
contactPhone?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read current app details (default language + contact info) inside an existing
|
|
46
|
+
* edit. Used to discover the app's actual default language before pushing
|
|
47
|
+
* subscriptions — Play rejects subscriptions that don't have a listing in that
|
|
48
|
+
* language, so the caller needs to ensure one exists.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getEditDetails(packageName: string, editId: string): Promise<PlayAppDetails | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Probe Play Console for the app's current default language via a short-lived
|
|
53
|
+
* edit (insert → get details → delete). Returns null if the probe fails so
|
|
54
|
+
* callers can fall back to whatever default they had in their config.
|
|
55
|
+
*/
|
|
56
|
+
export declare function fetchDefaultLanguage(packageName: string): Promise<string | null>;
|
|
57
|
+
export interface PlayAppState {
|
|
58
|
+
defaultLanguage: string | null;
|
|
59
|
+
hasUploadedBuild: boolean;
|
|
60
|
+
tracksWithReleases: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* One-shot probe that starts an edit, reads the details and tracks, and
|
|
64
|
+
* discards the edit — returns everything the orchestrator needs to know about
|
|
65
|
+
* the app's current state in a single transaction. Useful for pre-flight
|
|
66
|
+
* checks before monetization writes.
|
|
67
|
+
*
|
|
68
|
+
* Graceful: returns null if the probe fails (no network, restricted service
|
|
69
|
+
* account, etc.).
|
|
70
|
+
*/
|
|
71
|
+
export declare function fetchAppState(packageName: string): Promise<PlayAppState | null>;
|
|
72
|
+
export declare function withEdit<T>(packageName: string, fn: (editId: string) => Promise<T>): Promise<T>;
|
|
73
|
+
export declare function updateAppDetails(packageName: string, editId: string, defaultLanguage: string, details: GooglePlayAppDetails): Promise<void>;
|
|
74
|
+
export declare function updateListing(packageName: string, editId: string, listing: GooglePlayListing): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Upload a Play Console Data Safety declaration. The API does NOT take
|
|
77
|
+
* structured JSON — it takes a JSON object with a single `safetyLabels` field
|
|
78
|
+
* whose value is the raw CSV content exported from Play Console:
|
|
79
|
+
*
|
|
80
|
+
* POST /applications/{pkg}/dataSafety
|
|
81
|
+
* body: { "safetyLabels": "<csv file contents as string>" }
|
|
82
|
+
*
|
|
83
|
+
* The CSV is app-specific (Google generates different question sets based on
|
|
84
|
+
* the app's category/permissions), so callers must provide the contents of a
|
|
85
|
+
* real CSV exported from this app's Play Console page.
|
|
86
|
+
*/
|
|
87
|
+
export declare function updateDataSafety(packageName: string, csvContents: string): Promise<void>;
|