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,71 @@
1
+ export const ERROR_CODES = {
2
+ // Common
3
+ INTERNAL_ERROR: "INTERNAL_ERROR",
4
+ CLIENT_FACTORY_ERROR: "CLIENT_FACTORY_ERROR",
5
+ // Config/Secrets
6
+ CONFIG_ERROR: "CONFIG_ERROR",
7
+ CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
8
+ CONFIG_AUTH_NOT_FOUND: "CONFIG_AUTH_NOT_FOUND",
9
+ CONFIG_READ_FAILED: "CONFIG_READ_FAILED",
10
+ REGISTERED_APPS_READ_FAILED: "REGISTERED_APPS_READ_FAILED",
11
+ REGISTERED_APPS_WRITE_FAILED: "REGISTERED_APPS_WRITE_FAILED",
12
+ REGISTERED_APP_DUPLICATE: "REGISTERED_APP_DUPLICATE",
13
+ REGISTERED_APP_NOT_FOUND: "REGISTERED_APP_NOT_FOUND",
14
+ REGISTERED_APP_STORE_INFO_MISSING: "REGISTERED_APP_STORE_INFO_MISSING",
15
+ // Service guards
16
+ CONFIG_NOT_FOUND_SKIP: "CONFIG_NOT_FOUND",
17
+ IDENTIFIER_MISSING: "IDENTIFIER_MISSING",
18
+ NO_DATA_FOUND: "NO_DATA_FOUND",
19
+ // App resolution
20
+ APP_IDENTIFIER_MISSING: "APP_IDENTIFIER_MISSING",
21
+ APP_NOT_FOUND: "APP_NOT_FOUND",
22
+ APP_RESOLUTION_FAILED: "APP_RESOLUTION_FAILED",
23
+ // App Store factory
24
+ APP_STORE_CLIENT_CONFIG_MISSING: "APP_STORE_CLIENT_CONFIG_MISSING",
25
+ APP_STORE_BUNDLE_ID_INVALID: "APP_STORE_BUNDLE_ID_INVALID",
26
+ APP_STORE_CONFIG_LOAD_FAILED: "APP_STORE_CONFIG_LOAD_FAILED",
27
+ APP_STORE_CONFIG_MISSING: "APP_STORE_CONFIG_MISSING",
28
+ APP_STORE_ISSUER_ID_INVALID: "APP_STORE_ISSUER_ID_INVALID",
29
+ APP_STORE_KEY_ID_INVALID: "APP_STORE_KEY_ID_INVALID",
30
+ APP_STORE_PRIVATE_KEY_INVALID: "APP_STORE_PRIVATE_KEY_INVALID",
31
+ APP_STORE_PRIVATE_KEY_FORMAT_INVALID: "APP_STORE_PRIVATE_KEY_FORMAT_INVALID",
32
+ APP_STORE_CLIENT_CREATE_FAILED: "APP_STORE_CLIENT_CREATE_FAILED",
33
+ // Google Play factory
34
+ GOOGLE_PLAY_CLIENT_CONFIG_MISSING: "GOOGLE_PLAY_CLIENT_CONFIG_MISSING",
35
+ GOOGLE_PLAY_PACKAGE_NAME_INVALID: "GOOGLE_PLAY_PACKAGE_NAME_INVALID",
36
+ GOOGLE_PLAY_CONFIG_LOAD_FAILED: "GOOGLE_PLAY_CONFIG_LOAD_FAILED",
37
+ GOOGLE_PLAY_CONFIG_MISSING: "GOOGLE_PLAY_CONFIG_MISSING",
38
+ GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_INVALID: "GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_INVALID",
39
+ GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_FORMAT_INVALID: "GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_FORMAT_INVALID",
40
+ GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_PARSE_FAILED: "GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_PARSE_FAILED",
41
+ GOOGLE_PLAY_CLIENT_CREATE_FAILED: "GOOGLE_PLAY_CLIENT_CREATE_FAILED",
42
+ // App Store service
43
+ APP_STORE_LIST_APPS_FAILED: "APP_STORE_LIST_APPS_FAILED",
44
+ APP_STORE_FETCH_APP_INFO_FAILED: "APP_STORE_FETCH_APP_INFO_FAILED",
45
+ APP_STORE_GET_LATEST_VERSION_FAILED: "APP_STORE_GET_LATEST_VERSION_FAILED",
46
+ APP_STORE_VERSION_NOT_EDITABLE: "APP_STORE_VERSION_NOT_EDITABLE",
47
+ APP_STORE_UPDATE_RELEASE_NOTES_PARTIAL: "APP_STORE_UPDATE_RELEASE_NOTES_PARTIAL",
48
+ APP_STORE_UPDATE_RELEASE_NOTES_FAILED: "APP_STORE_UPDATE_RELEASE_NOTES_FAILED",
49
+ APP_STORE_PULL_RELEASE_NOTES_FAILED: "APP_STORE_PULL_RELEASE_NOTES_FAILED",
50
+ APP_STORE_CREATE_VERSION_FAILED: "APP_STORE_CREATE_VERSION_FAILED",
51
+ APP_STORE_PUSH_FAILED: "APP_STORE_PUSH_FAILED",
52
+ APP_STORE_STATE_ERROR: "APP_STORE_STATE_ERROR",
53
+ APP_STORE_CREATE_VERSION_FOR_STATE_ERROR_FAILED: "APP_STORE_CREATE_VERSION_FOR_STATE_ERROR_FAILED",
54
+ APP_STORE_VERIFY_AUTH_FAILED: "APP_STORE_VERIFY_AUTH_FAILED",
55
+ // Google Play service
56
+ GOOGLE_PLAY_FETCH_APP_INFO_FAILED: "GOOGLE_PLAY_FETCH_APP_INFO_FAILED",
57
+ GOOGLE_PLAY_GET_LATEST_RELEASE_FAILED: "GOOGLE_PLAY_GET_LATEST_RELEASE_FAILED",
58
+ GOOGLE_PLAY_RELEASE_NOTES_EMPTY: "GOOGLE_PLAY_RELEASE_NOTES_EMPTY",
59
+ GOOGLE_PLAY_UPDATE_RELEASE_NOTES_PARTIAL: "GOOGLE_PLAY_UPDATE_RELEASE_NOTES_PARTIAL",
60
+ GOOGLE_PLAY_UPDATE_RELEASE_NOTES_FAILED: "GOOGLE_PLAY_UPDATE_RELEASE_NOTES_FAILED",
61
+ GOOGLE_PLAY_PULL_RELEASE_NOTES_FAILED: "GOOGLE_PLAY_PULL_RELEASE_NOTES_FAILED",
62
+ GOOGLE_PLAY_CREATE_VERSION_FAILED: "GOOGLE_PLAY_CREATE_VERSION_FAILED",
63
+ GOOGLE_PLAY_PUSH_FAILED: "GOOGLE_PLAY_PUSH_FAILED",
64
+ GOOGLE_PLAY_VERIFY_AUTH_FAILED: "GOOGLE_PLAY_VERIFY_AUTH_FAILED",
65
+ // ASO data/files
66
+ ASO_GOOGLE_PLAY_DATA_PARSE_FAILED: "ASO_GOOGLE_PLAY_DATA_PARSE_FAILED",
67
+ ASO_APP_STORE_DATA_PARSE_FAILED: "ASO_APP_STORE_DATA_PARSE_FAILED",
68
+ ASO_DATA_SAVE_FAILED: "ASO_DATA_SAVE_FAILED",
69
+ ASO_IMAGE_DOWNLOAD_FAILED: "ASO_IMAGE_DOWNLOAD_FAILED",
70
+ ASO_LOCAL_ASSET_NOT_FOUND: "ASO_LOCAL_ASSET_NOT_FOUND",
71
+ };
@@ -0,0 +1,10 @@
1
+ export declare const HTTP_STATUS: {
2
+ readonly BAD_REQUEST: 400;
3
+ readonly UNAUTHORIZED: 401;
4
+ readonly FORBIDDEN: 403;
5
+ readonly NOT_FOUND: 404;
6
+ readonly CONFLICT: 409;
7
+ readonly UNPROCESSABLE_ENTITY: 422;
8
+ readonly INTERNAL_SERVER_ERROR: 500;
9
+ };
10
+ export type HttpStatusCode = (typeof HTTP_STATUS)[keyof typeof HTTP_STATUS];
@@ -0,0 +1,9 @@
1
+ export const HTTP_STATUS = {
2
+ BAD_REQUEST: 400,
3
+ UNAUTHORIZED: 401,
4
+ FORBIDDEN: 403,
5
+ NOT_FOUND: 404,
6
+ CONFLICT: 409,
7
+ UNPROCESSABLE_ENTITY: 422,
8
+ INTERNAL_SERVER_ERROR: 500,
9
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * ASO (App Store Optimization) constants
3
+ */
4
+ /**
5
+ * App Store Connect supported locale list
6
+ * Reference: https://developer.apple.com/documentation/appstoreconnectapi
7
+ */
8
+ export declare const APP_STORE_SUPPORTED_LOCALES: readonly ["en-US", "en-AU", "en-CA", "en-GB", "ko-KR", "ja-JP", "zh-Hans", "zh-Hant", "zh-HK", "fr-FR", "fr-CA", "de-DE", "it-IT", "es-ES", "es-MX", "pt-BR", "pt-PT", "ru-RU", "ar-SA", "nl-NL", "sv-SE", "da-DK", "no-NO", "fi-FI", "pl-PL", "tr-TR", "vi-VN", "th-TH", "id-ID", "ms-MY", "hi-IN", "cs-CZ", "sk-SK", "hu-HU", "ro-RO", "uk-UA", "he-IL", "el-GR"];
9
+ /**
10
+ * Google Play Console supported language list
11
+ * Reference: https://support.google.com/googleplay/android-developer/answer/9844778
12
+ */
13
+ export declare const GOOGLE_PLAY_SUPPORTED_LANGUAGES: readonly ["en-US", "en-AU", "en-CA", "en-GB", "en-IN", "en-SG", "ko-KR", "ja-JP", "zh-CN", "zh-TW", "zh-HK", "fr-FR", "fr-CA", "de-DE", "it-IT", "es-ES", "es-419", "es-US", "pt-BR", "pt-PT", "ru-RU", "ar-SA", "nl-NL", "sv-SE", "da-DK", "no-NO", "fi-FI", "pl-PL", "tr-TR", "vi-VN", "th-TH", "id-ID", "ms-MY", "hi-IN", "cs-CZ", "sk-SK", "hu-HU", "ro-RO", "uk-UA", "he-IL", "el-GR", "bg-BG", "hr-HR", "sr-RS", "sl-SI", "et-EE", "lv-LV", "lt-LT"];
14
+ export declare const DEFAULT_LOCALE: "en-US";
@@ -0,0 +1,102 @@
1
+ /**
2
+ * ASO (App Store Optimization) constants
3
+ */
4
+ /**
5
+ * App Store Connect supported locale list
6
+ * Reference: https://developer.apple.com/documentation/appstoreconnectapi
7
+ */
8
+ export const APP_STORE_SUPPORTED_LOCALES = [
9
+ "en-US",
10
+ "en-AU",
11
+ "en-CA",
12
+ "en-GB",
13
+ "ko-KR",
14
+ "ja-JP",
15
+ "zh-Hans",
16
+ "zh-Hant",
17
+ "zh-HK",
18
+ "fr-FR",
19
+ "fr-CA",
20
+ "de-DE",
21
+ "it-IT",
22
+ "es-ES",
23
+ "es-MX",
24
+ "pt-BR",
25
+ "pt-PT",
26
+ "ru-RU",
27
+ "ar-SA",
28
+ "nl-NL",
29
+ "sv-SE",
30
+ "da-DK",
31
+ "no-NO",
32
+ "fi-FI",
33
+ "pl-PL",
34
+ "tr-TR",
35
+ "vi-VN",
36
+ "th-TH",
37
+ "id-ID",
38
+ "ms-MY",
39
+ "hi-IN",
40
+ "cs-CZ",
41
+ "sk-SK",
42
+ "hu-HU",
43
+ "ro-RO",
44
+ "uk-UA",
45
+ "he-IL",
46
+ "el-GR",
47
+ ];
48
+ /**
49
+ * Google Play Console supported language list
50
+ * Reference: https://support.google.com/googleplay/android-developer/answer/9844778
51
+ */
52
+ export const GOOGLE_PLAY_SUPPORTED_LANGUAGES = [
53
+ "en-US",
54
+ "en-AU",
55
+ "en-CA",
56
+ "en-GB",
57
+ "en-IN",
58
+ "en-SG",
59
+ "ko-KR",
60
+ "ja-JP",
61
+ "zh-CN",
62
+ "zh-TW",
63
+ "zh-HK",
64
+ "fr-FR",
65
+ "fr-CA",
66
+ "de-DE",
67
+ "it-IT",
68
+ "es-ES",
69
+ "es-419",
70
+ "es-US",
71
+ "pt-BR",
72
+ "pt-PT",
73
+ "ru-RU",
74
+ "ar-SA",
75
+ "nl-NL",
76
+ "sv-SE",
77
+ "da-DK",
78
+ "no-NO",
79
+ "fi-FI",
80
+ "pl-PL",
81
+ "tr-TR",
82
+ "vi-VN",
83
+ "th-TH",
84
+ "id-ID",
85
+ "ms-MY",
86
+ "hi-IN",
87
+ "cs-CZ",
88
+ "sk-SK",
89
+ "hu-HU",
90
+ "ro-RO",
91
+ "uk-UA",
92
+ "he-IL",
93
+ "el-GR",
94
+ "bg-BG",
95
+ "hr-HR",
96
+ "sr-RS",
97
+ "sl-SI",
98
+ "et-EE",
99
+ "lv-LV",
100
+ "lt-LT",
101
+ ];
102
+ export const DEFAULT_LOCALE = "en-US";
@@ -0,0 +1,3 @@
1
+ import type { AppStoreLocale, GooglePlayLanguage } from "./types.js";
2
+ export declare function isAppStoreLocale(locale: string): locale is AppStoreLocale;
3
+ export declare function isGooglePlayLanguage(language: string): language is GooglePlayLanguage;
@@ -0,0 +1,7 @@
1
+ import { APP_STORE_SUPPORTED_LOCALES, GOOGLE_PLAY_SUPPORTED_LANGUAGES, } from "./constants.js";
2
+ export function isAppStoreLocale(locale) {
3
+ return APP_STORE_SUPPORTED_LOCALES.includes(locale);
4
+ }
5
+ export function isGooglePlayLanguage(language) {
6
+ return GOOGLE_PLAY_SUPPORTED_LANGUAGES.includes(language);
7
+ }
@@ -0,0 +1,11 @@
1
+ import type { StoreType } from "./types.js";
2
+ export type StoreTargets = {
3
+ /** Normalized store value (defaults to "both") */
4
+ store: StoreType;
5
+ includeAppStore: boolean;
6
+ includeGooglePlay: boolean;
7
+ };
8
+ /**
9
+ * Normalize store selection and expose booleans for per-store handling.
10
+ */
11
+ export declare function getStoreTargets(store?: StoreType): StoreTargets;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Normalize store selection and expose booleans for per-store handling.
3
+ */
4
+ export function getStoreTargets(store) {
5
+ const normalizedStore = store ?? "both";
6
+ return {
7
+ store: normalizedStore,
8
+ includeAppStore: normalizedStore === "appStore" || normalizedStore === "both",
9
+ includeGooglePlay: normalizedStore === "googlePlay" || normalizedStore === "both",
10
+ };
11
+ }
@@ -0,0 +1,98 @@
1
+ import { APP_STORE_SUPPORTED_LOCALES, GOOGLE_PLAY_SUPPORTED_LANGUAGES } from "./constants.js";
2
+ export type AppStoreLocale = (typeof APP_STORE_SUPPORTED_LOCALES)[number];
3
+ export type GooglePlayLanguage = (typeof GOOGLE_PLAY_SUPPORTED_LANGUAGES)[number];
4
+ export type SupportedLocale = AppStoreLocale | GooglePlayLanguage;
5
+ export interface GooglePlayScreenshots {
6
+ phone: string[];
7
+ tablet?: string[];
8
+ tablet7?: string[];
9
+ tablet10?: string[];
10
+ tv?: string[];
11
+ wear?: string[];
12
+ }
13
+ export interface GooglePlayAsoData {
14
+ title: string;
15
+ shortDescription: string;
16
+ fullDescription: string;
17
+ screenshots: GooglePlayScreenshots;
18
+ featureGraphic?: string;
19
+ promoGraphic?: string;
20
+ category?: string;
21
+ contentRating?: string;
22
+ keywords?: string[];
23
+ contactEmail?: string;
24
+ contactPhone?: string;
25
+ contactWebsite?: string;
26
+ packageName: string;
27
+ defaultLanguage: string;
28
+ }
29
+ export interface GooglePlayMultilingualAsoData {
30
+ locales: Record<string, GooglePlayAsoData>;
31
+ defaultLocale?: string;
32
+ }
33
+ export interface GooglePlayReleaseNote {
34
+ versionCode: number;
35
+ versionName: string;
36
+ releaseNotes: Record<string, string>;
37
+ track: string;
38
+ status: string;
39
+ releaseDate?: string;
40
+ }
41
+ export interface AppStoreScreenshots {
42
+ iphone65?: string[];
43
+ iphone61?: string[];
44
+ iphone58?: string[];
45
+ iphone55?: string[];
46
+ iphone47?: string[];
47
+ iphone40?: string[];
48
+ ipadPro129?: string[];
49
+ ipadPro11?: string[];
50
+ ipad105?: string[];
51
+ ipad97?: string[];
52
+ appleWatch?: string[];
53
+ }
54
+ export interface AppStoreAsoData {
55
+ name: string;
56
+ subtitle?: string;
57
+ description: string;
58
+ keywords?: string;
59
+ promotionalText?: string;
60
+ screenshots: AppStoreScreenshots;
61
+ appPreview?: string[];
62
+ primaryCategory?: string;
63
+ secondaryCategory?: string;
64
+ contentRightId?: string;
65
+ supportUrl?: string;
66
+ marketingUrl?: string;
67
+ privacyPolicyUrl?: string;
68
+ bundleId: string;
69
+ locale: string;
70
+ whatsNew?: string;
71
+ }
72
+ export interface AppStoreMultilingualAsoData {
73
+ locales: Record<string, AppStoreAsoData>;
74
+ defaultLocale?: string;
75
+ }
76
+ export interface AppStoreReleaseNote {
77
+ versionString: string;
78
+ releaseNotes: Record<string, string>;
79
+ platform: string;
80
+ releaseDate?: string;
81
+ }
82
+ export interface AsoData {
83
+ googlePlay?: GooglePlayAsoData | GooglePlayMultilingualAsoData;
84
+ appStore?: AppStoreAsoData | AppStoreMultilingualAsoData;
85
+ lastSynced?: {
86
+ googlePlay?: string;
87
+ appStore?: string;
88
+ };
89
+ }
90
+ export type StoreType = "googlePlay" | "appStore" | "both";
91
+ export type SyncDirection = "pull" | "push" | "sync";
92
+ export interface SyncOptions {
93
+ direction: SyncDirection;
94
+ productSlug: string;
95
+ store?: StoreType;
96
+ dryRun?: boolean;
97
+ uploadImages?: boolean;
98
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ // Re-export StoreType for backward compatibility
@@ -0,0 +1,43 @@
1
+ import { type AsoData, type GooglePlayAsoData, type GooglePlayMultilingualAsoData, type AppStoreAsoData, type AppStoreMultilingualAsoData } from "./types.js";
2
+ export declare function getAsoDir(): string;
3
+ export declare function getAsoPullDir(): string;
4
+ export declare function getAsoPushDir(): string;
5
+ export declare function getProductAsoDir(slug: string): string;
6
+ export declare function getPullProductAsoDir(slug: string, baseDir?: string): string;
7
+ export declare function getScreenshotDir(productStoreRoot: string, store: "google-play" | "app-store", locale: string): string;
8
+ export declare function getScreenshotFilePath(screenshotDir: string, filename: string): string;
9
+ export declare function getStoreDir(productStoreRoot: string, store: "google-play" | "app-store"): string;
10
+ export declare function getReleaseNotesPath(storeDir: string): string;
11
+ export declare function getAsoDataPaths(slug: string, asoDir?: string): {
12
+ googlePlay: string;
13
+ appStore: string;
14
+ };
15
+ export declare function ensureDir(dirPath: string): void;
16
+ export interface PreparedAsoData {
17
+ googlePlay?: GooglePlayMultilingualAsoData;
18
+ appStore?: AppStoreMultilingualAsoData;
19
+ }
20
+ export declare function convertToMultilingual<T extends {
21
+ locale?: string;
22
+ defaultLanguage?: string;
23
+ }>(data: T, locale?: string): {
24
+ locales: Record<string, T>;
25
+ defaultLocale: string;
26
+ };
27
+ export declare function isGooglePlayMultilingual(data: GooglePlayAsoData | GooglePlayMultilingualAsoData | undefined): data is GooglePlayMultilingualAsoData;
28
+ export declare function isAppStoreMultilingual(data: AppStoreAsoData | AppStoreMultilingualAsoData | undefined): data is AppStoreMultilingualAsoData;
29
+ export declare function prepareAsoDataForPush(slug: string, configData: AsoData, options?: {
30
+ baseUrl?: string;
31
+ }): PreparedAsoData;
32
+ export declare function saveAsoData(slug: string, asoData: Partial<AsoData>, options?: {
33
+ asoDir?: string;
34
+ }): void;
35
+ export declare function loadAsoData(slug: string, options?: {
36
+ asoDir?: string;
37
+ }): AsoData;
38
+ export declare function isLocalAssetPath(assetPath: string): boolean;
39
+ export declare function resolveAppStoreImageUrl(templateUrl: string): string;
40
+ export declare function downloadImage(url: string, outputPath: string): Promise<void>;
41
+ export declare function copyLocalAssetToAso(assetPath: string, outputPath: string, options?: {
42
+ publicDir?: string;
43
+ }): void;
@@ -0,0 +1,223 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { AppError } from "../../../packages/common/errors/app-error.js";
4
+ import { ERROR_CODES } from "../../../packages/common/errors/error-codes.js";
5
+ import { HTTP_STATUS } from "../../../packages/common/errors/status-codes.js";
6
+ import { getDataDir } from "../../../packages/configs/secrets-config/config.js";
7
+ import { DEFAULT_LOCALE } from "./constants.js";
8
+ // ============================================================================
9
+ // ASO Directory Path Utilities
10
+ // ============================================================================
11
+ export function getAsoDir() {
12
+ return join(getDataDir(), ".aso");
13
+ }
14
+ export function getAsoPullDir() {
15
+ return join(getAsoDir(), "pullData");
16
+ }
17
+ export function getAsoPushDir() {
18
+ return join(getAsoDir(), "pushData");
19
+ }
20
+ export function getProductAsoDir(slug) {
21
+ return join(getAsoDir(), "products", slug, "store");
22
+ }
23
+ export function getPullProductAsoDir(slug, baseDir) {
24
+ return join(baseDir ?? getAsoPullDir(), "products", slug, "store");
25
+ }
26
+ export function getScreenshotDir(productStoreRoot, store, locale) {
27
+ return join(productStoreRoot, store, "screenshots", locale);
28
+ }
29
+ export function getScreenshotFilePath(screenshotDir, filename) {
30
+ return join(screenshotDir, filename);
31
+ }
32
+ export function getStoreDir(productStoreRoot, store) {
33
+ return join(productStoreRoot, store);
34
+ }
35
+ export function getReleaseNotesPath(storeDir) {
36
+ return join(storeDir, "release-notes.json");
37
+ }
38
+ export function getAsoDataPaths(slug, asoDir) {
39
+ const baseDir = asoDir ?? getAsoDir();
40
+ const productStoreDir = join(baseDir, "products", slug, "store");
41
+ return {
42
+ googlePlay: join(productStoreDir, "google-play", "aso-data.json"),
43
+ appStore: join(productStoreDir, "app-store", "aso-data.json"),
44
+ };
45
+ }
46
+ export function ensureDir(dirPath) {
47
+ if (!existsSync(dirPath)) {
48
+ mkdirSync(dirPath, { recursive: true });
49
+ }
50
+ }
51
+ export function convertToMultilingual(data, locale) {
52
+ const detectedLocale = locale || data.locale || data.defaultLanguage || DEFAULT_LOCALE;
53
+ return {
54
+ locales: { [detectedLocale]: data },
55
+ defaultLocale: detectedLocale,
56
+ };
57
+ }
58
+ export function isGooglePlayMultilingual(data) {
59
+ return data !== undefined && "locales" in data;
60
+ }
61
+ export function isAppStoreMultilingual(data) {
62
+ return data !== undefined && "locales" in data;
63
+ }
64
+ export function prepareAsoDataForPush(slug, configData, options) {
65
+ const storeData = {};
66
+ const baseUrl = options?.baseUrl ??
67
+ process.env.NEXT_PUBLIC_SITE_URL ??
68
+ "https://labs.quartz.best";
69
+ const detailPageUrl = `${baseUrl}/${slug}`;
70
+ if (configData.googlePlay) {
71
+ const googlePlayData = configData.googlePlay;
72
+ const locales = isGooglePlayMultilingual(googlePlayData)
73
+ ? googlePlayData.locales
74
+ : { [googlePlayData.defaultLanguage || DEFAULT_LOCALE]: googlePlayData };
75
+ const cleanedLocales = {};
76
+ for (const [locale, localeData] of Object.entries(locales)) {
77
+ const { screenshots, featureGraphic, ...rest } = localeData;
78
+ cleanedLocales[locale] = {
79
+ ...rest,
80
+ contactWebsite: detailPageUrl,
81
+ };
82
+ }
83
+ const gpDefaultLocale = isGooglePlayMultilingual(googlePlayData)
84
+ ? googlePlayData.defaultLocale
85
+ : googlePlayData.defaultLanguage;
86
+ storeData.googlePlay = {
87
+ locales: cleanedLocales,
88
+ defaultLocale: gpDefaultLocale || DEFAULT_LOCALE,
89
+ };
90
+ }
91
+ if (configData.appStore) {
92
+ const appStoreData = configData.appStore;
93
+ const locales = isAppStoreMultilingual(appStoreData)
94
+ ? appStoreData.locales
95
+ : { [appStoreData.locale || DEFAULT_LOCALE]: appStoreData };
96
+ const cleanedLocales = {};
97
+ for (const [locale, localeData] of Object.entries(locales)) {
98
+ const { screenshots, ...rest } = localeData;
99
+ cleanedLocales[locale] = {
100
+ ...rest,
101
+ marketingUrl: detailPageUrl,
102
+ };
103
+ }
104
+ const asDefaultLocale = isAppStoreMultilingual(appStoreData)
105
+ ? appStoreData.defaultLocale
106
+ : appStoreData.locale;
107
+ storeData.appStore = {
108
+ locales: cleanedLocales,
109
+ defaultLocale: asDefaultLocale || DEFAULT_LOCALE,
110
+ };
111
+ }
112
+ return storeData;
113
+ }
114
+ // ============================================================================
115
+ // ASO Data Save/Load
116
+ // ============================================================================
117
+ export function saveAsoData(slug, asoData, options) {
118
+ const baseDir = options?.asoDir ?? getAsoDir();
119
+ const productStoreDir = join(baseDir, "products", slug, "store");
120
+ try {
121
+ if (asoData.googlePlay) {
122
+ const googlePlayDir = join(productStoreDir, "google-play");
123
+ ensureDir(googlePlayDir);
124
+ const filePath = join(googlePlayDir, "aso-data.json");
125
+ writeFileSync(filePath, JSON.stringify({ googlePlay: asoData.googlePlay }, null, 2));
126
+ console.log(`💾 Google Play data saved to ${filePath}`);
127
+ }
128
+ if (asoData.appStore) {
129
+ const appStoreDir = join(productStoreDir, "app-store");
130
+ ensureDir(appStoreDir);
131
+ const filePath = join(appStoreDir, "aso-data.json");
132
+ writeFileSync(filePath, JSON.stringify({ appStore: asoData.appStore }, null, 2));
133
+ console.log(`💾 App Store data saved to ${filePath}`);
134
+ }
135
+ }
136
+ catch (error) {
137
+ throw AppError.io(ERROR_CODES.ASO_DATA_SAVE_FAILED, `Failed to save ASO data for ${slug}`, { slug, baseDir, cause: error });
138
+ }
139
+ }
140
+ export function loadAsoData(slug, options) {
141
+ const baseDir = options?.asoDir ?? getAsoDir();
142
+ const asoData = {};
143
+ const googlePlayPath = join(baseDir, "products", slug, "store", "google-play", "aso-data.json");
144
+ if (existsSync(googlePlayPath)) {
145
+ try {
146
+ const content = readFileSync(googlePlayPath, "utf-8");
147
+ const data = JSON.parse(content);
148
+ if (data.googlePlay) {
149
+ asoData.googlePlay = isGooglePlayMultilingual(data.googlePlay)
150
+ ? data.googlePlay
151
+ : convertToMultilingual(data.googlePlay, data.googlePlay.defaultLanguage);
152
+ }
153
+ }
154
+ catch (error) {
155
+ throw AppError.validation(ERROR_CODES.ASO_GOOGLE_PLAY_DATA_PARSE_FAILED, `Failed to read Google Play ASO data for ${slug}`, { path: googlePlayPath, error });
156
+ }
157
+ }
158
+ const appStorePath = join(baseDir, "products", slug, "store", "app-store", "aso-data.json");
159
+ if (existsSync(appStorePath)) {
160
+ try {
161
+ const content = readFileSync(appStorePath, "utf-8");
162
+ const data = JSON.parse(content);
163
+ if (data.appStore) {
164
+ asoData.appStore = isAppStoreMultilingual(data.appStore)
165
+ ? data.appStore
166
+ : convertToMultilingual(data.appStore, data.appStore.locale);
167
+ }
168
+ }
169
+ catch (error) {
170
+ throw AppError.validation(ERROR_CODES.ASO_APP_STORE_DATA_PARSE_FAILED, `Failed to read App Store ASO data for ${slug}`, { path: appStorePath, error });
171
+ }
172
+ }
173
+ return asoData;
174
+ }
175
+ // ============================================================================
176
+ // Image Utilities
177
+ // ============================================================================
178
+ export function isLocalAssetPath(assetPath) {
179
+ if (!assetPath)
180
+ return false;
181
+ const trimmed = assetPath.trim();
182
+ return !/^([a-z]+:)?\/\//i.test(trimmed);
183
+ }
184
+ export function resolveAppStoreImageUrl(templateUrl) {
185
+ if (!templateUrl.includes("{w}") && !templateUrl.includes("{h}")) {
186
+ return templateUrl;
187
+ }
188
+ const width = 2048;
189
+ const height = 2732;
190
+ const format = "png";
191
+ return templateUrl
192
+ .replace("{w}", width.toString())
193
+ .replace("{h}", height.toString())
194
+ .replace("{f}", format);
195
+ }
196
+ export async function downloadImage(url, outputPath) {
197
+ try {
198
+ const response = await fetch(url);
199
+ if (!response.ok) {
200
+ throw AppError.io(ERROR_CODES.ASO_IMAGE_DOWNLOAD_FAILED, `Image download failed: ${response.status} ${response.statusText}`, { url, status: response.status, statusText: response.statusText });
201
+ }
202
+ const arrayBuffer = await response.arrayBuffer();
203
+ const buffer = Buffer.from(arrayBuffer);
204
+ ensureDir(dirname(outputPath));
205
+ writeFileSync(outputPath, buffer);
206
+ }
207
+ catch (error) {
208
+ throw AppError.wrap(error, HTTP_STATUS.INTERNAL_SERVER_ERROR, ERROR_CODES.ASO_IMAGE_DOWNLOAD_FAILED, `Image download failed (${url})`);
209
+ }
210
+ }
211
+ export function copyLocalAssetToAso(assetPath, outputPath, options) {
212
+ const publicDir = options?.publicDir ?? join(getDataDir(), "public");
213
+ const trimmedPath = assetPath
214
+ .replace(/^\.\//, "")
215
+ .replace(/^public\//, "")
216
+ .replace(/^\/+/, "");
217
+ const sourcePath = join(publicDir, trimmedPath);
218
+ if (!existsSync(sourcePath)) {
219
+ throw AppError.fileNotFound(ERROR_CODES.ASO_LOCAL_ASSET_NOT_FOUND, `Local image not found: ${sourcePath}`, { sourcePath });
220
+ }
221
+ ensureDir(dirname(outputPath));
222
+ copyFileSync(sourcePath, outputPath);
223
+ }
@@ -0,0 +1,12 @@
1
+ import type { EnvConfig } from "./types.js";
2
+ /**
3
+ * Get config directory path: ~/.config/pabal-mcp/
4
+ */
5
+ export declare function getConfigDir(): string;
6
+ /**
7
+ * Get config file path: ~/.config/pabal-mcp/config.json
8
+ */
9
+ export declare function getConfigPath(): string;
10
+ export declare function readConfigFile(): any;
11
+ export declare function getDataDir(): string;
12
+ export declare function loadConfig(): EnvConfig;