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.
Files changed (92) hide show
  1. package/README.md +481 -33
  2. package/dist/cli.js +146 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/adapty-setup.js +5 -4
  5. package/dist/commands/adapty-setup.js.map +1 -1
  6. package/dist/commands/android-release-build.d.ts +7 -0
  7. package/dist/commands/android-release-build.js +51 -0
  8. package/dist/commands/android-release-build.js.map +1 -0
  9. package/dist/commands/config.js +11 -1
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/create-appstore-app.js +18 -1
  12. package/dist/commands/create-appstore-app.js.map +1 -1
  13. package/dist/commands/create-logo.js +16 -5
  14. package/dist/commands/create-logo.js.map +1 -1
  15. package/dist/commands/create-play-app.d.ts +2 -0
  16. package/dist/commands/create-play-app.js +399 -0
  17. package/dist/commands/create-play-app.js.map +1 -0
  18. package/dist/commands/create.js +138 -64
  19. package/dist/commands/create.js.map +1 -1
  20. package/dist/commands/enhance.js +12 -4
  21. package/dist/commands/enhance.js.map +1 -1
  22. package/dist/commands/fastlane-configure.d.ts +1 -0
  23. package/dist/commands/fastlane-configure.js +9 -0
  24. package/dist/commands/fastlane-configure.js.map +1 -0
  25. package/dist/commands/generate-keystore.d.ts +7 -0
  26. package/dist/commands/generate-keystore.js +14 -0
  27. package/dist/commands/generate-keystore.js.map +1 -0
  28. package/dist/commands/generate-screenshots.js +22 -7
  29. package/dist/commands/generate-screenshots.js.map +1 -1
  30. package/dist/commands/gpc.d.ts +29 -0
  31. package/dist/commands/gpc.js +174 -0
  32. package/dist/commands/gpc.js.map +1 -0
  33. package/dist/commands/publish.d.ts +10 -0
  34. package/dist/commands/publish.js +38 -0
  35. package/dist/commands/publish.js.map +1 -0
  36. package/dist/commands/refactor.d.ts +9 -0
  37. package/dist/commands/refactor.js +9 -0
  38. package/dist/commands/refactor.js.map +1 -0
  39. package/dist/commands/remove-bg.js +12 -4
  40. package/dist/commands/remove-bg.js.map +1 -1
  41. package/dist/commands/translate-screenshots.js +22 -8
  42. package/dist/commands/translate-screenshots.js.map +1 -1
  43. package/dist/commands/update-version.d.ts +5 -0
  44. package/dist/commands/update-version.js +21 -0
  45. package/dist/commands/update-version.js.map +1 -0
  46. package/dist/services/asc-monetization.service.js +39 -29
  47. package/dist/services/asc-monetization.service.js.map +1 -1
  48. package/dist/services/asc.service.d.ts +1 -1
  49. package/dist/services/asc.service.js +94 -12
  50. package/dist/services/asc.service.js.map +1 -1
  51. package/dist/services/fastlane-setup.service.d.ts +1 -0
  52. package/dist/services/fastlane-setup.service.js +50 -0
  53. package/dist/services/fastlane-setup.service.js.map +1 -0
  54. package/dist/services/fastlane.service.js +20 -8
  55. package/dist/services/fastlane.service.js.map +1 -1
  56. package/dist/services/firebase.service.js +48 -18
  57. package/dist/services/firebase.service.js.map +1 -1
  58. package/dist/services/gpc-data-safety.service.d.ts +11 -0
  59. package/dist/services/gpc-data-safety.service.js +160 -0
  60. package/dist/services/gpc-data-safety.service.js.map +1 -0
  61. package/dist/services/gpc-monetization.service.d.ts +18 -0
  62. package/dist/services/gpc-monetization.service.js +244 -0
  63. package/dist/services/gpc-monetization.service.js.map +1 -0
  64. package/dist/services/gpc.service.d.ts +87 -0
  65. package/dist/services/gpc.service.js +338 -0
  66. package/dist/services/gpc.service.js.map +1 -0
  67. package/dist/services/gradle.service.d.ts +0 -3
  68. package/dist/services/gradle.service.js +0 -24
  69. package/dist/services/gradle.service.js.map +1 -1
  70. package/dist/services/keystore.service.d.ts +6 -0
  71. package/dist/services/keystore.service.js +44 -0
  72. package/dist/services/keystore.service.js.map +1 -0
  73. package/dist/services/publish.service.d.ts +10 -0
  74. package/dist/services/publish.service.js +59 -0
  75. package/dist/services/publish.service.js.map +1 -0
  76. package/dist/services/refactor.service.d.ts +3 -0
  77. package/dist/services/refactor.service.js +207 -0
  78. package/dist/services/refactor.service.js.map +1 -0
  79. package/dist/services/version.service.d.ts +10 -0
  80. package/dist/services/version.service.js +75 -0
  81. package/dist/services/version.service.js.map +1 -0
  82. package/dist/templates/Fastfile.txt +209 -0
  83. package/dist/templates/data-safety-template.json +5483 -0
  84. package/dist/templates/googleplay-config.json +71 -0
  85. package/dist/types/googleplay.d.ts +113 -0
  86. package/dist/types/googleplay.js +2 -0
  87. package/dist/types/googleplay.js.map +1 -0
  88. package/dist/types/index.d.ts +1 -0
  89. package/dist/utils/config.d.ts +1 -0
  90. package/dist/utils/config.js +5 -0
  91. package/dist/utils/config.js.map +1 -1
  92. package/package.json +2 -2
