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,5 @@
1
+ /**
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
4
+ */
5
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * App Store Connect API Types
3
+ *
4
+ * Type definitions for App Store Connect operations.
5
+ * Response types are from OpenAPI, Request attribute types are extracted.
6
+ *
7
+ * @see https://developer.apple.com/documentation/appstoreconnectapi
8
+ */
9
+ import type { App as AppModel, AppInfo as AppInfoModel, AppInfoLocalization as AppInfoLocalizationModel, AppScreenshot as AppScreenshotModel, AppScreenshotSet as AppScreenshotSetModel, AppStoreVersion as AppStoreVersionModel, AppStoreVersionLocalization as AppStoreVersionLocalizationModel, AppStoreVersionLocalizationUpdateRequestDataAttributes, AppInfoLocalizationUpdateRequestDataAttributes } from "appstore-connect-sdk/openapi";
10
+ export interface AppStoreClientConfig {
11
+ issuerId: string;
12
+ keyId: string;
13
+ privateKey: string;
14
+ bundleId: string;
15
+ }
16
+ export interface ApiResponse<T> {
17
+ data: T;
18
+ links?: {
19
+ self?: string;
20
+ next?: string;
21
+ };
22
+ }
23
+ export type AppStoreApp = AppModel;
24
+ export type AppInfo = AppInfoModel;
25
+ export type AppInfoLocalization = AppInfoLocalizationModel;
26
+ export type AppStoreVersion = AppStoreVersionModel;
27
+ export type AppStoreLocalization = AppStoreVersionLocalizationModel;
28
+ export type AppStoreScreenshotSet = AppScreenshotSetModel;
29
+ export type AppStoreScreenshot = AppScreenshotModel;
30
+ /**
31
+ * App Info Localization Update Request Attributes
32
+ * @see https://developer.apple.com/documentation/appstoreconnectapi/appinfolocalizationupdaterequest/data/attributes
33
+ */
34
+ export type AppInfoLocalizationUpdateAttributes = AppInfoLocalizationUpdateRequestDataAttributes;
35
+ /**
36
+ * App Store Version Localization Update Request Attributes
37
+ * @see https://developer.apple.com/documentation/appstoreconnectapi/appstoreversionlocalizationupdaterequest/data/attributes
38
+ */
39
+ export type AppStoreVersionLocalizationUpdateAttributes = AppStoreVersionLocalizationUpdateRequestDataAttributes;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * App Store Connect API Types
3
+ *
4
+ * Type definitions for App Store Connect operations.
5
+ * Response types are from OpenAPI, Request attribute types are extracted.
6
+ *
7
+ * @see https://developer.apple.com/documentation/appstoreconnectapi
8
+ */
9
+ export {};
@@ -0,0 +1,16 @@
1
+ export interface VerifyAppStoreAuthResult {
2
+ success: boolean;
3
+ error?: string;
4
+ data?: {
5
+ header: Record<string, unknown>;
6
+ payload: Record<string, unknown>;
7
+ };
8
+ }
9
+ /**
10
+ * Verify App Store Connect authentication configuration and generate JWT token for validation.
11
+ * @param expirationSeconds JWT token expiration time (seconds). Default: 300 seconds
12
+ * @returns Authentication verification result
13
+ */
14
+ export declare function verifyAppStoreAuth({ expirationSeconds, }?: {
15
+ expirationSeconds?: number;
16
+ }): Promise<VerifyAppStoreAuthResult>;
@@ -0,0 +1,34 @@
1
+ import { loadConfig } from "../../../packages/configs/secrets-config/config.js";
2
+ import { createAppStoreJWT, decodeJwt } from "../../../packages/stores/app-store/auth.js";
3
+ /**
4
+ * Verify App Store Connect authentication configuration and generate JWT token for validation.
5
+ * @param expirationSeconds JWT token expiration time (seconds). Default: 300 seconds
6
+ * @returns Authentication verification result
7
+ */
8
+ export async function verifyAppStoreAuth({ expirationSeconds = 300, } = {}) {
9
+ try {
10
+ const cfg = loadConfig().appStore;
11
+ if (!cfg) {
12
+ return {
13
+ success: false,
14
+ error: "App Store configuration not found in ~/.config/pabal-mcp/config.json file.",
15
+ };
16
+ }
17
+ const token = await createAppStoreJWT(cfg, { expirationSeconds });
18
+ const decoded = decodeJwt(token);
19
+ return {
20
+ success: true,
21
+ data: {
22
+ header: decoded.header,
23
+ payload: decoded.payload,
24
+ },
25
+ };
26
+ }
27
+ catch (error) {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ return {
30
+ success: false,
31
+ error: `App Store authentication verification failed: ${message}`,
32
+ };
33
+ }
34
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Google Play Console API Data Converters
3
+ *
4
+ * Data transformation logic between API responses and internal types
5
+ */
6
+ import type { GooglePlayAsoData, GooglePlayMultilingualAsoData, GooglePlayReleaseNote } from "../../../packages/configs/aso-config/types.js";
7
+ import type { ScreenshotUrls, ListingUpdateAttributes, AppDetailsUpdateAttributes, LatestReleaseInfo, ImageType } from "./types.js";
8
+ /**
9
+ * Convert API image responses to screenshot URLs structure
10
+ */
11
+ export declare function fetchScreenshotsAndFeatureGraphic(fetchImagesFunc: (imageType: ImageType) => Promise<any>, language: string): Promise<{
12
+ screenshots: ScreenshotUrls;
13
+ featureGraphic: string | undefined;
14
+ }>;
15
+ /**
16
+ * Convert API listing response to GooglePlayAsoData
17
+ */
18
+ export declare function convertToAsoData(listingData: any, appDetailsData: any, screenshots: ScreenshotUrls, featureGraphic: string | undefined, packageName: string, defaultLanguage: string): GooglePlayAsoData;
19
+ /**
20
+ * Convert API listing to locale-specific ASO data
21
+ */
22
+ export declare function convertToLocaleAsoData(listingData: any, appDetailsData: any, screenshots: ScreenshotUrls, featureGraphic: string | undefined, packageName: string, language: string): GooglePlayAsoData;
23
+ /**
24
+ * Convert multiple locales data to multilingual ASO data structure
25
+ */
26
+ export declare function convertToMultilingualAsoData(locales: Record<string, GooglePlayAsoData>, defaultLocale?: string): GooglePlayMultilingualAsoData;
27
+ /**
28
+ * Build request body for listing update (only defined values)
29
+ */
30
+ export declare function buildListingRequestBody(data: {
31
+ title?: string;
32
+ shortDescription?: string;
33
+ fullDescription?: string;
34
+ }): ListingUpdateAttributes;
35
+ /**
36
+ * Build request body for app details update (only defined values)
37
+ */
38
+ export declare function buildDetailsRequestBody(data: {
39
+ contactEmail?: string;
40
+ contactPhone?: string;
41
+ contactWebsite?: string;
42
+ defaultLanguage?: string;
43
+ }): AppDetailsUpdateAttributes;
44
+ /**
45
+ * Convert track release data to GooglePlayReleaseNote
46
+ */
47
+ export declare function convertToReleaseNote(release: any, versionCode: string | number, trackName: string): GooglePlayReleaseNote | null;
48
+ /**
49
+ * Convert release notes map to API format
50
+ */
51
+ export declare function convertReleaseNotesToApiFormat(releaseNotes: Record<string, string>): Array<{
52
+ language: string;
53
+ text: string;
54
+ }>;
55
+ /**
56
+ * Extract latest release from track releases
57
+ */
58
+ export declare function extractLatestRelease(releases: any[]): LatestReleaseInfo | null;
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Google Play Console API Data Converters
3
+ *
4
+ * Data transformation logic between API responses and internal types
5
+ */
6
+ import { DEFAULT_LOCALE } from "../../../packages/configs/aso-config/constants.js";
7
+ import { IMAGE_TYPES } from "./constants.js";
8
+ /**
9
+ * Convert API image responses to screenshot URLs structure
10
+ */
11
+ export async function fetchScreenshotsAndFeatureGraphic(fetchImagesFunc, language) {
12
+ const screenshots = {
13
+ phone: [],
14
+ tablet7: [],
15
+ tablet10: [],
16
+ tv: [],
17
+ wear: [],
18
+ };
19
+ let featureGraphic;
20
+ for (const imageType of IMAGE_TYPES) {
21
+ try {
22
+ const imagesResponse = await fetchImagesFunc(imageType);
23
+ const images = imagesResponse.data.images || [];
24
+ if (imageType === "featureGraphic") {
25
+ featureGraphic = images[0]?.url;
26
+ }
27
+ else {
28
+ const urls = images
29
+ .map((img) => img.url)
30
+ .filter(Boolean);
31
+ if (imageType === "phoneScreenshots") {
32
+ screenshots.phone.push(...urls);
33
+ }
34
+ else if (imageType === "sevenInchScreenshots") {
35
+ screenshots.tablet7.push(...urls);
36
+ }
37
+ else if (imageType === "tenInchScreenshots") {
38
+ screenshots.tablet10.push(...urls);
39
+ }
40
+ else if (imageType === "tvScreenshots") {
41
+ screenshots.tv.push(...urls);
42
+ }
43
+ else if (imageType === "wearScreenshots") {
44
+ screenshots.wear.push(...urls);
45
+ }
46
+ }
47
+ }
48
+ catch (error) {
49
+ const err = error;
50
+ if (err.code !== 404) {
51
+ console.warn(`⚠️ Failed to fetch ${imageType} images for ${language}:`, err.message);
52
+ }
53
+ }
54
+ }
55
+ return { screenshots, featureGraphic };
56
+ }
57
+ /**
58
+ * Convert API listing response to GooglePlayAsoData
59
+ */
60
+ export function convertToAsoData(listingData, appDetailsData, screenshots, featureGraphic, packageName, defaultLanguage) {
61
+ return {
62
+ title: listingData.title || "",
63
+ shortDescription: listingData.shortDescription || "",
64
+ fullDescription: listingData.fullDescription || "",
65
+ screenshots,
66
+ featureGraphic,
67
+ category: appDetailsData.category || "",
68
+ packageName,
69
+ defaultLanguage,
70
+ contactEmail: appDetailsData.contactEmail ?? undefined,
71
+ contactPhone: appDetailsData.contactPhone ?? undefined,
72
+ contactWebsite: appDetailsData.contactWebsite ?? undefined,
73
+ };
74
+ }
75
+ /**
76
+ * Convert API listing to locale-specific ASO data
77
+ */
78
+ export function convertToLocaleAsoData(listingData, appDetailsData, screenshots, featureGraphic, packageName, language) {
79
+ return {
80
+ title: listingData.title || "",
81
+ shortDescription: listingData.shortDescription || "",
82
+ fullDescription: listingData.fullDescription || "",
83
+ screenshots,
84
+ featureGraphic,
85
+ category: appDetailsData.category || "",
86
+ packageName,
87
+ defaultLanguage: language,
88
+ contactEmail: appDetailsData.contactEmail ?? undefined,
89
+ contactPhone: appDetailsData.contactPhone ?? undefined,
90
+ contactWebsite: appDetailsData.contactWebsite ?? undefined,
91
+ };
92
+ }
93
+ /**
94
+ * Convert multiple locales data to multilingual ASO data structure
95
+ */
96
+ export function convertToMultilingualAsoData(locales, defaultLocale) {
97
+ let finalDefaultLocale = defaultLocale;
98
+ if (!finalDefaultLocale && Object.keys(locales).length > 0) {
99
+ // Try to find DEFAULT_LOCALE
100
+ if (locales[DEFAULT_LOCALE]) {
101
+ finalDefaultLocale = DEFAULT_LOCALE;
102
+ }
103
+ else {
104
+ // Use first available locale
105
+ finalDefaultLocale = Object.keys(locales)[0];
106
+ }
107
+ }
108
+ return {
109
+ locales,
110
+ defaultLocale: finalDefaultLocale || DEFAULT_LOCALE,
111
+ };
112
+ }
113
+ /**
114
+ * Build request body for listing update (only defined values)
115
+ */
116
+ export function buildListingRequestBody(data) {
117
+ const body = {};
118
+ if (data.title)
119
+ body.title = data.title;
120
+ if (data.shortDescription)
121
+ body.shortDescription = data.shortDescription;
122
+ if (data.fullDescription)
123
+ body.fullDescription = data.fullDescription;
124
+ return body;
125
+ }
126
+ /**
127
+ * Build request body for app details update (only defined values)
128
+ */
129
+ export function buildDetailsRequestBody(data) {
130
+ const body = {};
131
+ if (data.defaultLanguage)
132
+ body.defaultLanguage = data.defaultLanguage;
133
+ if (data.contactEmail)
134
+ body.contactEmail = data.contactEmail;
135
+ if (data.contactPhone)
136
+ body.contactPhone = data.contactPhone;
137
+ if (data.contactWebsite)
138
+ body.contactWebsite = data.contactWebsite;
139
+ return body;
140
+ }
141
+ /**
142
+ * Convert track release data to GooglePlayReleaseNote
143
+ */
144
+ export function convertToReleaseNote(release, versionCode, trackName) {
145
+ const releaseNotesMap = {};
146
+ if (release.releaseNotes) {
147
+ for (const rn of release.releaseNotes) {
148
+ if (rn.language && rn.text) {
149
+ releaseNotesMap[rn.language] = rn.text;
150
+ }
151
+ }
152
+ }
153
+ if (Object.keys(releaseNotesMap).length === 0) {
154
+ return null;
155
+ }
156
+ const releaseDate = release.releaseDate?.seconds
157
+ ? new Date(Number(release.releaseDate.seconds) * 1000).toISOString()
158
+ : undefined;
159
+ return {
160
+ versionCode: Number(versionCode),
161
+ versionName: versionCode.toString(),
162
+ releaseNotes: releaseNotesMap,
163
+ track: trackName,
164
+ status: release.status || "draft",
165
+ releaseDate,
166
+ };
167
+ }
168
+ /**
169
+ * Convert release notes map to API format
170
+ */
171
+ export function convertReleaseNotesToApiFormat(releaseNotes) {
172
+ return Object.entries(releaseNotes).map(([language, text]) => ({
173
+ language,
174
+ text,
175
+ }));
176
+ }
177
+ /**
178
+ * Extract latest release from track releases
179
+ */
180
+ export function extractLatestRelease(releases) {
181
+ if (releases.length === 0) {
182
+ return null;
183
+ }
184
+ let latestRelease = null;
185
+ let latestVersionCode = 0;
186
+ for (const release of releases) {
187
+ const versionCodes = (release.versionCodes || []).map((code) => Number(code));
188
+ const maxVersionCode = versionCodes.reduce((max, code) => Math.max(max, code), 0);
189
+ if (!latestRelease || maxVersionCode > latestVersionCode) {
190
+ latestRelease = release;
191
+ latestVersionCode = maxVersionCode;
192
+ }
193
+ }
194
+ if (!latestRelease) {
195
+ return null;
196
+ }
197
+ const releaseDate = latestRelease.releaseDate?.seconds
198
+ ? new Date(Number(latestRelease.releaseDate.seconds) * 1000).toISOString()
199
+ : undefined;
200
+ return {
201
+ versionCodes: (latestRelease.versionCodes || []).map((code) => Number(code)),
202
+ status: latestRelease.status
203
+ ? latestRelease.status
204
+ : undefined,
205
+ versionName: latestRelease.name ? String(latestRelease.name) : undefined,
206
+ releaseName: latestRelease.name ? String(latestRelease.name) : undefined,
207
+ releaseDate,
208
+ };
209
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Google Play Console API Endpoints
3
+ *
4
+ * Centralized API endpoint management for androidpublisher v3 API
5
+ */
6
+ import type { androidpublisher_v3 } from "googleapis";
7
+ import type { EditSession, ListingUpdateAttributes, AppDetailsUpdateAttributes, TrackUpdateAttributes, ImageType, AppEdit, AppDetails, Listing, Image, Track, ListingsListResponse, ImagesListResponse, TracksListResponse } from "./types.js";
8
+ export declare class GooglePlayApiEndpoints {
9
+ private androidPublisher;
10
+ constructor(androidPublisher: androidpublisher_v3.Androidpublisher);
11
+ /**
12
+ * Edit Operations
13
+ */
14
+ createEdit(auth: EditSession["auth"], packageName: string): Promise<{
15
+ data: AppEdit;
16
+ }>;
17
+ deleteEdit(session: EditSession): Promise<{
18
+ data: void;
19
+ }>;
20
+ commitEdit(session: EditSession): Promise<{
21
+ data: AppEdit;
22
+ }>;
23
+ /**
24
+ * App Details Operations
25
+ */
26
+ getAppDetails(session: EditSession): Promise<{
27
+ data: AppDetails;
28
+ }>;
29
+ updateAppDetails(session: EditSession, requestBody: AppDetailsUpdateAttributes): Promise<{
30
+ data: AppDetails;
31
+ }>;
32
+ /**
33
+ * Listing Operations
34
+ */
35
+ listListings(session: EditSession): Promise<{
36
+ data: ListingsListResponse;
37
+ }>;
38
+ getListing(session: EditSession, language: string): Promise<{
39
+ data: Listing;
40
+ }>;
41
+ updateListing(session: EditSession, language: string, requestBody: ListingUpdateAttributes): Promise<{
42
+ data: Listing;
43
+ }>;
44
+ /**
45
+ * Image Operations
46
+ */
47
+ listImages(session: EditSession, language: string, imageType: ImageType): Promise<{
48
+ data: ImagesListResponse;
49
+ }>;
50
+ uploadImage(session: EditSession, language: string, imageType: ImageType, media: {
51
+ mimeType: string;
52
+ body: Buffer;
53
+ }): Promise<{
54
+ data: Image;
55
+ }>;
56
+ /**
57
+ * Track Operations
58
+ */
59
+ getTrack(session: EditSession, track: string): Promise<{
60
+ data: Track;
61
+ }>;
62
+ updateTrack(session: EditSession, track: string, requestBody: TrackUpdateAttributes): Promise<{
63
+ data: Track;
64
+ }>;
65
+ listTracks(session: EditSession): Promise<{
66
+ data: TracksListResponse;
67
+ }>;
68
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Google Play Console API Endpoints
3
+ *
4
+ * Centralized API endpoint management for androidpublisher v3 API
5
+ */
6
+ export class GooglePlayApiEndpoints {
7
+ androidPublisher;
8
+ constructor(androidPublisher) {
9
+ this.androidPublisher = androidPublisher;
10
+ }
11
+ /**
12
+ * Edit Operations
13
+ */
14
+ async createEdit(auth, packageName) {
15
+ const response = await this.androidPublisher.edits.insert({
16
+ auth,
17
+ packageName,
18
+ });
19
+ return { data: response.data };
20
+ }
21
+ async deleteEdit(session) {
22
+ await this.androidPublisher.edits.delete({
23
+ auth: session.auth,
24
+ packageName: session.packageName,
25
+ editId: session.editId,
26
+ });
27
+ return { data: undefined };
28
+ }
29
+ async commitEdit(session) {
30
+ const response = await this.androidPublisher.edits.commit({
31
+ auth: session.auth,
32
+ packageName: session.packageName,
33
+ editId: session.editId,
34
+ });
35
+ return { data: response.data };
36
+ }
37
+ /**
38
+ * App Details Operations
39
+ */
40
+ async getAppDetails(session) {
41
+ const response = await this.androidPublisher.edits.details.get({
42
+ auth: session.auth,
43
+ packageName: session.packageName,
44
+ editId: session.editId,
45
+ });
46
+ return { data: response.data };
47
+ }
48
+ async updateAppDetails(session, requestBody) {
49
+ const response = await this.androidPublisher.edits.details.update({
50
+ auth: session.auth,
51
+ packageName: session.packageName,
52
+ editId: session.editId,
53
+ requestBody,
54
+ });
55
+ return { data: response.data };
56
+ }
57
+ /**
58
+ * Listing Operations
59
+ */
60
+ async listListings(session) {
61
+ const response = await this.androidPublisher.edits.listings.list({
62
+ auth: session.auth,
63
+ packageName: session.packageName,
64
+ editId: session.editId,
65
+ });
66
+ return { data: response.data };
67
+ }
68
+ async getListing(session, language) {
69
+ const response = await this.androidPublisher.edits.listings.get({
70
+ auth: session.auth,
71
+ packageName: session.packageName,
72
+ editId: session.editId,
73
+ language,
74
+ });
75
+ return { data: response.data };
76
+ }
77
+ async updateListing(session, language, requestBody) {
78
+ const response = await this.androidPublisher.edits.listings.update({
79
+ auth: session.auth,
80
+ packageName: session.packageName,
81
+ editId: session.editId,
82
+ language,
83
+ requestBody,
84
+ });
85
+ return { data: response.data };
86
+ }
87
+ /**
88
+ * Image Operations
89
+ */
90
+ async listImages(session, language, imageType) {
91
+ const response = await this.androidPublisher.edits.images.list({
92
+ auth: session.auth,
93
+ packageName: session.packageName,
94
+ editId: session.editId,
95
+ language,
96
+ imageType,
97
+ });
98
+ return { data: response.data };
99
+ }
100
+ async uploadImage(session, language, imageType, media) {
101
+ const response = await this.androidPublisher.edits.images.upload({
102
+ auth: session.auth,
103
+ packageName: session.packageName,
104
+ editId: session.editId,
105
+ language,
106
+ imageType,
107
+ media,
108
+ });
109
+ const uploadData = response.data;
110
+ if (!uploadData?.image) {
111
+ throw new Error("Image upload failed: no image data returned");
112
+ }
113
+ return { data: uploadData.image };
114
+ }
115
+ /**
116
+ * Track Operations
117
+ */
118
+ async getTrack(session, track) {
119
+ const response = await this.androidPublisher.edits.tracks.get({
120
+ auth: session.auth,
121
+ packageName: session.packageName,
122
+ editId: session.editId,
123
+ track,
124
+ });
125
+ return { data: response.data };
126
+ }
127
+ async updateTrack(session, track, requestBody) {
128
+ const response = await this.androidPublisher.edits.tracks.update({
129
+ auth: session.auth,
130
+ packageName: session.packageName,
131
+ editId: session.editId,
132
+ track,
133
+ requestBody,
134
+ });
135
+ return { data: response.data };
136
+ }
137
+ async listTracks(session) {
138
+ const response = await this.androidPublisher.edits.tracks.list({
139
+ auth: session.auth,
140
+ packageName: session.packageName,
141
+ editId: session.editId,
142
+ });
143
+ return { data: response.data };
144
+ }
145
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Google Play Console API Client
3
+ *
4
+ * Authentication: Service account JSON key file required
5
+ * API Documentation: https://developers.google.com/android-publisher
6
+ */
7
+ import type { GooglePlayAsoData, GooglePlayMultilingualAsoData, GooglePlayReleaseNote } from "../../../packages/configs/aso-config/types.js";
8
+ import type { GooglePlayClientConfig, AppAccessInfo, LatestReleaseInfo, ReleaseUpdateResult, CreateReleaseOptions, UploadScreenshotOptions, UpdateReleaseNotesOptions, AppDetailsData } from "./types.js";
9
+ export declare class GooglePlayClient {
10
+ private auth;
11
+ private androidPublisher;
12
+ private packageName;
13
+ constructor(config: GooglePlayClientConfig);
14
+ /**
15
+ * Verify app access (returns app information)
16
+ * Google Play API does not support listing apps, so only verifies access by package name
17
+ */
18
+ verifyAppAccess(): Promise<AppAccessInfo>;
19
+ pullAllLanguagesAsoData(): Promise<GooglePlayMultilingualAsoData>;
20
+ pullAsoData(): Promise<GooglePlayAsoData>;
21
+ pushAsoData(data: Partial<GooglePlayAsoData>): Promise<void>;
22
+ /**
23
+ * Push multilingual ASO data in a single edit session
24
+ * This prevents backendError from rapid successive commits
25
+ */
26
+ pushMultilingualAsoData(data: GooglePlayMultilingualAsoData): Promise<void>;
27
+ /**
28
+ * Push app details (contactEmail, contactPhone, contactWebsite) in a separate edit session
29
+ * This must be called separately from pushMultilingualAsoData due to Google Play API limitations
30
+ * NOTE: defaultLanguage is required - it will be fetched from current app details if not provided
31
+ */
32
+ pushAppDetails(details: AppDetailsData): Promise<void>;
33
+ uploadScreenshot(options: UploadScreenshotOptions): Promise<void>;
34
+ getLatestProductionRelease(): Promise<LatestReleaseInfo | null>;
35
+ createProductionRelease(options: CreateReleaseOptions): Promise<void>;
36
+ /**
37
+ * Update release notes for production track
38
+ */
39
+ updateReleaseNotes(options: UpdateReleaseNotesOptions): Promise<ReleaseUpdateResult>;
40
+ pullReleaseNotes(): Promise<GooglePlayReleaseNote[]>;
41
+ pullProductionReleaseNotes(): Promise<GooglePlayReleaseNote[]>;
42
+ private createEdit;
43
+ private deleteEdit;
44
+ private commitEdit;
45
+ private getAppDetails;
46
+ private updateAppDetails;
47
+ private listListings;
48
+ private getListing;
49
+ private updateListing;
50
+ private listImages;
51
+ private uploadImage;
52
+ private getTrack;
53
+ private updateTrack;
54
+ private listTracks;
55
+ }