aso-mcp 1.0.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/build/cache/sqlite-cache.d.ts +10 -0
  4. package/build/cache/sqlite-cache.d.ts.map +1 -0
  5. package/build/cache/sqlite-cache.js +51 -0
  6. package/build/cache/sqlite-cache.js.map +1 -0
  7. package/build/data-sources/app-store-connect.d.ts +12 -0
  8. package/build/data-sources/app-store-connect.d.ts.map +1 -0
  9. package/build/data-sources/app-store-connect.js +415 -0
  10. package/build/data-sources/app-store-connect.js.map +1 -0
  11. package/build/data-sources/app-store.d.ts +7 -0
  12. package/build/data-sources/app-store.d.ts.map +1 -0
  13. package/build/data-sources/app-store.js +28 -0
  14. package/build/data-sources/app-store.js.map +1 -0
  15. package/build/data-sources/aso-scoring.d.ts +15 -0
  16. package/build/data-sources/aso-scoring.d.ts.map +1 -0
  17. package/build/data-sources/aso-scoring.js +140 -0
  18. package/build/data-sources/aso-scoring.js.map +1 -0
  19. package/build/data-sources/custom-scoring.d.ts +52 -0
  20. package/build/data-sources/custom-scoring.d.ts.map +1 -0
  21. package/build/data-sources/custom-scoring.js +83 -0
  22. package/build/data-sources/custom-scoring.js.map +1 -0
  23. package/build/server.d.ts +3 -0
  24. package/build/server.d.ts.map +1 -0
  25. package/build/server.js +69 -0
  26. package/build/server.js.map +1 -0
  27. package/build/tools/analyze-competitors.d.ts +3 -0
  28. package/build/tools/analyze-competitors.d.ts.map +1 -0
  29. package/build/tools/analyze-competitors.js +112 -0
  30. package/build/tools/analyze-competitors.js.map +1 -0
  31. package/build/tools/analyze-reviews.d.ts +3 -0
  32. package/build/tools/analyze-reviews.d.ts.map +1 -0
  33. package/build/tools/analyze-reviews.js +188 -0
  34. package/build/tools/analyze-reviews.js.map +1 -0
  35. package/build/tools/clear-cache.d.ts +3 -0
  36. package/build/tools/clear-cache.d.ts.map +1 -0
  37. package/build/tools/clear-cache.js +32 -0
  38. package/build/tools/clear-cache.js.map +1 -0
  39. package/build/tools/connect-get-app.d.ts +3 -0
  40. package/build/tools/connect-get-app.d.ts.map +1 -0
  41. package/build/tools/connect-get-app.js +56 -0
  42. package/build/tools/connect-get-app.js.map +1 -0
  43. package/build/tools/connect-get-metadata.d.ts +3 -0
  44. package/build/tools/connect-get-metadata.d.ts.map +1 -0
  45. package/build/tools/connect-get-metadata.js +73 -0
  46. package/build/tools/connect-get-metadata.js.map +1 -0
  47. package/build/tools/connect-list-localizations.d.ts +3 -0
  48. package/build/tools/connect-list-localizations.d.ts.map +1 -0
  49. package/build/tools/connect-list-localizations.js +55 -0
  50. package/build/tools/connect-list-localizations.js.map +1 -0
  51. package/build/tools/connect-setup.d.ts +3 -0
  52. package/build/tools/connect-setup.d.ts.map +1 -0
  53. package/build/tools/connect-setup.js +47 -0
  54. package/build/tools/connect-setup.js.map +1 -0
  55. package/build/tools/connect-update-metadata.d.ts +3 -0
  56. package/build/tools/connect-update-metadata.d.ts.map +1 -0
  57. package/build/tools/connect-update-metadata.js +176 -0
  58. package/build/tools/connect-update-metadata.js.map +1 -0
  59. package/build/tools/discover-keywords.d.ts +3 -0
  60. package/build/tools/discover-keywords.d.ts.map +1 -0
  61. package/build/tools/discover-keywords.js +195 -0
  62. package/build/tools/discover-keywords.js.map +1 -0
  63. package/build/tools/generate-aso-brief.d.ts +3 -0
  64. package/build/tools/generate-aso-brief.d.ts.map +1 -0
  65. package/build/tools/generate-aso-brief.js +295 -0
  66. package/build/tools/generate-aso-brief.js.map +1 -0
  67. package/build/tools/get-app-details.d.ts +3 -0
  68. package/build/tools/get-app-details.d.ts.map +1 -0
  69. package/build/tools/get-app-details.js +89 -0
  70. package/build/tools/get-app-details.js.map +1 -0
  71. package/build/tools/get-aso-report.d.ts +3 -0
  72. package/build/tools/get-aso-report.d.ts.map +1 -0
  73. package/build/tools/get-aso-report.js +168 -0
  74. package/build/tools/get-aso-report.js.map +1 -0
  75. package/build/tools/keyword-gap.d.ts +3 -0
  76. package/build/tools/keyword-gap.d.ts.map +1 -0
  77. package/build/tools/keyword-gap.js +116 -0
  78. package/build/tools/keyword-gap.js.map +1 -0
  79. package/build/tools/localized-keywords.d.ts +3 -0
  80. package/build/tools/localized-keywords.d.ts.map +1 -0
  81. package/build/tools/localized-keywords.js +107 -0
  82. package/build/tools/localized-keywords.js.map +1 -0
  83. package/build/tools/optimize-metadata.d.ts +3 -0
  84. package/build/tools/optimize-metadata.d.ts.map +1 -0
  85. package/build/tools/optimize-metadata.js +156 -0
  86. package/build/tools/optimize-metadata.js.map +1 -0
  87. package/build/tools/search-keywords.d.ts +3 -0
  88. package/build/tools/search-keywords.d.ts.map +1 -0
  89. package/build/tools/search-keywords.js +65 -0
  90. package/build/tools/search-keywords.js.map +1 -0
  91. package/build/tools/suggest-keywords.d.ts +3 -0
  92. package/build/tools/suggest-keywords.d.ts.map +1 -0
  93. package/build/tools/suggest-keywords.js +71 -0
  94. package/build/tools/suggest-keywords.js.map +1 -0
  95. package/build/tools/track-ranking.d.ts +3 -0
  96. package/build/tools/track-ranking.d.ts.map +1 -0
  97. package/build/tools/track-ranking.js +94 -0
  98. package/build/tools/track-ranking.js.map +1 -0
  99. package/build/types/index.d.ts +151 -0
  100. package/build/types/index.d.ts.map +1 -0
  101. package/build/types/index.js +2 -0
  102. package/build/types/index.js.map +1 -0
  103. package/build/utils/constants.d.ts +40 -0
  104. package/build/utils/constants.d.ts.map +1 -0
  105. package/build/utils/constants.js +35 -0
  106. package/build/utils/constants.js.map +1 -0
  107. package/build/utils/formatters.d.ts +9 -0
  108. package/build/utils/formatters.d.ts.map +1 -0
  109. package/build/utils/formatters.js +37 -0
  110. package/build/utils/formatters.js.map +1 -0
  111. package/build/utils/localization.d.ts +7 -0
  112. package/build/utils/localization.d.ts.map +1 -0
  113. package/build/utils/localization.js +63 -0
  114. package/build/utils/localization.js.map +1 -0
  115. package/build/utils/rate-limiter.d.ts +7 -0
  116. package/build/utils/rate-limiter.d.ts.map +1 -0
  117. package/build/utils/rate-limiter.js +23 -0
  118. package/build/utils/rate-limiter.js.map +1 -0
  119. package/package.json +60 -0