@@ -0,0 +1,338 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ import { createSign } from 'node:crypto';
4
+ import ora from 'ora';
5
+ import { logger } from '../utils/logger.js';
6
+ import { loadConfig } from '../utils/config.js';
7
+ // ── Constants ────────────────────────────────────────────────────────
8
+ const API_BASE = 'https://androidpublisher.googleapis.com/androidpublisher/v3';
9
+ const TOKEN_URL = 'https://oauth2.googleapis.com/token';
10
+ const SCOPE = 'https://www.googleapis.com/auth/androidpublisher';
11
+ export const PLAY_CONSOLE_URL = 'https://play.google.com/console/u/0/developers';
12
+ let cachedToken = null;
13
+ async function loadServiceAccount() {
14
+ const config = await loadConfig();
15
+ const resolved = path.resolve(config.googleServiceAccountPath.startsWith('~')
16
+ ? config.googleServiceAccountPath.replace(/^~/, process.env.HOME ?? '')
17
+ : config.googleServiceAccountPath);
18
+ if (!(await fs.pathExists(resolved))) {
19
+ logger.fatal(`Google service account file not found: ${resolved}`);
20
+ logger.info('Set it with: kappmaker config set googleServiceAccountPath <path-to-json>');
21
+ logger.info('Create one at: https://console.cloud.google.com/iam-admin/serviceaccounts');
22
+ process.exit(1);
23
+ }
24
+ const sa = await fs.readJson(resolved);
25
+ if (!sa.client_email || !sa.private_key) {
26
+ logger.fatal(`Invalid service account JSON at ${resolved}: missing client_email or private_key`);
27
+ process.exit(1);
28
+ }
29
+ return sa;
30
+ }
31
+ function base64Url(input) {
32
+ return Buffer.from(input).toString('base64url');
33
+ }
34
+ function buildJwt(sa) {
35
+ const now = Math.floor(Date.now() / 1000);
36
+ const header = { alg: 'RS256', typ: 'JWT' };
37
+ const claim = {
38
+ iss: sa.client_email,
39
+ scope: SCOPE,
40
+ aud: sa.token_uri ?? TOKEN_URL,
41
+ exp: now + 3600,
42
+ iat: now,
43
+ };
44
+ const unsigned = `${base64Url(JSON.stringify(header))}.${base64Url(JSON.stringify(claim))}`;
45
+ const signer = createSign('RSA-SHA256');
46
+ signer.update(unsigned);
47
+ const signature = signer.sign(sa.private_key).toString('base64url');
48
+ return `${unsigned}.${signature}`;
49
+ }
50
+ export async function getAccessToken() {
51
+ if (cachedToken && cachedToken.expiresAt > Date.now() + 60_000) {
52
+ return cachedToken.token;
53
+ }
54
+ const sa = await loadServiceAccount();
55
+ const jwt = buildJwt(sa);
56
+ const response = await fetch(TOKEN_URL, {
57
+ method: 'POST',
58
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
59
+ body: new URLSearchParams({
60
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
61
+ assertion: jwt,
62
+ }),
63
+ });
64
+ if (!response.ok) {
65
+ const body = await response.text();
66
+ logger.fatal(`Failed to obtain Google access token: ${response.status} ${body}`);
67
+ process.exit(1);
68
+ }
69
+ const data = await response.json();
70
+ cachedToken = {
71
+ token: data.access_token,
72
+ expiresAt: Date.now() + data.expires_in * 1000,
73
+ };
74
+ return data.access_token;
75
+ }
76
+ export async function apiRequest(options) {
77
+ const token = await getAccessToken();
78
+ const label = options.label ?? `${options.method} ${options.path}`;
79
+ const spinner = ora({ text: label, indent: 4 }).start();
80
+ const url = new URL(`${API_BASE}${options.path}`);
81
+ if (options.query) {
82
+ for (const [k, v] of Object.entries(options.query)) {
83
+ if (v !== undefined)
84
+ url.searchParams.set(k, v);
85
+ }
86
+ }
87
+ try {
88
+ const response = await fetch(url.toString(), {
89
+ method: options.method,
90
+ headers: {
91
+ Authorization: `Bearer ${token}`,
92
+ ...(options.body !== undefined ? { 'Content-Type': 'application/json' } : {}),
93
+ },
94
+ body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
95
+ });
96
+ const text = await response.text();
97
+ let data = null;
98
+ if (text) {
99
+ try {
100
+ data = JSON.parse(text);
101
+ }
102
+ catch {
103
+ data = null;
104
+ }
105
+ }
106
+ if (!response.ok) {
107
+ spinner.fail(label);
108
+ const message = data?.error?.message ?? text ?? response.statusText;
109
+ if (options.allowFailure) {
110
+ logger.warn(`${label}: ${response.status} ${message}`);
111
+ return { ok: false, status: response.status, data, error: message };
112
+ }
113
+ logger.error(`${label}: ${response.status} ${message}`);
114
+ process.exit(1);
115
+ }
116
+ spinner.succeed(label);
117
+ return { ok: true, status: response.status, data };
118
+ }
119
+ catch (error) {
120
+ spinner.fail(label);
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ if (options.allowFailure) {
123
+ logger.warn(`${label}: ${message}`);
124
+ return { ok: false, status: 0, data: null, error: message };
125
+ }
126
+ logger.error(message);
127
+ process.exit(1);
128
+ }
129
+ }
130
+ // ── App existence probe (side-effect-free) ──────────────────────────
131
+ /**
132
+ * Probe whether an app exists on Play Console WITHOUT starting an edit.
133
+ * Uses GET /subscriptions (the new monetization API) which is read-only and
134
+ * works on apps that have been migrated to the new publishing API. The older
135
+ * `/inappproducts` endpoint returns 403 "Please migrate to the new publishing
136
+ * API" for such apps, so we avoid it here.
137
+ *
138
+ * Returns true on 200, false on 404, exits fatal on any other error.
139
+ */
140
+ export async function checkAppExists(packageName) {
141
+ const result = await apiRequest({
142
+ method: 'GET',
143
+ path: `/applications/${encodeURIComponent(packageName)}/subscriptions`,
144
+ label: `Checking ${packageName} on Play Console`,
145
+ allowFailure: true,
146
+ });
147
+ if (result.ok)
148
+ return true;
149
+ if (result.status === 404)
150
+ return false;
151
+ logger.fatal(`Play Console probe failed: ${result.status} ${result.error ?? ''}`);
152
+ process.exit(1);
153
+ }
154
+ // ── Validation ───────────────────────────────────────────────────────
155
+ export async function validateServiceAccount() {
156
+ await loadServiceAccount(); // throws fatal if missing/invalid
157
+ try {
158
+ await getAccessToken();
159
+ }
160
+ catch (error) {
161
+ const message = error instanceof Error ? error.message : String(error);
162
+ logger.fatal(`Unable to authenticate with Google Play: ${message}`);
163
+ process.exit(1);
164
+ }
165
+ }
166
+ export async function insertEdit(packageName) {
167
+ const result = await apiRequest({
168
+ method: 'POST',
169
+ path: `/applications/${encodeURIComponent(packageName)}/edits`,
170
+ body: {},
171
+ label: `Starting Play Console edit for ${packageName}`,
172
+ allowFailure: true,
173
+ });
174
+ if (!result.ok) {
175
+ if (result.status === 404) {
176
+ logger.fatal(`App "${packageName}" not found on Google Play Console.`);
177
+ logger.info('Apps must be created manually in Play Console before configuring them.');
178
+ logger.info(`Create it at: ${PLAY_CONSOLE_URL}`);
179
+ logger.info('Then rerun this command.');
180
+ process.exit(1);
181
+ }
182
+ logger.fatal(`Failed to start Play Console edit: ${result.error ?? 'unknown error'}`);
183
+ process.exit(1);
184
+ }
185
+ if (!result.data?.id) {
186
+ logger.fatal('Play Console edit created but no id returned.');
187
+ process.exit(1);
188
+ }
189
+ return result.data.id;
190
+ }
191
+ export async function commitEdit(packageName, editId) {
192
+ await apiRequest({
193
+ method: 'POST',
194
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}:commit`,
195
+ label: 'Committing Play Console edit',
196
+ allowFailure: true,
197
+ });
198
+ }
199
+ export async function deleteEdit(packageName, editId) {
200
+ await apiRequest({
201
+ method: 'DELETE',
202
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}`,
203
+ label: 'Discarding Play Console edit',
204
+ allowFailure: true,
205
+ });
206
+ }
207
+ /**
208
+ * Read current app details (default language + contact info) inside an existing
209
+ * edit. Used to discover the app's actual default language before pushing
210
+ * subscriptions — Play rejects subscriptions that don't have a listing in that
211
+ * language, so the caller needs to ensure one exists.
212
+ */
213
+ export async function getEditDetails(packageName, editId) {
214
+ const result = await apiRequest({
215
+ method: 'GET',
216
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}/details`,
217
+ label: 'Fetching current app details',
218
+ allowFailure: true,
219
+ });
220
+ return result.ok ? (result.data ?? null) : null;
221
+ }
222
+ /**
223
+ * Probe Play Console for the app's current default language via a short-lived
224
+ * edit (insert → get details → delete). Returns null if the probe fails so
225
+ * callers can fall back to whatever default they had in their config.
226
+ */
227
+ export async function fetchDefaultLanguage(packageName) {
228
+ const state = await fetchAppState(packageName);
229
+ return state?.defaultLanguage ?? null;
230
+ }
231
+ /**
232
+ * One-shot probe that starts an edit, reads the details and tracks, and
233
+ * discards the edit — returns everything the orchestrator needs to know about
234
+ * the app's current state in a single transaction. Useful for pre-flight
235
+ * checks before monetization writes.
236
+ *
237
+ * Graceful: returns null if the probe fails (no network, restricted service
238
+ * account, etc.).
239
+ */
240
+ export async function fetchAppState(packageName) {
241
+ let editId = null;
242
+ try {
243
+ editId = await insertEdit(packageName);
244
+ const details = await getEditDetails(packageName, editId);
245
+ const tracksResult = await apiRequest({
246
+ method: 'GET',
247
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}/tracks`,
248
+ label: 'Fetching tracks and releases',
249
+ allowFailure: true,
250
+ });
251
+ const tracksWithReleases = [];
252
+ if (tracksResult.ok && tracksResult.data?.tracks) {
253
+ for (const track of tracksResult.data.tracks) {
254
+ const hasRelease = (track.releases ?? []).some((r) => (r.versionCodes?.length ?? 0) > 0);
255
+ if (hasRelease && track.track)
256
+ tracksWithReleases.push(track.track);
257
+ }
258
+ }
259
+ return {
260
+ defaultLanguage: details?.defaultLanguage ?? null,
261
+ hasUploadedBuild: tracksWithReleases.length > 0,
262
+ tracksWithReleases,
263
+ };
264
+ }
265
+ catch {
266
+ return null;
267
+ }
268
+ finally {
269
+ if (editId) {
270
+ await deleteEdit(packageName, editId);
271
+ }
272
+ }
273
+ }
274
+ export async function withEdit(packageName, fn) {
275
+ const editId = await insertEdit(packageName);
276
+ const result = await fn(editId);
277
+ await commitEdit(packageName, editId);
278
+ return result;
279
+ }
280
+ // ── App details ──────────────────────────────────────────────────────
281
+ export async function updateAppDetails(packageName, editId, defaultLanguage, details) {
282
+ const body = { defaultLanguage };
283
+ if (details.contact_website)
284
+ body.contactWebsite = details.contact_website;
285
+ if (details.contact_email)
286
+ body.contactEmail = details.contact_email;
287
+ if (details.contact_phone)
288
+ body.contactPhone = details.contact_phone;
289
+ await apiRequest({
290
+ method: 'PUT',
291
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}/details`,
292
+ body,
293
+ label: 'Updating app details (default language + contact)',
294
+ allowFailure: true,
295
+ });
296
+ }
297
+ // ── Store listings ───────────────────────────────────────────────────
298
+ export async function updateListing(packageName, editId, listing) {
299
+ const body = { language: listing.locale };
300
+ if (listing.title)
301
+ body.title = listing.title;
302
+ if (listing.short_description)
303
+ body.shortDescription = listing.short_description;
304
+ if (listing.full_description)
305
+ body.fullDescription = listing.full_description;
306
+ if (listing.video)
307
+ body.video = listing.video;
308
+ await apiRequest({
309
+ method: 'PUT',
310
+ path: `/applications/${encodeURIComponent(packageName)}/edits/${editId}/listings/${encodeURIComponent(listing.locale)}`,
311
+ body,
312
+ label: `Updating listing (${listing.locale})`,
313
+ allowFailure: true,
314
+ });
315
+ }
316
+ // ── Data safety (standalone, not inside edit) ────────────────────────
317
+ /**
318
+ * Upload a Play Console Data Safety declaration. The API does NOT take
319
+ * structured JSON — it takes a JSON object with a single `safetyLabels` field
320
+ * whose value is the raw CSV content exported from Play Console:
321
+ *
322
+ * POST /applications/{pkg}/dataSafety
323
+ * body: { "safetyLabels": "<csv file contents as string>" }
324
+ *
325
+ * The CSV is app-specific (Google generates different question sets based on
326
+ * the app's category/permissions), so callers must provide the contents of a
327
+ * real CSV exported from this app's Play Console page.
328
+ */
329
+ export async function updateDataSafety(packageName, csvContents) {
330
+ await apiRequest({
331
+ method: 'POST',
332
+ path: `/applications/${encodeURIComponent(packageName)}/dataSafety`,
333
+ body: { safetyLabels: csvContents },
334
+ label: 'Updating data safety declaration',
335
+ allowFailure: true,
336
+ });
337
+ }
338
+ //# sourceMappingURL=gpc.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpc.service.js","sourceRoot":"","sources":["../../src/services/gpc.service.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,2 @@
1
- import type { DerivedConfig } from '../types/index.js';
2
- export declare function hasRefactorPackageTask(mobileDir: string): Promise<boolean>;
3
- export declare function refactorPackage(config: DerivedConfig, mobileDir: string, shouldUpdatePackageName: boolean): Promise<void>;
4
1
  export declare function createLocalProperties(mobileDir: string, androidSdkPath: string): Promise<void>;
5
2
  export declare function cleanAndBuild(mobileDir: string): Promise<void>;
@@ -1,31 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import fs from 'fs-extra';
3
- import { execa } from 'execa';
4
3
  import { run } from '../utils/exec.js';
5
4
  import { logger } from '../utils/logger.js';
6
- export async function hasRefactorPackageTask(mobileDir) {
7
- const gradlewPath = path.join(mobileDir, 'gradlew');
8
- if (!(await fs.pathExists(gradlewPath)))
9
- return false;
10
- try {
11
- const { stdout } = await execa('./gradlew', ['tasks', '--all'], { cwd: mobileDir });
12
- return stdout.includes('refactorPackage');
13
- }
14
- catch {
15
- return false;
16
- }
17
- }
18
- export async function refactorPackage(config, mobileDir, shouldUpdatePackageName) {
19
- await run('./gradlew', [
20
- 'refactorPackage',
21
- `-PnewAppId=${config.packageName}`,
22
- `-PnewAppName=${config.appName}`,
23
- `-PshouldUpdatePackageName=${shouldUpdatePackageName}`,
24
- ], {
25
- cwd: mobileDir,
26
- label: 'Running Gradle refactor (setting package name and app name)',
27
- });
28
- }
29
5
  export async function createLocalProperties(mobileDir, androidSdkPath) {
30
6
  const propsPath = path.join(mobileDir, 'local.properties');
31
7
  await fs.writeFile(propsPath, `sdk.dir=${androidSdkPath}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"gradle.service.js","sourceRoot":"","sources":["../../src/services/gradle.service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,SAAiB;IAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QACpF,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAqB,EACrB,SAAiB,EACjB,uBAAgC;IAEhC,MAAM,GAAG,CACP,WAAW,EACX;QACE,iBAAiB;QACjB,cAAc,MAAM,CAAC,WAAW,EAAE;QAClC,gBAAgB,MAAM,CAAC,OAAO,EAAE;QAChC,6BAA6B,uBAAuB,EAAE;KACvD,EACD;QACE,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,6DAA6D;KACrE,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB,EAAE,cAAsB;IACnF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,cAAc,IAAI,CAAC,CAAC;IAC7D,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE;QAC/C,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,sBAAsB;KAC9B,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE;QACvD,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,4DAA4D;KACpE,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"gradle.service.js","sourceRoot":"","sources":["../../src/services/gradle.service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB,EAAE,cAAsB;IACnF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,cAAc,IAAI,CAAC,CAAC;IAC7D,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE;QAC/C,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,sBAAsB;KAC9B,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE;QACvD,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,4DAA4D;KACpE,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface KeystoreResult {
2
+ keystorePath: string;
3
+ propertiesPath: string;
4
+ }
5
+ export declare function hasKeystore(mobileDir: string): Promise<boolean>;
6
+ export declare function generateKeystore(mobileDir: string, firstName: string, organization: string, outputDir?: string): Promise<KeystoreResult>;
@@ -0,0 +1,44 @@
1
+ import path from 'path';
2
+ import crypto from 'crypto';
3
+ import fs from 'fs-extra';
4
+ import { run } from '../utils/exec.js';
5
+ import { logger } from '../utils/logger.js';
6
+ const KEY_ALIAS = 'aliasKey';
7
+ const KEY_VALIDITY = 10000;
8
+ export async function hasKeystore(mobileDir) {
9
+ const propsPath = path.join(mobileDir, 'distribution', 'android', 'keystore', 'keystore.properties');
10
+ return fs.pathExists(propsPath);
11
+ }
12
+ export async function generateKeystore(mobileDir, firstName, organization, outputDir) {
13
+ const keystoreDir = outputDir
14
+ ? path.resolve(outputDir)
15
+ : path.join(mobileDir, 'distribution', 'android', 'keystore');
16
+ const keystorePath = path.join(keystoreDir, 'keystore.jks');
17
+ const propertiesPath = path.join(keystoreDir, 'keystore.properties');
18
+ await fs.ensureDir(keystoreDir);
19
+ const password = crypto.randomBytes(18).toString('base64url').slice(0, 24);
20
+ await run('keytool', [
21
+ '-genkeypair',
22
+ '-v',
23
+ '-keystore', keystorePath,
24
+ '-storepass', password,
25
+ '-alias', KEY_ALIAS,
26
+ '-keypass', password,
27
+ '-keyalg', 'RSA',
28
+ '-keysize', '2048',
29
+ '-validity', String(KEY_VALIDITY),
30
+ '-dname', `CN=${firstName}, O=${organization}`,
31
+ ], { label: 'Generating Android keystore' });
32
+ const propsContent = [
33
+ `keystorePassword=${password}`,
34
+ `keyPassword=${password}`,
35
+ `keyAlias=${KEY_ALIAS}`,
36
+ `storeFile=../distribution/android/keystore/keystore.jks`,
37
+ '',
38
+ ].join('\n');
39
+ await fs.writeFile(propertiesPath, propsContent, 'utf8');
40
+ logger.success(`Keystore: ${keystorePath}`);
41
+ logger.success(`Properties: ${propertiesPath}`);
42
+ return { keystorePath, propertiesPath };
43
+ }
44
+ //# sourceMappingURL=keystore.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keystore.service.js","sourceRoot":"","sources":["../../src/services/keystore.service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,MAAM,YAAY,GAAG,KAAK,CAAC;AAO3B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC;IACrG,OAAO,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,SAAiB,EACjB,YAAoB,EACpB,SAAkB;IAElB,MAAM,WAAW,GAAG,SAAS;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QACzB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEhE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAErE,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAEhC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE3E,MAAM,GAAG,CACP,SAAS,EACT;QACE,aAAa;QACb,IAAI;QACJ,WAAW,EAAE,YAAY;QACzB,YAAY,EAAE,QAAQ;QACtB,QAAQ,EAAE,SAAS;QACnB,UAAU,EAAE,QAAQ;QACpB,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC;QACjC,QAAQ,EAAE,MAAM,SAAS,OAAO,YAAY,EAAE;KAC/C,EACD,EAAE,KAAK,EAAE,6BAA6B,EAAE,CACzC,CAAC;IAEF,MAAM,YAAY,GAAG;QACnB,oBAAoB,QAAQ,EAAE;QAC9B,eAAe,QAAQ,EAAE;QACzB,YAAY,SAAS,EAAE;QACvB,yDAAyD;QACzD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,CAAC,aAAa,YAAY,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,OAAO,CAAC,eAAe,cAAc,EAAE,CAAC,CAAC;IAEhD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { KAppMakerConfig } from '../types/index.js';
2
+ export interface PublishOptions {
3
+ track: string;
4
+ uploadMetadata: boolean;
5
+ uploadScreenshots: boolean;
6
+ uploadImages: boolean;
7
+ submitForReview: boolean;
8
+ }
9
+ export declare function publishAndroid(mobileDir: string, options: PublishOptions, config: KAppMakerConfig): Promise<void>;
10
+ export declare function publishIos(mobileDir: string, options: PublishOptions, config: KAppMakerConfig): Promise<void>;
@@ -0,0 +1,59 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { runStreaming } from '../utils/exec.js';
4
+ import { logger } from '../utils/logger.js';
5
+ import { getConfigDir } from '../utils/config.js';
6
+ async function ensureAppStorePublisherJson(config) {
7
+ if (!config.ascKeyId || !config.ascIssuerId || !config.ascPrivateKeyPath) {
8
+ logger.error('iOS publishing requires ascKeyId, ascIssuerId, and ascPrivateKeyPath in config.');
9
+ logger.info('Run: kappmaker config set ascKeyId <key-id>');
10
+ logger.info('Run: kappmaker config set ascIssuerId <issuer-id>');
11
+ logger.info('Run: kappmaker config set ascPrivateKeyPath /path/to/AuthKey.p8');
12
+ process.exit(1);
13
+ }
14
+ const p8Path = path.resolve(config.ascPrivateKeyPath);
15
+ if (!(await fs.pathExists(p8Path))) {
16
+ logger.error(`Private key file not found: ${p8Path}`);
17
+ process.exit(1);
18
+ }
19
+ const keyContent = await fs.readFile(p8Path, 'utf8');
20
+ const publisherJson = {
21
+ key_id: config.ascKeyId,
22
+ issuer_id: config.ascIssuerId,
23
+ key: keyContent.trim(),
24
+ };
25
+ const outputPath = path.join(getConfigDir(), 'appstore-publisher.json');
26
+ await fs.writeJson(outputPath, publisherJson, { spaces: 2 });
27
+ return outputPath;
28
+ }
29
+ export async function publishAndroid(mobileDir, options, config) {
30
+ const serviceAccountPath = path.resolve(config.googleServiceAccountPath);
31
+ if (!(await fs.pathExists(serviceAccountPath))) {
32
+ logger.error(`Google Play service account not found: ${serviceAccountPath}`);
33
+ logger.info('Run: kappmaker config set googleServiceAccountPath /path/to/service-account.json');
34
+ process.exit(1);
35
+ }
36
+ logger.info(`Publishing Android to ${options.track} track...`);
37
+ await runStreaming('bundle', [
38
+ 'exec', 'fastlane', 'android', 'playstore_release',
39
+ `track:${options.track}`,
40
+ `service_account:${serviceAccountPath}`,
41
+ `upload_metadata:${options.uploadMetadata}`,
42
+ `upload_screenshots:${options.uploadScreenshots}`,
43
+ `upload_images:${options.uploadImages}`,
44
+ `submit_for_review:${options.submitForReview}`,
45
+ ], { cwd: mobileDir, label: 'Fastlane: Android Play Store release' });
46
+ logger.success('Android publish complete!');
47
+ }
48
+ export async function publishIos(mobileDir, options, config) {
49
+ const apiKeyPath = await ensureAppStorePublisherJson(config);
50
+ logger.info('Publishing iOS to App Store...');
51
+ await runStreaming('bundle', [
52
+ 'exec', 'fastlane', 'ios', 'appstore_release',
53
+ `upload_metadata:${options.uploadMetadata}`,
54
+ `upload_screenshots:${options.uploadScreenshots}`,
55
+ `submit_for_review:${options.submitForReview}`,
56
+ ], { cwd: mobileDir, label: 'Fastlane: iOS App Store release' });
57
+ logger.success('iOS publish complete!');
58
+ }
59
+ //# sourceMappingURL=publish.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.service.js","sourceRoot":"","sources":["../../src/services/publish.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_OLD_APP_ID = "com.measify.kappmaker";
2
+ export declare const DEFAULT_OLD_APP_NAME = "KAppMakerAllModules";
3
+ export declare function refactor(mobileDir: string, newAppId: string, newAppName: string, skipPackageRename: boolean, oldAppId?: string, oldAppName?: string): Promise<void>;