pabal-store-api-mcp 1.1.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 (111) hide show
  1. package/README.md +95 -0
  2. package/bin/pabal-mcp.js +6 -0
  3. package/dist/src/core/clients/app-store-factory.d.ts +29 -0
  4. package/dist/src/core/clients/app-store-factory.js +72 -0
  5. package/dist/src/core/clients/client-factory-helpers.d.ts +7 -0
  6. package/dist/src/core/clients/client-factory-helpers.js +10 -0
  7. package/dist/src/core/clients/google-play-factory.d.ts +29 -0
  8. package/dist/src/core/clients/google-play-factory.js +72 -0
  9. package/dist/src/core/clients/types.d.ts +8 -0
  10. package/dist/src/core/clients/types.js +1 -0
  11. package/dist/src/core/helpers/formatters.d.ts +3 -0
  12. package/dist/src/core/helpers/formatters.js +38 -0
  13. package/dist/src/core/helpers/registration.d.ts +21 -0
  14. package/dist/src/core/helpers/registration.js +21 -0
  15. package/dist/src/core/helpers/translate-release-notes.d.ts +46 -0
  16. package/dist/src/core/helpers/translate-release-notes.js +87 -0
  17. package/dist/src/core/services/app-resolution-service.d.ts +14 -0
  18. package/dist/src/core/services/app-resolution-service.js +35 -0
  19. package/dist/src/core/services/app-store-service.d.ts +41 -0
  20. package/dist/src/core/services/app-store-service.js +266 -0
  21. package/dist/src/core/services/google-play-service.d.ts +36 -0
  22. package/dist/src/core/services/google-play-service.js +203 -0
  23. package/dist/src/core/services/service-helpers.d.ts +15 -0
  24. package/dist/src/core/services/service-helpers.js +31 -0
  25. package/dist/src/core/services/types.d.ts +81 -0
  26. package/dist/src/core/services/types.js +1 -0
  27. package/dist/src/core/workflows/version-info.d.ts +29 -0
  28. package/dist/src/core/workflows/version-info.js +100 -0
  29. package/dist/src/index.d.ts +10 -0
  30. package/dist/src/index.js +279 -0
  31. package/dist/src/packages/common/errors/app-error.d.ts +39 -0
  32. package/dist/src/packages/common/errors/app-error.js +134 -0
  33. package/dist/src/packages/common/errors/error-codes.d.ts +63 -0
  34. package/dist/src/packages/common/errors/error-codes.js +71 -0
  35. package/dist/src/packages/common/errors/status-codes.d.ts +10 -0
  36. package/dist/src/packages/common/errors/status-codes.js +9 -0
  37. package/dist/src/packages/configs/aso-config/constants.d.ts +14 -0
  38. package/dist/src/packages/configs/aso-config/constants.js +102 -0
  39. package/dist/src/packages/configs/aso-config/locale-guards.d.ts +3 -0
  40. package/dist/src/packages/configs/aso-config/locale-guards.js +7 -0
  41. package/dist/src/packages/configs/aso-config/store.d.ts +11 -0
  42. package/dist/src/packages/configs/aso-config/store.js +11 -0
  43. package/dist/src/packages/configs/aso-config/types.d.ts +98 -0
  44. package/dist/src/packages/configs/aso-config/types.js +2 -0
  45. package/dist/src/packages/configs/aso-config/utils.d.ts +43 -0
  46. package/dist/src/packages/configs/aso-config/utils.js +223 -0
  47. package/dist/src/packages/configs/secrets-config/config.d.ts +12 -0
  48. package/dist/src/packages/configs/secrets-config/config.js +187 -0
  49. package/dist/src/packages/configs/secrets-config/constants.d.ts +1 -0
  50. package/dist/src/packages/configs/secrets-config/constants.js +1 -0
  51. package/dist/src/packages/configs/secrets-config/errors.d.ts +9 -0
  52. package/dist/src/packages/configs/secrets-config/errors.js +15 -0
  53. package/dist/src/packages/configs/secrets-config/registered-apps.d.ts +52 -0
  54. package/dist/src/packages/configs/secrets-config/registered-apps.js +108 -0
  55. package/dist/src/packages/configs/secrets-config/schemas.d.ts +21 -0
  56. package/dist/src/packages/configs/secrets-config/schemas.js +9 -0
  57. package/dist/src/packages/configs/secrets-config/types.d.ts +8 -0
  58. package/dist/src/packages/configs/secrets-config/types.js +1 -0
  59. package/dist/src/packages/stores/app-store/api-converters.d.ts +26 -0
  60. package/dist/src/packages/stores/app-store/api-converters.js +131 -0
  61. package/dist/src/packages/stores/app-store/api-endpoints.d.ts +33 -0
  62. package/dist/src/packages/stores/app-store/api-endpoints.js +157 -0
  63. package/dist/src/packages/stores/app-store/auth.d.ts +12 -0
  64. package/dist/src/packages/stores/app-store/auth.js +36 -0
  65. package/dist/src/packages/stores/app-store/client.d.ts +78 -0
  66. package/dist/src/packages/stores/app-store/client.js +637 -0
  67. package/dist/src/packages/stores/app-store/constants.d.ts +11 -0
  68. package/dist/src/packages/stores/app-store/constants.js +38 -0
  69. package/dist/src/packages/stores/app-store/generated-types.d.ts +118537 -0
  70. package/dist/src/packages/stores/app-store/generated-types.js +5 -0
  71. package/dist/src/packages/stores/app-store/types.d.ts +39 -0
  72. package/dist/src/packages/stores/app-store/types.js +9 -0
  73. package/dist/src/packages/stores/app-store/verify-auth.d.ts +16 -0
  74. package/dist/src/packages/stores/app-store/verify-auth.js +34 -0
  75. package/dist/src/packages/stores/play-store/api-converters.d.ts +58 -0
  76. package/dist/src/packages/stores/play-store/api-converters.js +209 -0
  77. package/dist/src/packages/stores/play-store/api-endpoints.d.ts +68 -0
  78. package/dist/src/packages/stores/play-store/api-endpoints.js +145 -0
  79. package/dist/src/packages/stores/play-store/client.d.ts +55 -0
  80. package/dist/src/packages/stores/play-store/client.js +628 -0
  81. package/dist/src/packages/stores/play-store/constants.d.ts +10 -0
  82. package/dist/src/packages/stores/play-store/constants.js +17 -0
  83. package/dist/src/packages/stores/play-store/types.d.ts +146 -0
  84. package/dist/src/packages/stores/play-store/types.js +9 -0
  85. package/dist/src/packages/stores/play-store/verify-auth.d.ts +13 -0
  86. package/dist/src/packages/stores/play-store/verify-auth.js +31 -0
  87. package/dist/src/tools/apps/add.d.ts +28 -0
  88. package/dist/src/tools/apps/add.js +307 -0
  89. package/dist/src/tools/apps/init.d.ts +58 -0
  90. package/dist/src/tools/apps/init.js +390 -0
  91. package/dist/src/tools/apps/search.d.ts +33 -0
  92. package/dist/src/tools/apps/search.js +147 -0
  93. package/dist/src/tools/aso/pull.d.ts +22 -0
  94. package/dist/src/tools/aso/pull.js +264 -0
  95. package/dist/src/tools/aso/push.d.ts +23 -0
  96. package/dist/src/tools/aso/push.js +189 -0
  97. package/dist/src/tools/auth/app-store.d.ts +9 -0
  98. package/dist/src/tools/auth/app-store.js +34 -0
  99. package/dist/src/tools/auth/check.d.ts +14 -0
  100. package/dist/src/tools/auth/check.js +50 -0
  101. package/dist/src/tools/auth/play-store.d.ts +9 -0
  102. package/dist/src/tools/auth/play-store.js +30 -0
  103. package/dist/src/tools/release/check-versions.d.ts +14 -0
  104. package/dist/src/tools/release/check-versions.js +65 -0
  105. package/dist/src/tools/release/create.d.ts +23 -0
  106. package/dist/src/tools/release/create.js +128 -0
  107. package/dist/src/tools/release/pull-notes.d.ts +22 -0
  108. package/dist/src/tools/release/pull-notes.js +151 -0
  109. package/dist/src/tools/release/update-notes.d.ts +110 -0
  110. package/dist/src/tools/release/update-notes.js +537 -0
  111. package/package.json +71 -0