@@ -0,0 +1,415 @@
1
+ import jwt from "jsonwebtoken";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import os from "os";
5
+ import { withRateLimit } from "../utils/rate-limiter.js";
6
+ import { RATE_LIMITS } from "../utils/constants.js";
7
+ import { countryToLocale } from "../utils/localization.js";
8
+ const RL = RATE_LIMITS["app-store-connect"];
9
+ const BASE_URL = "https://api.appstoreconnect.apple.com";
10
+ const CONFIG_DIR = path.join(os.homedir(), ".aso-mcp");
11
+ const CONFIG_PATH = path.join(CONFIG_DIR, "connect-config.json");
12
+ // ─── Config Management ───
13
+ export function loadConfig() {
14
+ // Try env vars first
15
+ const issuerId = process.env.ASC_ISSUER_ID;
16
+ const apiKeyId = process.env.ASC_KEY_ID;
17
+ const privateKeyPath = process.env.ASC_PRIVATE_KEY_PATH;
18
+ if (issuerId && apiKeyId && privateKeyPath) {
19
+ return { issuerId, apiKeyId, privateKeyPath };
20
+ }
21
+ // Try config file
22
+ try {
23
+ if (fs.existsSync(CONFIG_PATH)) {
24
+ const raw = fs.readFileSync(CONFIG_PATH, "utf-8");
25
+ return JSON.parse(raw);
26
+ }
27
+ }
28
+ catch {
29
+ // ignore
30
+ }
31
+ return null;
32
+ }
33
+ export function saveConfig(config) {
34
+ if (!fs.existsSync(CONFIG_DIR)) {
35
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
36
+ }
37
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
38
+ }
39
+ // ─── JWT Token Generation ───
40
+ function generateToken(config) {
41
+ const privateKey = fs.readFileSync(config.privateKeyPath, "utf-8");
42
+ const now = Math.floor(Date.now() / 1000);
43
+ const payload = {
44
+ iss: config.issuerId,
45
+ iat: now,
46
+ exp: now + 20 * 60,
47
+ aud: "appstoreconnect-v1",
48
+ };
49
+ return jwt.sign(payload, privateKey, {
50
+ algorithm: "ES256",
51
+ header: {
52
+ alg: "ES256",
53
+ kid: config.apiKeyId,
54
+ typ: "JWT",
55
+ },
56
+ });
57
+ }
58
+ // ─── HTTP Wrapper ───
59
+ async function apiRequest(config, endpoint, method = "GET", body) {
60
+ return withRateLimit("app-store-connect", RL, async () => {
61
+ const token = generateToken(config);
62
+ const url = `${BASE_URL}${endpoint}`;
63
+ const headers = {
64
+ Authorization: `Bearer ${token}`,
65
+ "Content-Type": "application/json",
66
+ };
67
+ const res = await fetch(url, {
68
+ method,
69
+ headers,
70
+ body: body ? JSON.stringify(body) : undefined,
71
+ });
72
+ if (!res.ok) {
73
+ const errorBody = await res.text();
74
+ let errorMsg = `App Store Connect API error: ${res.status} ${res.statusText}`;
75
+ try {
76
+ const parsed = JSON.parse(errorBody);
77
+ if (parsed.errors?.[0]?.detail) {
78
+ errorMsg += ` — ${parsed.errors[0].detail}`;
79
+ }
80
+ }
81
+ catch {
82
+ // ignore parse error
83
+ }
84
+ throw new Error(errorMsg);
85
+ }
86
+ const text = await res.text();
87
+ return text ? JSON.parse(text) : null;
88
+ });
89
+ }
90
+ // ─── Public API Functions ───
91
+ export async function validateCredentials(config) {
92
+ // Check .p8 file exists
93
+ if (!fs.existsSync(config.privateKeyPath)) {
94
+ throw new Error(`Private key file not found: ${config.privateKeyPath}`);
95
+ }
96
+ // Test API call — list apps (limit 1)
97
+ await apiRequest(config, "/v1/apps?limit=1");
98
+ return true;
99
+ }
100
+ export async function getApp(config, bundleId) {
101
+ // Find app by bundle ID
102
+ const appsResponse = await apiRequest(config, `/v1/apps?filter[bundleId]=${encodeURIComponent(bundleId)}&fields[apps]=name,bundleId,primaryLocale&limit=1`);
103
+ const app = appsResponse.data?.[0];
104
+ if (!app) {
105
+ throw new Error(`App not found for bundle ID: ${bundleId}`);
106
+ }
107
+ // Get latest editable version (PREPARE_FOR_SUBMISSION)
108
+ let versionId = null;
109
+ let versionState = null;
110
+ try {
111
+ const versionsResponse = await apiRequest(config, `/v1/apps/${app.id}/appStoreVersions?filter[appStoreState]=PREPARE_FOR_SUBMISSION&limit=1`);
112
+ const version = versionsResponse.data?.[0];
113
+ if (version) {
114
+ versionId = version.id;
115
+ versionState = version.attributes?.appStoreState ?? null;
116
+ }
117
+ }
118
+ catch {
119
+ // No editable version — not a fatal error
120
+ }
121
+ return {
122
+ id: app.id,
123
+ bundleId: app.attributes.bundleId,
124
+ name: app.attributes.name,
125
+ primaryLocale: app.attributes.primaryLocale ?? "en-US",
126
+ versionId,
127
+ versionState,
128
+ };
129
+ }
130
+ export async function getMetadata(config, appId, locale = "tr") {
131
+ const resolvedLocale = countryToLocale(locale);
132
+ // Fetch app info localizations (subtitle)
133
+ let subtitle = null;
134
+ let appInfoLocalizationId = null;
135
+ try {
136
+ const appInfosResponse = await apiRequest(config, `/v1/apps/${appId}/appInfos`);
137
+ const allInfos = appInfosResponse.data ?? [];
138
+ const editableInfo = allInfos.find((info) => info.attributes?.appStoreState !== "READY_FOR_SALE");
139
+ const appInfoId = editableInfo?.id ?? allInfos[0]?.id;
140
+ if (appInfoId) {
141
+ const locResponse = await apiRequest(config, `/v1/appInfos/${appInfoId}/appInfoLocalizations?filter[locale]=${resolvedLocale}`);
142
+ const loc = locResponse.data?.[0];
143
+ if (loc) {
144
+ appInfoLocalizationId = loc.id;
145
+ subtitle = loc.attributes?.subtitle ?? null;
146
+ }
147
+ }
148
+ }
149
+ catch {
150
+ // Subtitle not available
151
+ }
152
+ // Fetch version localizations (keywords, description, etc.)
153
+ let keywords = null;
154
+ let description = null;
155
+ let promotionalText = null;
156
+ let whatsNew = null;
157
+ let supportUrl = null;
158
+ let marketingUrl = null;
159
+ let versionLocalizationId = null;
160
+ try {
161
+ // Get the editable version
162
+ const versionsResponse = await apiRequest(config, `/v1/apps/${appId}/appStoreVersions?filter[appStoreState]=PREPARE_FOR_SUBMISSION&limit=1`);
163
+ const versionId = versionsResponse.data?.[0]?.id;
164
+ if (versionId) {
165
+ const verLocResponse = await apiRequest(config, `/v1/appStoreVersions/${versionId}/appStoreVersionLocalizations?filter[locale]=${resolvedLocale}`);
166
+ const verLoc = verLocResponse.data?.[0];
167
+ if (verLoc) {
168
+ versionLocalizationId = verLoc.id;
169
+ keywords = verLoc.attributes?.keywords ?? null;
170
+ description = verLoc.attributes?.description ?? null;
171
+ promotionalText = verLoc.attributes?.promotionalText ?? null;
172
+ whatsNew = verLoc.attributes?.whatsNew ?? null;
173
+ supportUrl = verLoc.attributes?.supportUrl ?? null;
174
+ marketingUrl = verLoc.attributes?.marketingUrl ?? null;
175
+ }
176
+ }
177
+ }
178
+ catch {
179
+ // Version localizations not available
180
+ }
181
+ return {
182
+ locale: resolvedLocale,
183
+ subtitle,
184
+ subtitleLength: subtitle?.length ?? 0,
185
+ keywords,
186
+ keywordsLength: keywords?.length ?? 0,
187
+ description,
188
+ descriptionLength: description?.length ?? 0,
189
+ promotionalText,
190
+ promotionalTextLength: promotionalText?.length ?? 0,
191
+ whatsNew,
192
+ whatsNewLength: whatsNew?.length ?? 0,
193
+ supportUrl,
194
+ marketingUrl,
195
+ appInfoLocalizationId,
196
+ versionLocalizationId,
197
+ };
198
+ }
199
+ // ─── Helper: Get App Info ID ───
200
+ async function getAppInfoId(config, appId) {
201
+ try {
202
+ const response = await apiRequest(config, `/v1/apps/${appId}/appInfos`);
203
+ const appInfos = response.data ?? [];
204
+ // Prefer editable appInfo (not READY_FOR_SALE) for creating new localizations
205
+ const editable = appInfos.find((info) => info.attributes?.appStoreState !== "READY_FOR_SALE");
206
+ return editable?.id ?? appInfos[0]?.id ?? null;
207
+ }
208
+ catch {
209
+ return null;
210
+ }
211
+ }
212
+ // ─── Helper: Get Editable Version ID ───
213
+ async function getEditableVersionId(config, appId) {
214
+ try {
215
+ const response = await apiRequest(config, `/v1/apps/${appId}/appStoreVersions?filter[appStoreState]=PREPARE_FOR_SUBMISSION&limit=1`);
216
+ return response.data?.[0]?.id ?? null;
217
+ }
218
+ catch {
219
+ return null;
220
+ }
221
+ }
222
+ // ─── Create Localization (POST) ───
223
+ async function createAppInfoLocalization(config, appInfoId, locale, attributes) {
224
+ const response = await apiRequest(config, "/v1/appInfoLocalizations", "POST", {
225
+ data: {
226
+ type: "appInfoLocalizations",
227
+ attributes: {
228
+ locale,
229
+ ...attributes,
230
+ },
231
+ relationships: {
232
+ appInfo: {
233
+ data: { type: "appInfos", id: appInfoId },
234
+ },
235
+ },
236
+ },
237
+ });
238
+ return response.data.id;
239
+ }
240
+ async function createVersionLocalization(config, versionId, locale, attributes) {
241
+ const response = await apiRequest(config, "/v1/appStoreVersionLocalizations", "POST", {
242
+ data: {
243
+ type: "appStoreVersionLocalizations",
244
+ attributes: {
245
+ locale,
246
+ ...attributes,
247
+ },
248
+ relationships: {
249
+ appStoreVersion: {
250
+ data: { type: "appStoreVersions", id: versionId },
251
+ },
252
+ },
253
+ },
254
+ });
255
+ return response.data.id;
256
+ }
257
+ // ─── Decode HTML Entities ───
258
+ function decodeHtmlEntities(text) {
259
+ return text
260
+ .replace(/&/g, "&")
261
+ .replace(/&lt;/g, "<")
262
+ .replace(/&gt;/g, ">")
263
+ .replace(/&quot;/g, '"')
264
+ .replace(/&#39;/g, "'")
265
+ .replace(/&#x27;/g, "'")
266
+ .replace(/&#x2F;/g, "/");
267
+ }
268
+ function sanitizeUpdates(updates) {
269
+ const sanitized = {};
270
+ for (const [key, value] of Object.entries(updates)) {
271
+ sanitized[key] =
272
+ value !== undefined ? decodeHtmlEntities(value) : undefined;
273
+ }
274
+ return sanitized;
275
+ }
276
+ // ─── Update Metadata ───
277
+ export async function updateMetadata(config, appId, locale = "tr", updates) {
278
+ const resolvedLocale = countryToLocale(locale);
279
+ // Sanitize: decode any HTML entities before sending to ASC API
280
+ updates = sanitizeUpdates(updates);
281
+ // Get current metadata
282
+ const before = await getMetadata(config, appId, locale);
283
+ // ─── Update/Create App Info Localization (name + subtitle) ───
284
+ const appInfoAttrs = {};
285
+ if (updates.name !== undefined)
286
+ appInfoAttrs.name = updates.name;
287
+ if (updates.subtitle !== undefined)
288
+ appInfoAttrs.subtitle = updates.subtitle;
289
+ if (Object.keys(appInfoAttrs).length > 0) {
290
+ if (before.appInfoLocalizationId) {
291
+ // PATCH existing
292
+ await apiRequest(config, `/v1/appInfoLocalizations/${before.appInfoLocalizationId}`, "PATCH", {
293
+ data: {
294
+ type: "appInfoLocalizations",
295
+ id: before.appInfoLocalizationId,
296
+ attributes: appInfoAttrs,
297
+ },
298
+ });
299
+ }
300
+ else {
301
+ // CREATE new app info localization — 'name' is required by the API
302
+ const appInfoId = await getAppInfoId(config, appId);
303
+ if (!appInfoId) {
304
+ throw new Error(`Could not find appInfo for app "${appId}". Cannot create localization.`);
305
+ }
306
+ if (!appInfoAttrs.name) {
307
+ throw new Error(`Cannot create new localization for "${resolvedLocale}" without a name. ` +
308
+ `Provide the 'name' parameter when adding a new locale.`);
309
+ }
310
+ await createAppInfoLocalization(config, appInfoId, resolvedLocale, appInfoAttrs);
311
+ }
312
+ }
313
+ // ─── Update/Create Version Localization (keywords, description, etc.) ───
314
+ const versionFields = {};
315
+ if (updates.keywords !== undefined)
316
+ versionFields.keywords = updates.keywords;
317
+ if (updates.description !== undefined)
318
+ versionFields.description = updates.description;
319
+ if (updates.promotionalText !== undefined)
320
+ versionFields.promotionalText = updates.promotionalText;
321
+ if (updates.whatsNew !== undefined)
322
+ versionFields.whatsNew = updates.whatsNew;
323
+ if (updates.supportUrl !== undefined)
324
+ versionFields.supportUrl = updates.supportUrl;
325
+ if (updates.marketingUrl !== undefined)
326
+ versionFields.marketingUrl = updates.marketingUrl;
327
+ if (Object.keys(versionFields).length > 0) {
328
+ if (before.versionLocalizationId) {
329
+ // PATCH existing
330
+ await apiRequest(config, `/v1/appStoreVersionLocalizations/${before.versionLocalizationId}`, "PATCH", {
331
+ data: {
332
+ type: "appStoreVersionLocalizations",
333
+ id: before.versionLocalizationId,
334
+ attributes: versionFields,
335
+ },
336
+ });
337
+ }
338
+ else {
339
+ // CREATE new version localization
340
+ const versionId = await getEditableVersionId(config, appId);
341
+ if (!versionId) {
342
+ throw new Error(`No PREPARE_FOR_SUBMISSION version found for app "${appId}". ` +
343
+ `Create a new version in App Store Connect first.`);
344
+ }
345
+ await createVersionLocalization(config, versionId, resolvedLocale, versionFields);
346
+ }
347
+ }
348
+ // Get updated metadata
349
+ const after = await getMetadata(config, appId, locale);
350
+ return { before, after };
351
+ }
352
+ export async function listLocalizations(config, appId) {
353
+ const summaries = [];
354
+ const localeMap = new Map();
355
+ // Get app info localizations
356
+ try {
357
+ const appInfosResponse = await apiRequest(config, `/v1/apps/${appId}/appInfos`);
358
+ const allInfos = appInfosResponse.data ?? [];
359
+ const editableInfo = allInfos.find((info) => info.attributes?.appStoreState !== "READY_FOR_SALE");
360
+ const appInfoId = editableInfo?.id ?? allInfos[0]?.id;
361
+ if (appInfoId) {
362
+ const locResponse = await apiRequest(config, `/v1/appInfos/${appInfoId}/appInfoLocalizations`);
363
+ for (const loc of locResponse.data ?? []) {
364
+ const locale = loc.attributes?.locale;
365
+ if (!locale)
366
+ continue;
367
+ localeMap.set(locale, {
368
+ locale,
369
+ hasSubtitle: !!loc.attributes?.subtitle,
370
+ appInfoLocalizationId: loc.id,
371
+ });
372
+ }
373
+ }
374
+ }
375
+ catch {
376
+ // ignore
377
+ }
378
+ // Get version localizations
379
+ try {
380
+ const versionsResponse = await apiRequest(config, `/v1/apps/${appId}/appStoreVersions?filter[appStoreState]=PREPARE_FOR_SUBMISSION&limit=1`);
381
+ const versionId = versionsResponse.data?.[0]?.id;
382
+ if (versionId) {
383
+ const verLocResponse = await apiRequest(config, `/v1/appStoreVersions/${versionId}/appStoreVersionLocalizations`);
384
+ for (const loc of verLocResponse.data ?? []) {
385
+ const locale = loc.attributes?.locale;
386
+ if (!locale)
387
+ continue;
388
+ const existing = localeMap.get(locale) ?? { locale };
389
+ existing.hasKeywords = !!loc.attributes?.keywords;
390
+ existing.hasDescription = !!loc.attributes?.description;
391
+ existing.hasPromotionalText = !!loc.attributes?.promotionalText;
392
+ existing.hasWhatsNew = !!loc.attributes?.whatsNew;
393
+ existing.versionLocalizationId = loc.id;
394
+ localeMap.set(locale, existing);
395
+ }
396
+ }
397
+ }
398
+ catch {
399
+ // ignore
400
+ }
401
+ for (const [, entry] of localeMap) {
402
+ summaries.push({
403
+ locale: entry.locale,
404
+ hasSubtitle: entry.hasSubtitle ?? false,
405
+ hasKeywords: entry.hasKeywords ?? false,
406
+ hasDescription: entry.hasDescription ?? false,
407
+ hasPromotionalText: entry.hasPromotionalText ?? false,
408
+ hasWhatsNew: entry.hasWhatsNew ?? false,
409
+ appInfoLocalizationId: entry.appInfoLocalizationId ?? null,
410
+ versionLocalizationId: entry.versionLocalizationId ?? null,
411
+ });
412
+ }
413
+ return summaries.sort((a, b) => a.locale.localeCompare(b.locale));
414
+ }
415
+ //# sourceMappingURL=app-store-connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-store-connect.js","sourceRoot":"","sources":["../../src/data-sources/app-store-connect.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAS3D,MAAM,EAAE,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAC5C,MAAM,QAAQ,GAAG,uCAAuC,CAAC;AACzD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACvD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;AAEjE,4BAA4B;AAE5B,MAAM,UAAU,UAAU;IACxB,qBAAqB;IACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACxC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAExD,IAAI,QAAQ,IAAI,QAAQ,IAAI,cAAc,EAAE,CAAC;QAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAChD,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAC1C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC;AAED,+BAA+B;AAE/B,SAAS,aAAa,CAAC,MAAqB;IAC1C,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,MAAM,CAAC,QAAQ;QACpB,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE;QAClB,GAAG,EAAE,oBAAoB;KAC1B,CAAC;IAEF,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE;QACnC,SAAS,EAAE,OAAO;QAClB,MAAM,EAAE;YACN,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,MAAM,CAAC,QAAQ;YACpB,GAAG,EAAE,KAAK;SACX;KACF,CAAC,CAAC;AACL,CAAC;AAED,uBAAuB;AAEvB,KAAK,UAAU,UAAU,CACvB,MAAqB,EACrB,QAAgB,EAChB,SAAiB,KAAK,EACtB,IAAa;IAEb,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;QAErC,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,QAAQ,GAAG,gCAAgC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAC9E,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBACrC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;oBAC/B,QAAQ,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC9C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+BAA+B;AAE/B,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAqB;IAErB,wBAAwB;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,+BAA+B,MAAM,CAAC,cAAc,EAAE,CACvD,CAAC;IACJ,CAAC;IAED,sCAAsC;IACtC,MAAM,UAAU,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAqB,EACrB,QAAgB;IAEhB,wBAAwB;IACxB,MAAM,YAAY,GAAG,MAAM,UAAU,CACnC,MAAM,EACN,6BAA6B,kBAAkB,CAAC,QAAQ,CAAC,mDAAmD,CAC7G,CAAC;IAEF,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,uDAAuD;IACvD,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,YAAY,GAAkB,IAAI,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,EACN,YAAY,GAAG,CAAC,EAAE,wEAAwE,CAC3F,CAAC;QAEF,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;YACvB,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,aAAa,IAAI,IAAI,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IAED,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,QAAQ;QACjC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI;QACzB,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,aAAa,IAAI,OAAO;QACtD,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAqB,EACrB,KAAa,EACb,SAAiB,IAAI;IAErB,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAE/C,0CAA0C;IAC1C,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,qBAAqB,GAAkB,IAAI,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,EACN,YAAY,KAAK,WAAW,CAC7B,CAAC;QACF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAChC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,KAAK,gBAAgB,CACnE,CAAC;QACF,MAAM,SAAS,GAAG,YAAY,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEtD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,MAAM,UAAU,CAClC,MAAM,EACN,gBAAgB,SAAS,wCAAwC,cAAc,EAAE,CAClF,CAAC;YACF,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,GAAG,EAAE,CAAC;gBACR,qBAAqB,GAAG,GAAG,CAAC,EAAE,CAAC;gBAC/B,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE,QAAQ,IAAI,IAAI,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IAED,4DAA4D;IAC5D,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,qBAAqB,GAAkB,IAAI,CAAC;IAEhD,IAAI,CAAC;QACH,2BAA2B;QAC3B,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,EACN,YAAY,KAAK,wEAAwE,CAC1F,CAAC;QACF,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEjD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,cAAc,GAAG,MAAM,UAAU,CACrC,MAAM,EACN,wBAAwB,SAAS,gDAAgD,cAAc,EAAE,CAClG,CAAC;YACF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,IAAI,MAAM,EAAE,CAAC;gBACX,qBAAqB,GAAG,MAAM,CAAC,EAAE,CAAC;gBAClC,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,IAAI,IAAI,CAAC;gBAC/C,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,WAAW,IAAI,IAAI,CAAC;gBACrD,eAAe,GAAG,MAAM,CAAC,UAAU,EAAE,eAAe,IAAI,IAAI,CAAC;gBAC7D,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,IAAI,IAAI,CAAC;gBAC/C,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,UAAU,IAAI,IAAI,CAAC;gBACnD,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE,YAAY,IAAI,IAAI,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,cAAc;QACtB,QAAQ;QACR,cAAc,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrC,QAAQ;QACR,cAAc,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrC,WAAW;QACX,iBAAiB,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;QAC3C,eAAe;QACf,qBAAqB,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;QACnD,QAAQ;QACR,cAAc,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrC,UAAU;QACV,YAAY;QACZ,qBAAqB;QACrB,qBAAqB;KACtB,CAAC;AACJ,CAAC;AAED,kCAAkC;AAElC,KAAK,UAAU,YAAY,CACzB,MAAqB,EACrB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,MAAM,EACN,YAAY,KAAK,WAAW,CAC7B,CAAC;QACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;QACrC,8EAA8E;QAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAC5B,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,KAAK,gBAAgB,CACnE,CAAC;QACF,OAAO,QAAQ,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0CAA0C;AAE1C,KAAK,UAAU,oBAAoB,CACjC,MAAqB,EACrB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,MAAM,EACN,YAAY,KAAK,wEAAwE,CAC1F,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,qCAAqC;AAErC,KAAK,UAAU,yBAAyB,CACtC,MAAqB,EACrB,SAAiB,EACjB,MAAc,EACd,UAAgD;IAEhD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,MAAM,EACN,0BAA0B,EAC1B,MAAM,EACN;QACE,IAAI,EAAE;YACJ,IAAI,EAAE,sBAAsB;YAC5B,UAAU,EAAE;gBACV,MAAM;gBACN,GAAG,UAAU;aACd;YACD,aAAa,EAAE;gBACb,OAAO,EAAE;oBACP,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE;iBAC1C;aACF;SACF;KACF,CACF,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,MAAqB,EACrB,SAAiB,EACjB,MAAc,EACd,UAAkC;IAElC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,MAAM,EACN,kCAAkC,EAClC,MAAM,EACN;QACE,IAAI,EAAE;YACJ,IAAI,EAAE,8BAA8B;YACpC,UAAU,EAAE;gBACV,MAAM;gBACN,GAAG,UAAU;aACd;YACD,aAAa,EAAE;gBACb,eAAe,EAAE;oBACf,IAAI,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,SAAS,EAAE;iBAClD;aACF;SACF;KACF,CACF,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED,+BAA+B;AAE/B,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,IAAI;SACR,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,eAAe,CAAC,OAA8B;IACrD,MAAM,SAAS,GAA0B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,SAAS,CAAC,GAAkC,CAAC;YAC3C,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,0BAA0B;AAE1B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAqB,EACrB,KAAa,EACb,SAAiB,IAAI,EACrB,OAA8B;IAE9B,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAE/C,+DAA+D;IAC/D,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAEnC,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAExD,gEAAgE;IAChE,MAAM,YAAY,GAAyC,EAAE,CAAC;IAC9D,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACjE,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAE7E,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACjC,iBAAiB;YACjB,MAAM,UAAU,CACd,MAAM,EACN,4BAA4B,MAAM,CAAC,qBAAqB,EAAE,EAC1D,OAAO,EACP;gBACE,IAAI,EAAE;oBACJ,IAAI,EAAE,sBAAsB;oBAC5B,EAAE,EAAE,MAAM,CAAC,qBAAqB;oBAChC,UAAU,EAAE,YAAY;iBACzB;aACF,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,mEAAmE;YACnE,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,mCAAmC,KAAK,gCAAgC,CACzE,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,uCAAuC,cAAc,oBAAoB;oBACvE,wDAAwD,CAC3D,CAAC;YACJ,CAAC;YACD,MAAM,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,MAAM,aAAa,GAA2B,EAAE,CAAC;IACjD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9E,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QACnC,aAAa,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAClD,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS;QACvC,aAAa,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9E,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,aAAa,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACpF,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;QAAE,aAAa,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAE1F,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACjC,iBAAiB;YACjB,MAAM,UAAU,CACd,MAAM,EACN,oCAAoC,MAAM,CAAC,qBAAqB,EAAE,EAClE,OAAO,EACP;gBACE,IAAI,EAAE;oBACJ,IAAI,EAAE,8BAA8B;oBACpC,EAAE,EAAE,MAAM,CAAC,qBAAqB;oBAChC,UAAU,EAAE,aAAa;iBAC1B;aACF,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,oDAAoD,KAAK,KAAK;oBAC5D,kDAAkD,CACrD,CAAC;YACJ,CAAC;YACD,MAAM,yBAAyB,CAC7B,MAAM,EACN,SAAS,EACT,cAAc,EACd,aAAa,CACd,CAAC;QACJ,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAqB,EACrB,KAAa;IAEb,MAAM,SAAS,GAAiC,EAAE,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA+C,CAAC;IAEzE,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,EACN,YAAY,KAAK,WAAW,CAC7B,CAAC;QACF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAChC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,KAAK,gBAAgB,CACnE,CAAC;QACF,MAAM,SAAS,GAAG,YAAY,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEtD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,MAAM,UAAU,CAClC,MAAM,EACN,gBAAgB,SAAS,uBAAuB,CACjD,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;gBACzC,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC;gBACtC,IAAI,CAAC,MAAM;oBAAE,SAAS;gBACtB,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE;oBACpB,MAAM;oBACN,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ;oBACvC,qBAAqB,EAAE,GAAG,CAAC,EAAE;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,EACN,YAAY,KAAK,wEAAwE,CAC1F,CAAC;QACF,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEjD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,cAAc,GAAG,MAAM,UAAU,CACrC,MAAM,EACN,wBAAwB,SAAS,+BAA+B,CACjE,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;gBAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC;gBACtC,IAAI,CAAC,MAAM;oBAAE,SAAS;gBACtB,MAAM,QAAQ,GAAwC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;gBAC1F,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC;gBAClD,QAAQ,CAAC,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC;gBACxD,QAAQ,CAAC,kBAAkB,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC;gBAChE,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC;gBAClD,QAAQ,CAAC,qBAAqB,GAAG,GAAG,CAAC,EAAE,CAAC;gBACxC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IAED,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QAClC,SAAS,CAAC,IAAI,CAAC;YACb,MAAM,EAAE,KAAK,CAAC,MAAO;YACrB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;YACvC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;YACvC,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,KAAK;YAC7C,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,IAAI,KAAK;YACrD,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;YACvC,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,IAAI,IAAI;YAC1D,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,IAAI,IAAI;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function searchApps(term: string, country?: string, num?: number): Promise<any[]>;
2
+ export declare function getAppDetails(appId: string | number, country?: string): Promise<any>;
3
+ export declare function getSimilarApps(appId: number, country?: string): Promise<any[]>;
4
+ export declare function getReviews(appId: number, country?: string, page?: number): Promise<any[]>;
5
+ export declare function getRatings(appId: number, country?: string): Promise<any>;
6
+ export declare function getSuggestions(term: string): Promise<string[]>;
7
+ //# sourceMappingURL=app-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-store.d.ts","sourceRoot":"","sources":["../../src/data-sources/app-store.ts"],"names":[],"mappings":"AAMA,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAa,EACtB,GAAG,GAAE,MAAW,GACf,OAAO,CAAC,GAAG,EAAE,CAAC,CAIhB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,GAAE,MAAa,GACrB,OAAO,CAAC,GAAG,CAAC,CAOd;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAa,GACrB,OAAO,CAAC,GAAG,EAAE,CAAC,CAIhB;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAa,EACtB,IAAI,GAAE,MAAU,GACf,OAAO,CAAC,GAAG,EAAE,CAAC,CAIhB;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAa,GACrB,OAAO,CAAC,GAAG,CAAC,CAId;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIpE"}
@@ -0,0 +1,28 @@
1
+ import store from "app-store-scraper";
2
+ import { withRateLimit } from "../utils/rate-limiter.js";
3
+ import { RATE_LIMITS } from "../utils/constants.js";
4
+ const RL = RATE_LIMITS["app-store-scraper"];
5
+ export async function searchApps(term, country = "tr", num = 10) {
6
+ return withRateLimit("app-store-scraper", RL, () => store.search({ term, num, country }));
7
+ }
8
+ export async function getAppDetails(appId, country = "tr") {
9
+ return withRateLimit("app-store-scraper", RL, () => {
10
+ if (typeof appId === "string" && !/^\d+$/.test(appId)) {
11
+ return store.app({ appId, country, ratings: true });
12
+ }
13
+ return store.app({ id: Number(appId), country, ratings: true });
14
+ });
15
+ }
16
+ export async function getSimilarApps(appId, country = "tr") {
17
+ return withRateLimit("app-store-scraper", RL, () => store.similar({ id: appId, country }));
18
+ }
19
+ export async function getReviews(appId, country = "tr", page = 1) {
20
+ return withRateLimit("app-store-scraper", RL, () => store.reviews({ id: appId, country, page, sort: store.sort.RECENT }));
21
+ }
22
+ export async function getRatings(appId, country = "tr") {
23
+ return withRateLimit("app-store-scraper", RL, () => store.ratings({ id: appId, country }));
24
+ }
25
+ export async function getSuggestions(term) {
26
+ return withRateLimit("app-store-scraper", RL, () => store.suggest({ term }));
27
+ }
28
+ //# sourceMappingURL=app-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-store.js","sourceRoot":"","sources":["../../src/data-sources/app-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,EAAE,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,UAAkB,IAAI,EACtB,MAAc,EAAE;IAEhB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,CACjD,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CACrC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAsB,EACtB,UAAkB,IAAI;IAEtB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE;QACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa,EACb,UAAkB,IAAI;IAEtB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,CACjD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CACtC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,UAAkB,IAAI,EACtB,OAAe,CAAC;IAEhB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,CACjD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CACrE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,UAAkB,IAAI;IAEtB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,CACjD,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CACtC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,CACjD,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare function getScores(keyword: string, country?: string): Promise<{
2
+ traffic: number;
3
+ difficulty: number;
4
+ }>;
5
+ export declare function suggestKeywords(appId: string, strategy: "category" | "similar" | "competition", country?: string, num?: number): Promise<string[]>;
6
+ /**
7
+ * Score multiple keywords in parallel with a concurrency limit.
8
+ * Returns results in the same order as input keywords.
9
+ */
10
+ export declare function batchGetScores(keywords: string[], country?: string, concurrency?: number): Promise<{
11
+ keyword: string;
12
+ traffic: number;
13
+ difficulty: number;
14
+ }[]>;
15
+ //# sourceMappingURL=aso-scoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aso-scoring.d.ts","sourceRoot":"","sources":["../../src/data-sources/aso-scoring.ts"],"names":[],"mappings":"AA8DA,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAa,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBlD;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,aAAa,EAChD,OAAO,GAAE,MAAa,EACtB,GAAG,GAAE,MAAW,GACf,OAAO,CAAC,MAAM,EAAE,CAAC,CA0BnB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,GAAE,MAAa,EACtB,WAAW,GAAE,MAAU,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmBrE"}
@@ -0,0 +1,140 @@
1
+ import { withRateLimit } from "../utils/rate-limiter.js";
2
+ import { RATE_LIMITS } from "../utils/constants.js";
3
+ import { searchApps, getSuggestions } from "./app-store.js";
4
+ import { calculateCompetitiveScore } from "./custom-scoring.js";
5
+ const RL = RATE_LIMITS["aso-scores"];
6
+ let asoModule = null;
7
+ let asoAvailable = true;
8
+ async function getAsoModule() {
9
+ if (!asoModule) {
10
+ const mod = await import("aso");
11
+ asoModule = mod.default || mod;
12
+ }
13
+ return asoModule;
14
+ }
15
+ async function getClient(country = "tr") {
16
+ const asoFn = await getAsoModule();
17
+ return asoFn("itunes", { country });
18
+ }
19
+ /**
20
+ * If the aso package returns 503, calculate our own scores from search results.
21
+ * Traffic: estimated from search result count + average review count
22
+ * Difficulty: calculated from rating/review strength of top-ranking apps
23
+ */
24
+ async function fallbackScores(keyword, country) {
25
+ const results = await searchApps(keyword, country, 20);
26
+ if (results.length === 0) {
27
+ return { traffic: 1, difficulty: 1 };
28
+ }
29
+ // Traffic estimate: based on result quality
30
+ const avgReviews = results.reduce((s, a) => s + (a.reviews || 0), 0) /
31
+ results.length;
32
+ const traffic = Math.min(10, Math.max(1, Math.log10(Math.max(1, avgReviews)) * 1.8));
33
+ // Difficulty: competitive score
34
+ const difficulty = calculateCompetitiveScore(results.slice(0, 10).map((a) => ({
35
+ rating: a.score || 0,
36
+ reviews: a.reviews || 0,
37
+ free: a.free ?? true,
38
+ })));
39
+ return {
40
+ traffic: Math.round(traffic * 10) / 10,
41
+ difficulty: Math.round(difficulty * 10) / 10,
42
+ };
43
+ }
44
+ export async function getScores(keyword, country = "tr") {
45
+ // If the aso package has previously failed, use fallback directly
46
+ if (!asoAvailable) {
47
+ return fallbackScores(keyword, country);
48
+ }
49
+ return withRateLimit("aso-scores", RL, async () => {
50
+ try {
51
+ const client = await getClient(country);
52
+ const result = await client.scores(keyword);
53
+ return {
54
+ traffic: result.traffic ?? 0,
55
+ difficulty: result.difficulty ?? 0,
56
+ };
57
+ }
58
+ catch {
59
+ // aso package not working, switch to fallback
60
+ asoAvailable = false;
61
+ return fallbackScores(keyword, country);
62
+ }
63
+ });
64
+ }
65
+ export async function suggestKeywords(appId, strategy, country = "tr", num = 20) {
66
+ // If aso package unavailable, use App Store suggest + search based fallback
67
+ if (!asoAvailable) {
68
+ return fallbackSuggest(appId, strategy, country, num);
69
+ }
70
+ return withRateLimit("aso-scores", RL, async () => {
71
+ try {
72
+ const client = await getClient(country);
73
+ const strategyMap = {
74
+ category: client.CATEGORY,
75
+ similar: client.SIMILAR,
76
+ competition: client.COMPETITION,
77
+ };
78
+ return await client.suggest({
79
+ strategy: strategyMap[strategy],
80
+ appId,
81
+ num,
82
+ });
83
+ }
84
+ catch {
85
+ asoAvailable = false;
86
+ return fallbackSuggest(appId, strategy, country, num);
87
+ }
88
+ });
89
+ }
90
+ /**
91
+ * Score multiple keywords in parallel with a concurrency limit.
92
+ * Returns results in the same order as input keywords.
93
+ */
94
+ export async function batchGetScores(keywords, country = "tr", concurrency = 5) {
95
+ const results = [];
96
+ for (let i = 0; i < keywords.length; i += concurrency) {
97
+ const batch = keywords.slice(i, i + concurrency);
98
+ const batchResults = await Promise.all(batch.map(async (kw) => {
99
+ try {
100
+ const scores = await getScores(kw, country);
101
+ return { keyword: kw, traffic: scores.traffic, difficulty: scores.difficulty };
102
+ }
103
+ catch {
104
+ return { keyword: kw, traffic: 0, difficulty: 0 };
105
+ }
106
+ }));
107
+ results.push(...batchResults);
108
+ }
109
+ return results;
110
+ }
111
+ /**
112
+ * When the aso package is unavailable, generate keyword suggestions via app-store-scraper.
113
+ * Sends keywords from the app's title + description to App Store suggest.
114
+ */
115
+ async function fallbackSuggest(appId, _strategy, country, num) {
116
+ try {
117
+ // App Store autocomplete suggestions
118
+ const suggestions = await getSuggestions(appId);
119
+ if (suggestions.length >= num) {
120
+ return suggestions.slice(0, num);
121
+ }
122
+ // Additionally pull suggestions from simple keywords
123
+ const extraTerms = appId.split(/[.\-_]/).filter((t) => t.length > 2);
124
+ const allSuggestions = new Set(suggestions);
125
+ for (const term of extraTerms.slice(0, 3)) {
126
+ try {
127
+ const more = await getSuggestions(term);
128
+ more.forEach((s) => allSuggestions.add(s));
129
+ }
130
+ catch {
131
+ // continue
132
+ }
133
+ }
134
+ return [...allSuggestions].slice(0, num);
135
+ }
136
+ catch {
137
+ return [];
138
+ }
139
+ }
140
+ //# sourceMappingURL=aso-scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aso-scoring.js","sourceRoot":"","sources":["../../src/data-sources/aso-scoring.ts"],"names":[],"mappings":"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"}