kappmaker 1.1.0 → 1.2.1
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 +254 -30
- package/dist/cli.js +87 -1
- 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/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 +133 -54
- 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-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 +1 -1
- package/dist/commands/publish.js +1 -1
- package/dist/commands/publish.js.map +1 -1
- 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/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/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/refactor.service.js +44 -29
- package/dist/services/refactor.service.js.map +1 -1
- 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/utils/config.d.ts +1 -0
- package/dist/utils/config.js +4 -0
- package/dist/utils/config.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { promptInput, confirm } from '../utils/prompt.js';
|
|
6
|
+
import { loadConfig, getGooglePlayTemplate } from '../utils/config.js';
|
|
7
|
+
import * as gpc from '../services/gpc.service.js';
|
|
8
|
+
import * as gpcMoney from '../services/gpc-monetization.service.js';
|
|
9
|
+
import { buildDataSafetyCsv } from '../services/gpc-data-safety.service.js';
|
|
10
|
+
const CONFIG_FILENAME = 'Assets/googleplay-config.json';
|
|
11
|
+
const TOTAL_STEPS = 11;
|
|
12
|
+
export async function createPlayApp(options) {
|
|
13
|
+
// Step 1: Validate service account and obtain access token
|
|
14
|
+
logger.step(1, TOTAL_STEPS, 'Validating Google Play service account');
|
|
15
|
+
const userConfig = await loadConfig();
|
|
16
|
+
if (!userConfig.googleServiceAccountPath) {
|
|
17
|
+
logger.fatal('Google service account path is not set.');
|
|
18
|
+
logger.info('Set it with: kappmaker config set googleServiceAccountPath <path-to-json>');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
await gpc.validateServiceAccount();
|
|
22
|
+
// Step 2: Load config
|
|
23
|
+
logger.step(2, TOTAL_STEPS, 'Loading Google Play config');
|
|
24
|
+
const { config, configPath } = await loadPlayConfig(options.config);
|
|
25
|
+
logger.info(`App: ${config.app.name} (${config.app.package_name})`);
|
|
26
|
+
logger.info(`Default language: ${config.app.default_language}`);
|
|
27
|
+
// Step 3: Review summary
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log(chalk.bold(' Review before proceeding:\n'));
|
|
30
|
+
console.log(` ${chalk.cyan('Config:')} ${configPath}`);
|
|
31
|
+
console.log(` ${chalk.cyan('App:')} ${config.app.name}`);
|
|
32
|
+
console.log(` ${chalk.cyan('Package:')} ${config.app.package_name}`);
|
|
33
|
+
console.log(` ${chalk.cyan('Language:')} ${config.app.default_language}`);
|
|
34
|
+
console.log(` ${chalk.cyan('Listings:')} ${config.listings.length} locale(s)`);
|
|
35
|
+
console.log(` ${chalk.cyan('Subscriptions:')} ${config.subscriptions.length}`);
|
|
36
|
+
if (config.subscriptions.length > 0) {
|
|
37
|
+
for (const sub of config.subscriptions) {
|
|
38
|
+
const firstBp = sub.base_plans[0];
|
|
39
|
+
const price = firstBp?.regional_configs[0];
|
|
40
|
+
const priceLabel = price ? `$${price.price} ${firstBp.base_plan_id}` : '?';
|
|
41
|
+
console.log(` ${chalk.gray('•')} ${sub.product_id} (${priceLabel})`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
console.log(` ${chalk.cyan('IAPs:')} ${config.in_app_products.length}`);
|
|
45
|
+
let dsSummary;
|
|
46
|
+
if (config.data_safety_csv_path)
|
|
47
|
+
dsSummary = `CSV file: ${config.data_safety_csv_path}`;
|
|
48
|
+
else if (config.data_safety)
|
|
49
|
+
dsSummary = `JSON (apply_defaults=${config.data_safety.apply_defaults !== false})`;
|
|
50
|
+
else
|
|
51
|
+
dsSummary = chalk.gray('(not set)');
|
|
52
|
+
console.log(` ${chalk.cyan('Data safety:')} ${dsSummary}`);
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(chalk.gray(' Edit the config file to change any values before continuing.'));
|
|
55
|
+
console.log('');
|
|
56
|
+
const shouldContinue = await confirm(' Continue with these settings?');
|
|
57
|
+
if (!shouldContinue) {
|
|
58
|
+
logger.info(`Config saved at: ${configPath}`);
|
|
59
|
+
logger.info('Edit the file and run the command again.');
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
// Re-read in case the user edited during confirmation
|
|
63
|
+
const finalConfig = await fs.readJson(configPath);
|
|
64
|
+
Object.assign(config, finalConfig);
|
|
65
|
+
// Step 4: Verify app exists on Play Console. Default language was already
|
|
66
|
+
// detected during config load (loadPlayConfig → detectAndApplyDefaultLanguage)
|
|
67
|
+
// and written into config.app.default_language.
|
|
68
|
+
logger.step(4, TOTAL_STEPS, 'Verifying app on Google Play Console');
|
|
69
|
+
const exists = await gpc.checkAppExists(config.app.package_name);
|
|
70
|
+
if (!exists) {
|
|
71
|
+
logger.fatal(`App "${config.app.package_name}" not found on Google Play Console.`);
|
|
72
|
+
logger.info(`Create it manually at: ${gpc.PLAY_CONSOLE_URL}, then rerun.`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
const defaultListing = config.listings.find((l) => l.locale === config.app.default_language);
|
|
76
|
+
const hasUsableDefaultListing = !!(defaultListing?.title && defaultListing.title.trim().length > 0);
|
|
77
|
+
if (!hasUsableDefaultListing) {
|
|
78
|
+
logger.warn(`Default-language listing (${config.app.default_language}) has no title.`);
|
|
79
|
+
logger.info('Fill in listings[].title/short_description/full_description in the config and re-run.');
|
|
80
|
+
logger.info('Skipping steps 5-7 (app details + listings + commit) for this run.');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const editId = await gpc.insertEdit(config.app.package_name);
|
|
84
|
+
logger.info(`Edit ID: ${editId}`);
|
|
85
|
+
// Step 5: Update app details (default language + contact)
|
|
86
|
+
logger.step(5, TOTAL_STEPS, 'Updating app details');
|
|
87
|
+
await gpc.updateAppDetails(config.app.package_name, editId, config.app.default_language, config.details);
|
|
88
|
+
// Step 6: Update store listings per locale (skipping any that are still blank)
|
|
89
|
+
logger.step(6, TOTAL_STEPS, 'Updating store listings');
|
|
90
|
+
for (const listing of config.listings) {
|
|
91
|
+
if (!listing.title || listing.title.trim().length === 0) {
|
|
92
|
+
logger.warn(`Skipping ${listing.locale} listing — title is empty.`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
await gpc.updateListing(config.app.package_name, editId, listing);
|
|
96
|
+
}
|
|
97
|
+
// Step 7: Commit edit
|
|
98
|
+
logger.step(7, TOTAL_STEPS, 'Committing Play Console edit');
|
|
99
|
+
await gpc.commitEdit(config.app.package_name, editId);
|
|
100
|
+
}
|
|
101
|
+
// Step 8: Create / reuse subscriptions (monetization API, outside edit).
|
|
102
|
+
// Subscriptions must contain a listing in the app's default language —
|
|
103
|
+
// `setupSubscriptions` auto-clones the first entry with that locale if missing.
|
|
104
|
+
//
|
|
105
|
+
// Pre-flight: Google Play rejects monetization writes unless the app has at
|
|
106
|
+
// least one build (with the BILLING permission) uploaded to some track —
|
|
107
|
+
// internal testing is enough. Skip step 8 & 9 loudly if that's not the case.
|
|
108
|
+
logger.step(8, TOTAL_STEPS, 'Setting up subscriptions');
|
|
109
|
+
if (cachedAppState && !cachedAppState.hasUploadedBuild) {
|
|
110
|
+
logger.warn('Skipping subscriptions — no build uploaded to any Play Console track.');
|
|
111
|
+
logger.info('Google Play requires at least one build (with BILLING permission) uploaded');
|
|
112
|
+
logger.info('to a track before subscriptions/IAPs can be created via the API.');
|
|
113
|
+
logger.info('Upload one with: kappmaker publish --platform android --track internal');
|
|
114
|
+
logger.info('Then rerun: kappmaker gpc setup');
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
await gpcMoney.setupSubscriptions(config.app.package_name, config.subscriptions, config.app.default_language);
|
|
118
|
+
}
|
|
119
|
+
// Step 9: Create / reuse one-time in-app products
|
|
120
|
+
logger.step(9, TOTAL_STEPS, 'Setting up in-app products');
|
|
121
|
+
if (cachedAppState && !cachedAppState.hasUploadedBuild) {
|
|
122
|
+
logger.warn('Skipping in-app products — no build uploaded to any Play Console track.');
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await gpcMoney.setupInAppProducts(config.app.package_name, config.in_app_products);
|
|
126
|
+
}
|
|
127
|
+
// Step 10: Data safety declaration (standalone endpoint, CSV upload).
|
|
128
|
+
// POST /applications/{pkg}/dataSafety expects `{ safetyLabels: <csv-string> }`
|
|
129
|
+
// where the CSV is an app-specific export from Play Console → Policy →
|
|
130
|
+
// App content → Data safety → "Export to CSV". We don't ship a default
|
|
131
|
+
// because the question set differs per app.
|
|
132
|
+
logger.step(10, TOTAL_STEPS, 'Updating data safety declaration');
|
|
133
|
+
await pushDataSafetyFromConfig(config);
|
|
134
|
+
// Step 11: Manual-only declarations. Google doesn't expose any of these
|
|
135
|
+
// in the Publisher API v3 — verified against the discovery document
|
|
136
|
+
// ($discovery/rest?version=v3). They must be completed in Play Console.
|
|
137
|
+
logger.step(11, TOTAL_STEPS, 'Wrap-up — manual Play Console declarations');
|
|
138
|
+
printManualDeclarationsChecklist(config.app.package_name);
|
|
139
|
+
// Save updated config (currently unchanged, but mirrors ASC save-back behaviour)
|
|
140
|
+
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
141
|
+
logger.info(`Config saved to ${configPath}`);
|
|
142
|
+
logger.done();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Tracks the Play Console state fetched once during loadPlayConfig so step 8
|
|
146
|
+
* can reuse it without a second probe. Populated as a side-effect of
|
|
147
|
+
* `detectAndApplyDefaultLanguage`.
|
|
148
|
+
*/
|
|
149
|
+
let cachedAppState = null;
|
|
150
|
+
async function loadPlayConfig(configPath) {
|
|
151
|
+
const savePath = configPath ?? path.resolve(CONFIG_FILENAME);
|
|
152
|
+
if (await fs.pathExists(savePath)) {
|
|
153
|
+
logger.info(`Using config: ${savePath}`);
|
|
154
|
+
const config = await fs.readJson(savePath);
|
|
155
|
+
migrateLegacyConfig(config);
|
|
156
|
+
await detectAndApplyDefaultLanguage(config);
|
|
157
|
+
fillSubscriptionDefaults(config);
|
|
158
|
+
await fs.writeJson(savePath, config, { spaces: 2 });
|
|
159
|
+
return { config, configPath: savePath };
|
|
160
|
+
}
|
|
161
|
+
// No config found — prompt for required fields and generate one
|
|
162
|
+
logger.info('No Google Play config file found. Let\'s set up the basics.');
|
|
163
|
+
const template = getGooglePlayTemplate();
|
|
164
|
+
const userConfig = await loadConfig();
|
|
165
|
+
template.app.name = await promptInput(' App name: ');
|
|
166
|
+
const appNameLower = template.app.name.toLowerCase().replace(/\s+/g, '');
|
|
167
|
+
const defaultPackage = userConfig.bundleIdPrefix
|
|
168
|
+
? `${userConfig.bundleIdPrefix}.${appNameLower}`
|
|
169
|
+
: `com.${appNameLower}`;
|
|
170
|
+
template.app.package_name = await promptInput(` Package name (${defaultPackage}): `) || defaultPackage;
|
|
171
|
+
if (!template.details.contact_email) {
|
|
172
|
+
template.details.contact_email = await promptInput(' Contact email: ');
|
|
173
|
+
}
|
|
174
|
+
// Detect Play's actual default language so the template's en-US placeholder
|
|
175
|
+
// gets rewritten to whatever Play Console reports for the real app.
|
|
176
|
+
await detectAndApplyDefaultLanguage(template);
|
|
177
|
+
fillSubscriptionDefaults(template);
|
|
178
|
+
await fs.ensureDir(path.dirname(savePath));
|
|
179
|
+
await fs.writeJson(savePath, template, { spaces: 2 });
|
|
180
|
+
logger.success(`Config saved to ${savePath}`);
|
|
181
|
+
return { config: template, configPath: savePath };
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Probe Play Console for the app's current default language and rewrite the
|
|
185
|
+
* config in place to match. Used to auto-heal configs whose `default_language`
|
|
186
|
+
* was set to the template's fallback ("en-US") but the real app uses something
|
|
187
|
+
* else (e.g. "en-GB"). The store-listing whose locale equals the stale default
|
|
188
|
+
* is also renamed to the detected locale, provided no listing already exists
|
|
189
|
+
* for the new locale.
|
|
190
|
+
*
|
|
191
|
+
* Graceful: if the probe fails (no network, restricted service account, app
|
|
192
|
+
* not found), leaves `config.app.default_language` untouched and moves on.
|
|
193
|
+
*/
|
|
194
|
+
async function detectAndApplyDefaultLanguage(config) {
|
|
195
|
+
if (!config.app.package_name)
|
|
196
|
+
return;
|
|
197
|
+
const state = await gpc.fetchAppState(config.app.package_name);
|
|
198
|
+
cachedAppState = state;
|
|
199
|
+
if (!state)
|
|
200
|
+
return;
|
|
201
|
+
const detected = state.defaultLanguage;
|
|
202
|
+
if (!detected)
|
|
203
|
+
return;
|
|
204
|
+
if (config.app.default_language === detected) {
|
|
205
|
+
logger.info(`Play Console default language: ${detected} (matches config).`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const stale = config.app.default_language;
|
|
209
|
+
logger.warn(`Play Console default language is ${detected}, but config had ${stale}.`);
|
|
210
|
+
logger.info(`Auto-updating config to use "${detected}".`);
|
|
211
|
+
config.app.default_language = detected;
|
|
212
|
+
// Rename the stale-locale store listing so it doesn't get abandoned.
|
|
213
|
+
const staleListing = config.listings.find((l) => l.locale === stale);
|
|
214
|
+
const hasDetectedListing = config.listings.some((l) => l.locale === detected);
|
|
215
|
+
if (staleListing && !hasDetectedListing) {
|
|
216
|
+
staleListing.locale = detected;
|
|
217
|
+
logger.info(`Renamed listing locale "${stale}" → "${detected}".`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (state.hasUploadedBuild) {
|
|
221
|
+
logger.info(`Play Console tracks with uploaded builds: ${state.tracksWithReleases.join(', ')}`);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
logger.warn('No uploaded build found on any Play Console track.');
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Print a checklist of policy declarations that Google's Play Publisher API
|
|
229
|
+
* does NOT expose. All of these must be completed in Play Console before
|
|
230
|
+
* publishing — verified against the v3 discovery document.
|
|
231
|
+
*/
|
|
232
|
+
function printManualDeclarationsChecklist(packageName) {
|
|
233
|
+
const appContentUrl = `https://play.google.com/console/u/0/developers/-/app/-/app-content`;
|
|
234
|
+
console.log('');
|
|
235
|
+
console.log(chalk.bold(' The following App content policy items are not in the Play Publisher API.'));
|
|
236
|
+
console.log(chalk.bold(' Complete them manually in Play Console before publishing:'));
|
|
237
|
+
console.log('');
|
|
238
|
+
const items = [
|
|
239
|
+
'Content rating (IARC questionnaire)',
|
|
240
|
+
'Target audience and content (age groups, child-directed)',
|
|
241
|
+
'Ads declaration (does your app contain ads?)',
|
|
242
|
+
'App access declaration (demo credentials for review if login-walled)',
|
|
243
|
+
'Government apps declaration',
|
|
244
|
+
'Financial features declaration',
|
|
245
|
+
'Health apps declaration (SaMD, health data, health research)',
|
|
246
|
+
'News apps declaration',
|
|
247
|
+
'Gambling declaration',
|
|
248
|
+
'COVID-19 contact tracing declaration (if applicable)',
|
|
249
|
+
'Advertising ID usage declaration',
|
|
250
|
+
'Families policy compliance (if targeting children)',
|
|
251
|
+
'App pricing tier (free vs paid — set at app creation)',
|
|
252
|
+
];
|
|
253
|
+
for (const item of items) {
|
|
254
|
+
console.log(` ${chalk.gray('☐')} ${item}`);
|
|
255
|
+
}
|
|
256
|
+
console.log('');
|
|
257
|
+
console.log(chalk.gray(' Open the App content page at:'));
|
|
258
|
+
console.log(` ${chalk.cyan(appContentUrl)}`);
|
|
259
|
+
console.log(chalk.gray(` (select your "${packageName}" app from the list)`));
|
|
260
|
+
console.log('');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Push data safety declaration. Priority:
|
|
264
|
+
* 1. `data_safety_csv_path` file (if set and exists) — uploaded verbatim,
|
|
265
|
+
* the escape hatch for users who exported a CSV from Play Console.
|
|
266
|
+
* 2. `data_safety` JSON block — converted to CSV via buildDataSafetyCsv()
|
|
267
|
+
* using kappmaker defaults + user overrides.
|
|
268
|
+
* 3. Skip with a helpful message.
|
|
269
|
+
*/
|
|
270
|
+
async function pushDataSafetyFromConfig(config) {
|
|
271
|
+
// (1) Raw CSV escape hatch takes priority when explicitly set.
|
|
272
|
+
if (config.data_safety_csv_path) {
|
|
273
|
+
const csvPath = path.isAbsolute(config.data_safety_csv_path)
|
|
274
|
+
? config.data_safety_csv_path
|
|
275
|
+
: path.resolve(config.data_safety_csv_path);
|
|
276
|
+
if (!(await fs.pathExists(csvPath))) {
|
|
277
|
+
logger.warn(`data_safety_csv_path is set to ${csvPath} but the file does not exist.`);
|
|
278
|
+
logger.info('Skipping data safety push.');
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const csvContents = await fs.readFile(csvPath, 'utf8');
|
|
282
|
+
if (!csvContents.trim()) {
|
|
283
|
+
logger.warn(`Data safety CSV at ${csvPath} is empty — skipping.`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
await gpc.updateDataSafety(config.app.package_name, csvContents);
|
|
287
|
+
logger.info(`Pushed data safety CSV from ${csvPath}`);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
// (2) Structured JSON (primary path).
|
|
291
|
+
if (config.data_safety !== undefined) {
|
|
292
|
+
const csv = buildDataSafetyCsv(config.data_safety);
|
|
293
|
+
await gpc.updateDataSafety(config.app.package_name, csv);
|
|
294
|
+
logger.info('Pushed data safety declaration (built from data_safety JSON).');
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// (3) Nothing configured — skip cleanly.
|
|
298
|
+
logger.info('No data_safety in config, skipping.');
|
|
299
|
+
logger.info('To enable: add a `data_safety: { apply_defaults: true }` block to the config');
|
|
300
|
+
logger.info('or set `data_safety_csv_path` to a Play-Console-exported CSV file.');
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Clean up known-legacy fields in an existing config so subsequent runs don't
|
|
304
|
+
* trip over outdated values. Mutates `config` in place.
|
|
305
|
+
*
|
|
306
|
+
* - Older KAppMaker templates had `data_safety: { dataTypes, securityPractices }`
|
|
307
|
+
* which does NOT match Google's API (POST /dataSafety takes a CSV wrapped in
|
|
308
|
+
* a `safetyLabels` string). Replace any legacy object with the new
|
|
309
|
+
* `data_safety_csv_path` field pointing at `Assets/data-safety.csv`.
|
|
310
|
+
* - `subscriptions[].product_id` values ending in `.v1.<digits>.v1` are the
|
|
311
|
+
* iOS-style format that included the price suffix. Strip the suffix so
|
|
312
|
+
* `fillSubscriptionDefaults` can regenerate the canonical Play product ID.
|
|
313
|
+
*/
|
|
314
|
+
function migrateLegacyConfig(config) {
|
|
315
|
+
// Legacy data_safety object → CSV path.
|
|
316
|
+
// The field is `any`-shaped via a cast so we can safely detect and drop it
|
|
317
|
+
// without declaring it on the current type.
|
|
318
|
+
const legacy = config;
|
|
319
|
+
if (legacy.data_safety !== undefined) {
|
|
320
|
+
delete legacy.data_safety;
|
|
321
|
+
if (config.data_safety_csv_path === undefined) {
|
|
322
|
+
config.data_safety_csv_path = '';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const legacyProductIdRegex = /^(.+\.premium\.[A-Za-z]+\.v1)\.\d+\.v1$/;
|
|
326
|
+
for (const sub of config.subscriptions ?? []) {
|
|
327
|
+
if (sub.product_id) {
|
|
328
|
+
const match = legacyProductIdRegex.exec(sub.product_id);
|
|
329
|
+
if (match) {
|
|
330
|
+
sub.product_id = match[1];
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Auto-generate Google Play subscription product IDs, base plan IDs, and
|
|
337
|
+
* localized listing titles, aligned with the Adapty / App Store naming:
|
|
338
|
+
*
|
|
339
|
+
* product_id: {appname}.premium.{period}.v1 (no price)
|
|
340
|
+
* base_plan_id: autorenew-{period}-{priceDigits}-v1 (e.g. autorenew-weekly-699-v1)
|
|
341
|
+
* listing title: {AppName} Premium {PeriodLabel} (e.g. "Mangit Premium Weekly")
|
|
342
|
+
*
|
|
343
|
+
* The period is derived from the ISO 8601 billing_period (P1W→weekly, P1M→monthly,
|
|
344
|
+
* P3M→quarterly, P6M→semiannual, P1Y→yearly). priceDigits is the first regional
|
|
345
|
+
* config's price with the decimal removed (e.g. "6.99" → "699").
|
|
346
|
+
*
|
|
347
|
+
* Existing non-legacy IDs are preserved. Legacy base_plan_id values (the raw
|
|
348
|
+
* period word like "weekly") are normalized to the new format.
|
|
349
|
+
*/
|
|
350
|
+
function fillSubscriptionDefaults(config) {
|
|
351
|
+
const appName = config.app.name;
|
|
352
|
+
const appNameLower = appName.toLowerCase().replace(/\s+/g, '');
|
|
353
|
+
if (!appNameLower)
|
|
354
|
+
return;
|
|
355
|
+
const billingPeriodToSlug = {
|
|
356
|
+
P1W: 'weekly',
|
|
357
|
+
P1M: 'monthly',
|
|
358
|
+
P2M: 'twomonths',
|
|
359
|
+
P3M: 'quarterly',
|
|
360
|
+
P6M: 'semiannual',
|
|
361
|
+
P1Y: 'yearly',
|
|
362
|
+
};
|
|
363
|
+
const periodLabel = {
|
|
364
|
+
weekly: 'Weekly',
|
|
365
|
+
monthly: 'Monthly',
|
|
366
|
+
twomonths: 'Two Months',
|
|
367
|
+
quarterly: 'Quarterly',
|
|
368
|
+
semiannual: 'Semi Annual',
|
|
369
|
+
yearly: 'Yearly',
|
|
370
|
+
};
|
|
371
|
+
const LEGACY_BASE_PLAN_IDS = new Set([
|
|
372
|
+
'weekly', 'monthly', 'twomonths', 'quarterly', 'semiannual', 'yearly',
|
|
373
|
+
]);
|
|
374
|
+
for (const sub of config.subscriptions) {
|
|
375
|
+
const basePlan = sub.base_plans[0];
|
|
376
|
+
if (!basePlan)
|
|
377
|
+
continue;
|
|
378
|
+
const period = billingPeriodToSlug[basePlan.billing_period] ?? basePlan.base_plan_id;
|
|
379
|
+
const label = periodLabel[period] ?? period;
|
|
380
|
+
const price = basePlan.regional_configs[0]?.price ?? '0';
|
|
381
|
+
const priceTag = price.replace('.', '');
|
|
382
|
+
// Product ID: appname.premium.weekly.v1
|
|
383
|
+
if (!sub.product_id) {
|
|
384
|
+
sub.product_id = `${appNameLower}.premium.${period}.v1`;
|
|
385
|
+
}
|
|
386
|
+
// Base plan ID: autorenew-weekly-699-v1 (normalize legacy "weekly"/"yearly"/etc.)
|
|
387
|
+
if (!basePlan.base_plan_id || LEGACY_BASE_PLAN_IDS.has(basePlan.base_plan_id)) {
|
|
388
|
+
basePlan.base_plan_id = `autorenew-${period}-${priceTag}-v1`;
|
|
389
|
+
}
|
|
390
|
+
// Subscription listing title: "Mangit Premium Weekly" (only if empty or legacy)
|
|
391
|
+
for (const listing of sub.listings) {
|
|
392
|
+
const LEGACY_TITLES = new Set(['Weekly Premium', 'Monthly Premium', 'Yearly Premium', 'Quarterly Premium', 'Semi Annual Premium']);
|
|
393
|
+
if (!listing.title || LEGACY_TITLES.has(listing.title)) {
|
|
394
|
+
listing.title = `${appName} Premium ${label}`;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=create-play-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-play-app.js","sourceRoot":"","sources":["../../src/commands/create-play-app.ts"],"names":[],"mappings":"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"}
|