@@ -0,0 +1,157 @@
1
+ /**
2
+ * App Store Connect API Endpoints
3
+ *
4
+ * Centralized API endpoint management for App Store Connect
5
+ */
6
+ import { APP_STORE_API_BASE_URL, APP_STORE_PLATFORM, DEFAULT_APP_LIST_LIMIT, DEFAULT_VERSIONS_FETCH_LIMIT, } from "./constants.js";
7
+ export class AppStoreApiEndpoints {
8
+ generateToken;
9
+ issuerId;
10
+ keyId;
11
+ constructor(generateToken, issuerId, keyId) {
12
+ this.generateToken = generateToken;
13
+ this.issuerId = issuerId;
14
+ this.keyId = keyId;
15
+ }
16
+ normalizeNextLink(nextLink) {
17
+ if (!nextLink)
18
+ return null;
19
+ return nextLink.replace(APP_STORE_API_BASE_URL, "");
20
+ }
21
+ async request(endpoint, options = {}) {
22
+ const token = await this.generateToken();
23
+ const url = endpoint.startsWith("http")
24
+ ? endpoint
25
+ : `${APP_STORE_API_BASE_URL}${endpoint}`;
26
+ const response = await fetch(url, {
27
+ ...options,
28
+ headers: {
29
+ Authorization: `Bearer ${token}`,
30
+ "Content-Type": "application/json",
31
+ ...options.headers,
32
+ },
33
+ });
34
+ if (!response.ok) {
35
+ const error = await response.json().catch(() => ({ errors: [] }));
36
+ if (response.status === 401) {
37
+ throw new Error(`App Store Connect API authentication failed (401 Unauthorized)\n` +
38
+ `Issuer ID: ${this.issuerId}\n` +
39
+ `Key ID: ${this.keyId}\n` +
40
+ `Error: ${JSON.stringify(error, null, 2)}`);
41
+ }
42
+ if (response.status === 409) {
43
+ const errorDetails = JSON.stringify(error, null, 2);
44
+ if (errorDetails.includes("STATE_ERROR")) {
45
+ throw new Error(`App Store Connect API error: 409 Conflict (STATE_ERROR)\n` +
46
+ `Metadata cannot be modified in current state. Please check app status.\n` +
47
+ `Error: ${errorDetails}`);
48
+ }
49
+ }
50
+ throw new Error(`App Store Connect API error: ${response.status} ${response.statusText}\n${JSON.stringify(error, null, 2)}`);
51
+ }
52
+ return response.json();
53
+ }
54
+ async listApps(nextUrl = `/apps?limit=${DEFAULT_APP_LIST_LIMIT}`) {
55
+ return this.request(nextUrl);
56
+ }
57
+ async findAppByBundleId(bundleId) {
58
+ return this.request(`/apps?filter[bundleId]=${bundleId}`);
59
+ }
60
+ async getApp(appId) {
61
+ return this.request(`/apps/${appId}`);
62
+ }
63
+ async listAppInfos(appId) {
64
+ return this.request(`/apps/${appId}/appInfos?limit=1`);
65
+ }
66
+ async listAppInfoLocalizations(appInfoId, locale) {
67
+ const filter = locale ? `?filter[locale]=${locale}` : "";
68
+ return this.request(`/appInfos/${appInfoId}/appInfoLocalizations${filter}`);
69
+ }
70
+ async updateAppInfoLocalization(localizationId, attributes) {
71
+ await this.request(`/appInfoLocalizations/${localizationId}`, {
72
+ method: "PATCH",
73
+ body: JSON.stringify({
74
+ data: {
75
+ type: "appInfoLocalizations",
76
+ id: localizationId,
77
+ attributes,
78
+ },
79
+ }),
80
+ });
81
+ }
82
+ async createAppInfoLocalization(appInfoId, locale, attributes) {
83
+ return this.request(`/appInfoLocalizations`, {
84
+ method: "POST",
85
+ body: JSON.stringify({
86
+ data: {
87
+ type: "appInfoLocalizations",
88
+ attributes: { locale, ...attributes },
89
+ relationships: {
90
+ appInfo: { data: { type: "appInfos", id: appInfoId } },
91
+ },
92
+ },
93
+ }),
94
+ });
95
+ }
96
+ async listAppStoreVersions(appId, options = {}) {
97
+ const { platform = APP_STORE_PLATFORM, state, limit = DEFAULT_VERSIONS_FETCH_LIMIT, } = options;
98
+ const queryParts = [`filter[platform]=${platform}`, `limit=${limit}`];
99
+ if (state)
100
+ queryParts.push(`filter[appStoreState]=${state}`);
101
+ const query = queryParts.join("&");
102
+ return this.request(`/apps/${appId}/appStoreVersions?${query}`);
103
+ }
104
+ async createAppStoreVersion(appId, versionString, platform = APP_STORE_PLATFORM) {
105
+ return this.request(`/appStoreVersions`, {
106
+ method: "POST",
107
+ body: JSON.stringify({
108
+ data: {
109
+ type: "appStoreVersions",
110
+ attributes: { platform, versionString },
111
+ relationships: { app: { data: { type: "apps", id: appId } } },
112
+ },
113
+ }),
114
+ });
115
+ }
116
+ async listAppStoreVersionLocalizations(versionId, locale) {
117
+ const filter = locale ? `?filter[locale]=${locale}` : "";
118
+ return this.request(`/appStoreVersions/${versionId}/appStoreVersionLocalizations${filter}`);
119
+ }
120
+ async getAppStoreVersionLocalization(localizationId) {
121
+ return this.request(`/appStoreVersionLocalizations/${localizationId}`);
122
+ }
123
+ async updateAppStoreVersionLocalization(localizationId, attributes) {
124
+ await this.request(`/appStoreVersionLocalizations/${localizationId}`, {
125
+ method: "PATCH",
126
+ body: JSON.stringify({
127
+ data: {
128
+ type: "appStoreVersionLocalizations",
129
+ id: localizationId,
130
+ attributes,
131
+ },
132
+ }),
133
+ });
134
+ }
135
+ async createAppStoreVersionLocalization(versionId, locale, attributes) {
136
+ return this.request(`/appStoreVersionLocalizations`, {
137
+ method: "POST",
138
+ body: JSON.stringify({
139
+ data: {
140
+ type: "appStoreVersionLocalizations",
141
+ attributes: { locale, ...attributes },
142
+ relationships: {
143
+ appStoreVersion: {
144
+ data: { type: "appStoreVersions", id: versionId },
145
+ },
146
+ },
147
+ },
148
+ }),
149
+ });
150
+ }
151
+ async listScreenshotSets(localizationId) {
152
+ return this.request(`/appStoreVersionLocalizations/${localizationId}/appScreenshotSets`);
153
+ }
154
+ async listScreenshots(screenshotSetId) {
155
+ return this.request(`/appScreenshotSets/${screenshotSetId}/appScreenshots`);
156
+ }
157
+ }
@@ -0,0 +1,12 @@
1
+ import type { AppStoreConfig } from "../../../packages/configs/secrets-config/types.js";
2
+ type JwtOptions = {
3
+ now?: number;
4
+ expirationSeconds?: number;
5
+ };
6
+ export declare function createAppStoreJWT(config: AppStoreConfig, options?: JwtOptions): Promise<string>;
7
+ export declare function decodeJwt(token: string): {
8
+ header: Record<string, unknown>;
9
+ payload: Record<string, unknown>;
10
+ signature: string;
11
+ };
12
+ export {};
@@ -0,0 +1,36 @@
1
+ import { SignJWT, importPKCS8 } from "jose";
2
+ const AUDIENCE = "appstoreconnect-v1";
3
+ const MAX_EXP_SECONDS = 60 * 20;
4
+ const DEFAULT_EXP_SECONDS = 60 * 10;
5
+ export async function createAppStoreJWT(config, options = {}) {
6
+ const nowSeconds = options.now ?? Math.floor(Date.now() / 1000);
7
+ const expSeconds = Math.min(options.expirationSeconds ?? DEFAULT_EXP_SECONDS, MAX_EXP_SECONDS);
8
+ // Normalize private key
9
+ const normalizedKey = config.privateKey.replace(/\\n/g, "\n").trim();
10
+ // Import private key in PKCS8 format
11
+ const privateKey = await importPKCS8(normalizedKey, "ES256");
12
+ // Create JWT (App Store Connect API does not require iat)
13
+ const jwt = await new SignJWT({
14
+ iss: config.issuerId,
15
+ aud: AUDIENCE,
16
+ })
17
+ .setProtectedHeader({
18
+ alg: "ES256",
19
+ kid: config.keyId,
20
+ typ: "JWT",
21
+ })
22
+ .setExpirationTime(nowSeconds + expSeconds)
23
+ .sign(privateKey);
24
+ return jwt;
25
+ }
26
+ export function decodeJwt(token) {
27
+ const [header, payload, signature] = token.split(".");
28
+ if (!header || !payload || !signature) {
29
+ throw new Error("Invalid JWT format");
30
+ }
31
+ return {
32
+ header: JSON.parse(Buffer.from(header, "base64url").toString("utf-8")),
33
+ payload: JSON.parse(Buffer.from(payload, "base64url").toString("utf-8")),
34
+ signature,
35
+ };
36
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * App Store Connect API Client
3
+ *
4
+ * Authentication: API Key (Issuer ID, Key ID, Private Key) required
5
+ * API Documentation: https://developer.apple.com/documentation/appstoreconnectapi
6
+ */
7
+ import type { AppStoreAsoData, AppStoreMultilingualAsoData, AppStoreReleaseNote } from "../../../packages/configs/aso-config/types.js";
8
+ import type { AppStoreClientConfig, AppStoreVersion } from "./types.js";
9
+ export declare class AppStoreClient {
10
+ private issuerId;
11
+ private keyId;
12
+ private privateKey;
13
+ private bundleId;
14
+ private sdk;
15
+ private apiCache;
16
+ constructor(config: AppStoreClientConfig);
17
+ private normalizePrivateKey;
18
+ /**
19
+ * List all apps registered in the account
20
+ * @param options.onlyReleased - If true, returns only released apps (apps with READY_FOR_SALE status)
21
+ */
22
+ listAllApps(options?: {
23
+ onlyReleased?: boolean;
24
+ }): Promise<Array<{
25
+ id: string;
26
+ name: string;
27
+ bundleId: string;
28
+ sku: string;
29
+ isReleased: boolean;
30
+ }>>;
31
+ private checkAppReleased;
32
+ private getEnglishAppName;
33
+ /**
34
+ * Get supported locales for an app
35
+ */
36
+ getSupportedLocales(appId: string): Promise<string[]>;
37
+ private findAppId;
38
+ private findAppInfoId;
39
+ pullAsoData(options?: {
40
+ locale?: string;
41
+ }): Promise<AppStoreAsoData>;
42
+ pullAllLocalesAsoData(): Promise<AppStoreMultilingualAsoData>;
43
+ pushAsoData(data: Partial<AppStoreAsoData>): Promise<{
44
+ failedFields?: string[];
45
+ }>;
46
+ getAllVersions(limit?: number): Promise<AppStoreVersion[]>;
47
+ getLatestVersion(): Promise<AppStoreVersion | null>;
48
+ incrementVersion(versionString: string): string;
49
+ createNewVersion(versionString: string): Promise<AppStoreVersion>;
50
+ createNewVersionWithAutoIncrement(baseVersion?: string): Promise<AppStoreVersion>;
51
+ updateWhatsNew(options: {
52
+ versionId: string;
53
+ locale: string;
54
+ whatsNew: string;
55
+ }): Promise<void>;
56
+ pullReleaseNotes(): Promise<AppStoreReleaseNote[]>;
57
+ private normalizeNextLink;
58
+ private listApps;
59
+ private findAppByBundleId;
60
+ private getApp;
61
+ private listAppInfos;
62
+ private listAppInfoLocalizations;
63
+ private updateAppInfoLocalization;
64
+ private createAppInfoLocalization;
65
+ private listAppStoreVersions;
66
+ private createAppStoreVersion;
67
+ private listAppStoreVersionLocalizations;
68
+ private getAppStoreVersionLocalization;
69
+ private updateAppStoreVersionLocalization;
70
+ private createAppStoreVersionLocalization;
71
+ private listScreenshotSets;
72
+ private listScreenshots;
73
+ private getApi;
74
+ private normalizeEndpoint;
75
+ private requestCollection;
76
+ private formatErrorPayload;
77
+ private handleSdkError;
78
+ }