native-update 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 (184) hide show
  1. package/CapacitorNativeUpdate.podspec +18 -0
  2. package/LICENSE +21 -0
  3. package/Readme.md +451 -0
  4. package/android/build.gradle +92 -0
  5. package/android/gradle/wrapper/gradle-wrapper.properties +8 -0
  6. package/android/gradle.properties +17 -0
  7. package/android/proguard-rules.pro +29 -0
  8. package/android/settings.gradle +2 -0
  9. package/android/src/main/AndroidManifest.xml +34 -0
  10. package/android/src/main/java/com/aoneahsan/nativeupdate/AppReviewPlugin.kt +153 -0
  11. package/android/src/main/java/com/aoneahsan/nativeupdate/AppUpdatePlugin.kt +275 -0
  12. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +390 -0
  13. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateManager.kt +46 -0
  14. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +333 -0
  15. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +251 -0
  16. package/android/src/main/java/com/aoneahsan/nativeupdate/CapacitorNativeUpdatePlugin.kt +265 -0
  17. package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +526 -0
  18. package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +99 -0
  19. package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +249 -0
  20. package/dist/esm/__tests__/bundle-manager.test.d.ts +1 -0
  21. package/dist/esm/__tests__/bundle-manager.test.js +123 -0
  22. package/dist/esm/__tests__/bundle-manager.test.js.map +1 -0
  23. package/dist/esm/__tests__/config.test.d.ts +1 -0
  24. package/dist/esm/__tests__/config.test.js +69 -0
  25. package/dist/esm/__tests__/config.test.js.map +1 -0
  26. package/dist/esm/__tests__/integration.test.d.ts +1 -0
  27. package/dist/esm/__tests__/integration.test.js +78 -0
  28. package/dist/esm/__tests__/integration.test.js.map +1 -0
  29. package/dist/esm/__tests__/security.test.d.ts +1 -0
  30. package/dist/esm/__tests__/security.test.js +54 -0
  31. package/dist/esm/__tests__/security.test.js.map +1 -0
  32. package/dist/esm/__tests__/version-manager.test.d.ts +1 -0
  33. package/dist/esm/__tests__/version-manager.test.js +45 -0
  34. package/dist/esm/__tests__/version-manager.test.js.map +1 -0
  35. package/dist/esm/app-review/app-review-manager.d.ts +24 -0
  36. package/dist/esm/app-review/app-review-manager.js +195 -0
  37. package/dist/esm/app-review/app-review-manager.js.map +1 -0
  38. package/dist/esm/app-review/index.d.ts +5 -0
  39. package/dist/esm/app-review/index.js +6 -0
  40. package/dist/esm/app-review/index.js.map +1 -0
  41. package/dist/esm/app-review/platform-review-handler.d.ts +20 -0
  42. package/dist/esm/app-review/platform-review-handler.js +138 -0
  43. package/dist/esm/app-review/platform-review-handler.js.map +1 -0
  44. package/dist/esm/app-review/review-conditions-checker.d.ts +22 -0
  45. package/dist/esm/app-review/review-conditions-checker.js +155 -0
  46. package/dist/esm/app-review/review-conditions-checker.js.map +1 -0
  47. package/dist/esm/app-review/review-rate-limiter.d.ts +23 -0
  48. package/dist/esm/app-review/review-rate-limiter.js +164 -0
  49. package/dist/esm/app-review/review-rate-limiter.js.map +1 -0
  50. package/dist/esm/app-review/types.d.ts +41 -0
  51. package/dist/esm/app-review/types.js +2 -0
  52. package/dist/esm/app-review/types.js.map +1 -0
  53. package/dist/esm/app-update/app-update-checker.d.ts +13 -0
  54. package/dist/esm/app-update/app-update-checker.js +104 -0
  55. package/dist/esm/app-update/app-update-checker.js.map +1 -0
  56. package/dist/esm/app-update/app-update-installer.d.ts +19 -0
  57. package/dist/esm/app-update/app-update-installer.js +123 -0
  58. package/dist/esm/app-update/app-update-installer.js.map +1 -0
  59. package/dist/esm/app-update/app-update-manager.d.ts +28 -0
  60. package/dist/esm/app-update/app-update-manager.js +199 -0
  61. package/dist/esm/app-update/app-update-manager.js.map +1 -0
  62. package/dist/esm/app-update/app-update-notifier.d.ts +14 -0
  63. package/dist/esm/app-update/app-update-notifier.js +100 -0
  64. package/dist/esm/app-update/app-update-notifier.js.map +1 -0
  65. package/dist/esm/app-update/index.d.ts +6 -0
  66. package/dist/esm/app-update/index.js +7 -0
  67. package/dist/esm/app-update/index.js.map +1 -0
  68. package/dist/esm/app-update/platform-app-update.d.ts +19 -0
  69. package/dist/esm/app-update/platform-app-update.js +129 -0
  70. package/dist/esm/app-update/platform-app-update.js.map +1 -0
  71. package/dist/esm/app-update/types.d.ts +58 -0
  72. package/dist/esm/app-update/types.js +12 -0
  73. package/dist/esm/app-update/types.js.map +1 -0
  74. package/dist/esm/background-update/background-scheduler.d.ts +17 -0
  75. package/dist/esm/background-update/background-scheduler.js +195 -0
  76. package/dist/esm/background-update/background-scheduler.js.map +1 -0
  77. package/dist/esm/background-update/index.d.ts +3 -0
  78. package/dist/esm/background-update/index.js +3 -0
  79. package/dist/esm/background-update/index.js.map +1 -0
  80. package/dist/esm/background-update/notification-manager.d.ts +29 -0
  81. package/dist/esm/background-update/notification-manager.js +89 -0
  82. package/dist/esm/background-update/notification-manager.js.map +1 -0
  83. package/dist/esm/core/analytics.d.ts +70 -0
  84. package/dist/esm/core/analytics.js +137 -0
  85. package/dist/esm/core/analytics.js.map +1 -0
  86. package/dist/esm/core/cache-manager.d.ts +72 -0
  87. package/dist/esm/core/cache-manager.js +275 -0
  88. package/dist/esm/core/cache-manager.js.map +1 -0
  89. package/dist/esm/core/config.d.ts +48 -0
  90. package/dist/esm/core/config.js +83 -0
  91. package/dist/esm/core/config.js.map +1 -0
  92. package/dist/esm/core/errors.d.ts +51 -0
  93. package/dist/esm/core/errors.js +80 -0
  94. package/dist/esm/core/errors.js.map +1 -0
  95. package/dist/esm/core/logger.d.ts +21 -0
  96. package/dist/esm/core/logger.js +109 -0
  97. package/dist/esm/core/logger.js.map +1 -0
  98. package/dist/esm/core/performance.d.ts +53 -0
  99. package/dist/esm/core/performance.js +140 -0
  100. package/dist/esm/core/performance.js.map +1 -0
  101. package/dist/esm/core/plugin-manager.d.ts +66 -0
  102. package/dist/esm/core/plugin-manager.js +148 -0
  103. package/dist/esm/core/plugin-manager.js.map +1 -0
  104. package/dist/esm/core/security.d.ts +93 -0
  105. package/dist/esm/core/security.js +315 -0
  106. package/dist/esm/core/security.js.map +1 -0
  107. package/dist/esm/definitions.d.ts +639 -0
  108. package/dist/esm/definitions.js +103 -0
  109. package/dist/esm/definitions.js.map +1 -0
  110. package/dist/esm/index.d.ts +12 -0
  111. package/dist/esm/index.js +16 -0
  112. package/dist/esm/index.js.map +1 -0
  113. package/dist/esm/live-update/bundle-manager.d.ts +94 -0
  114. package/dist/esm/live-update/bundle-manager.js +310 -0
  115. package/dist/esm/live-update/bundle-manager.js.map +1 -0
  116. package/dist/esm/live-update/certificate-pinning.d.ts +38 -0
  117. package/dist/esm/live-update/certificate-pinning.js +78 -0
  118. package/dist/esm/live-update/certificate-pinning.js.map +1 -0
  119. package/dist/esm/live-update/download-manager.d.ts +67 -0
  120. package/dist/esm/live-update/download-manager.js +319 -0
  121. package/dist/esm/live-update/download-manager.js.map +1 -0
  122. package/dist/esm/live-update/update-manager.d.ts +52 -0
  123. package/dist/esm/live-update/update-manager.js +294 -0
  124. package/dist/esm/live-update/update-manager.js.map +1 -0
  125. package/dist/esm/live-update/version-manager.d.ts +84 -0
  126. package/dist/esm/live-update/version-manager.js +335 -0
  127. package/dist/esm/live-update/version-manager.js.map +1 -0
  128. package/dist/esm/plugin.d.ts +6 -0
  129. package/dist/esm/plugin.js +283 -0
  130. package/dist/esm/plugin.js.map +1 -0
  131. package/dist/esm/security/crypto.d.ts +25 -0
  132. package/dist/esm/security/crypto.js +70 -0
  133. package/dist/esm/security/crypto.js.map +1 -0
  134. package/dist/esm/security/validator.d.ts +60 -0
  135. package/dist/esm/security/validator.js +143 -0
  136. package/dist/esm/security/validator.js.map +1 -0
  137. package/dist/esm/web.d.ts +74 -0
  138. package/dist/esm/web.js +595 -0
  139. package/dist/esm/web.js.map +1 -0
  140. package/dist/plugin.cjs.js +2 -0
  141. package/dist/plugin.cjs.js.map +1 -0
  142. package/dist/plugin.esm.js +2 -0
  143. package/dist/plugin.esm.js.map +1 -0
  144. package/dist/plugin.js +3 -0
  145. package/dist/plugin.js.map +1 -0
  146. package/docs/APP_REVIEW_GUIDE.md +768 -0
  147. package/docs/BUNDLE_SIGNING.md +264 -0
  148. package/docs/LIVE_UPDATES_GUIDE.md +650 -0
  149. package/docs/MIGRATION.md +192 -0
  150. package/docs/NATIVE_UPDATES_GUIDE.md +694 -0
  151. package/docs/QUICK_START.md +606 -0
  152. package/docs/README.md +111 -0
  153. package/docs/REMAINING_FEATURES.md +139 -0
  154. package/docs/api/app-review-api.md +259 -0
  155. package/docs/api/app-update-api.md +238 -0
  156. package/docs/api/events-api.md +451 -0
  157. package/docs/api/live-update-api.md +265 -0
  158. package/docs/background-updates.md +392 -0
  159. package/docs/examples/advanced-scenarios.md +410 -0
  160. package/docs/examples/basic-usage.md +185 -0
  161. package/docs/features/app-reviews.md +975 -0
  162. package/docs/features/app-updates.md +785 -0
  163. package/docs/features/live-updates.md +633 -0
  164. package/docs/getting-started/configuration.md +468 -0
  165. package/docs/getting-started/installation.md +209 -0
  166. package/docs/getting-started/quick-start.md +379 -0
  167. package/docs/guides/deployment-guide.md +333 -0
  168. package/docs/guides/migration-from-codepush.md +142 -0
  169. package/docs/guides/security-best-practices.md +1057 -0
  170. package/docs/guides/testing-guide.md +373 -0
  171. package/docs/production-readiness.md +478 -0
  172. package/docs/security/certificate-pinning.md +122 -0
  173. package/docs/server-requirements.md +147 -0
  174. package/ios/Plugin/AppReview/AppReviewPlugin.swift +158 -0
  175. package/ios/Plugin/AppUpdate/AppUpdatePlugin.swift +234 -0
  176. package/ios/Plugin/BackgroundUpdate/BackgroundNotificationManager.swift +329 -0
  177. package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +396 -0
  178. package/ios/Plugin/CapacitorNativeUpdatePlugin.m +45 -0
  179. package/ios/Plugin/CapacitorNativeUpdatePlugin.swift +190 -0
  180. package/ios/Plugin/Info.plist +43 -0
  181. package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +689 -0
  182. package/ios/Plugin/LiveUpdate/WebViewConfiguration.swift +45 -0
  183. package/ios/Plugin/Security/SecurityManager.swift +289 -0
  184. package/package.json +90 -0
@@ -0,0 +1,45 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { VersionManager } from '../live-update/version-manager';
3
+ describe('VersionManager', () => {
4
+ describe('compareVersions', () => {
5
+ it('should correctly compare semantic versions', () => {
6
+ expect(VersionManager.compareVersions('1.0.0', '1.0.0')).toBe(0);
7
+ expect(VersionManager.compareVersions('1.0.0', '1.0.1')).toBe(-1);
8
+ expect(VersionManager.compareVersions('1.0.1', '1.0.0')).toBe(1);
9
+ expect(VersionManager.compareVersions('2.0.0', '1.9.9')).toBe(1);
10
+ expect(VersionManager.compareVersions('1.0.0-alpha', '1.0.0')).toBe(-1);
11
+ });
12
+ it('should handle invalid versions', () => {
13
+ expect(VersionManager.compareVersions('invalid', '1.0.0')).toBe(-1);
14
+ expect(VersionManager.compareVersions('1.0.0', 'invalid')).toBe(1);
15
+ expect(VersionManager.compareVersions('invalid', 'invalid')).toBe(0);
16
+ });
17
+ });
18
+ describe('isValidVersion', () => {
19
+ it('should validate semantic versions', () => {
20
+ expect(VersionManager.isValidVersion('1.0.0')).toBe(true);
21
+ expect(VersionManager.isValidVersion('1.2.3')).toBe(true);
22
+ expect(VersionManager.isValidVersion('1.0.0-alpha')).toBe(true);
23
+ expect(VersionManager.isValidVersion('1.0.0+build123')).toBe(true);
24
+ });
25
+ it('should reject invalid versions', () => {
26
+ expect(VersionManager.isValidVersion('1.0')).toBe(false);
27
+ expect(VersionManager.isValidVersion('invalid')).toBe(false);
28
+ expect(VersionManager.isValidVersion('')).toBe(false);
29
+ expect(VersionManager.isValidVersion('v1.0.0')).toBe(false);
30
+ });
31
+ });
32
+ describe('shouldUpdate', () => {
33
+ it('should determine if update is needed', () => {
34
+ expect(VersionManager.shouldUpdate('1.0.0', '1.0.1')).toBe(true);
35
+ expect(VersionManager.shouldUpdate('1.0.0', '2.0.0')).toBe(true);
36
+ expect(VersionManager.shouldUpdate('1.0.1', '1.0.0')).toBe(false);
37
+ expect(VersionManager.shouldUpdate('1.0.0', '1.0.0')).toBe(false);
38
+ });
39
+ it('should respect minimum app version', () => {
40
+ expect(VersionManager.shouldUpdate('1.0.0', '1.0.1', '1.0.0')).toBe(true);
41
+ expect(VersionManager.shouldUpdate('1.0.0', '1.0.1', '2.0.0')).toBe(false);
42
+ });
43
+ });
44
+ });
45
+ //# sourceMappingURL=version-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-manager.test.js","sourceRoot":"","sources":["../../../src/__tests__/version-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { PluginConfig } from '../core/config';
2
+ import { ReviewConditions, ReviewRequestOptions } from './types';
3
+ import { AppReviewPlugin, ReviewResult, CanRequestReviewResult } from '../definitions';
4
+ import { PluginListenerHandle } from '@capacitor/core';
5
+ export declare class AppReviewManager implements AppReviewPlugin {
6
+ private config;
7
+ private logger;
8
+ private conditionsChecker;
9
+ private rateLimiter;
10
+ private platformHandler;
11
+ private listeners;
12
+ constructor(config: PluginConfig);
13
+ requestReview(options?: ReviewRequestOptions): Promise<ReviewResult>;
14
+ canRequestReview(): Promise<CanRequestReviewResult>;
15
+ openStoreReview(): Promise<void>;
16
+ private getStoreReviewUrl;
17
+ resetReviewPrompts(): Promise<void>;
18
+ setReviewConditions(conditions: ReviewConditions): Promise<void>;
19
+ trackSignificantEvent(eventName: string): Promise<void>;
20
+ getReviewMetrics(): Promise<any>;
21
+ addListener(eventName: string, listenerFunc: (data: any) => void): PluginListenerHandle;
22
+ removeAllListeners(eventName?: string): void;
23
+ private emit;
24
+ }
@@ -0,0 +1,195 @@
1
+ import { Logger } from '../core/logger';
2
+ import { ReviewConditionsChecker } from './review-conditions-checker';
3
+ import { ReviewRateLimiter } from './review-rate-limiter';
4
+ import { PlatformReviewHandler } from './platform-review-handler';
5
+ export class AppReviewManager {
6
+ constructor(config) {
7
+ this.listeners = new Map();
8
+ this.config = config;
9
+ this.logger = new Logger('AppReviewManager');
10
+ this.conditionsChecker = new ReviewConditionsChecker(config);
11
+ this.rateLimiter = new ReviewRateLimiter(config);
12
+ this.platformHandler = new PlatformReviewHandler(config);
13
+ }
14
+ async requestReview(options) {
15
+ try {
16
+ this.logger.log('Requesting app review', options);
17
+ // Check if we can request review (unless forced)
18
+ if (!(options === null || options === void 0 ? void 0 : options.force)) {
19
+ const availability = await this.canRequestReview();
20
+ if (!availability.canRequest) {
21
+ return {
22
+ displayed: false,
23
+ reason: availability.reason || 'Rate limiting active',
24
+ };
25
+ }
26
+ }
27
+ // Request review based on platform
28
+ const result = await this.platformHandler.requestReview(options);
29
+ // Update rate limiting data
30
+ if (result.displayed) {
31
+ await this.rateLimiter.recordRequest();
32
+ // Emit event
33
+ this.emit('reviewPromptDisplayed', {
34
+ platform: this.platformHandler.getPlatform(),
35
+ method: (options === null || options === void 0 ? void 0 : options.useCustomUI) ? 'custom' : 'in-app',
36
+ timestamp: Date.now(),
37
+ });
38
+ }
39
+ return result;
40
+ }
41
+ catch (error) {
42
+ this.logger.error('Failed to request review', error);
43
+ throw error;
44
+ }
45
+ }
46
+ async canRequestReview() {
47
+ try {
48
+ this.logger.log('Checking review availability');
49
+ // Check rate limits
50
+ const rateLimitCheck = await this.rateLimiter.canRequestReview();
51
+ if (!rateLimitCheck.canRequest) {
52
+ return rateLimitCheck;
53
+ }
54
+ // Check conditions
55
+ const conditionsCheck = await this.conditionsChecker.checkConditions();
56
+ if (!conditionsCheck.canRequest) {
57
+ return conditionsCheck;
58
+ }
59
+ // Check platform availability
60
+ const platformCheck = await this.platformHandler.isReviewAvailable();
61
+ if (!platformCheck) {
62
+ return {
63
+ canRequest: false,
64
+ reason: 'Review not available on this platform',
65
+ };
66
+ }
67
+ return {
68
+ canRequest: true,
69
+ };
70
+ }
71
+ catch (error) {
72
+ this.logger.error('Failed to check review availability', error);
73
+ return {
74
+ canRequest: false,
75
+ reason: 'Error checking availability',
76
+ };
77
+ }
78
+ }
79
+ async openStoreReview() {
80
+ try {
81
+ this.logger.log('Opening store review page');
82
+ const storeUrl = await this.getStoreReviewUrl();
83
+ await this.platformHandler.openUrl(storeUrl.url);
84
+ // Emit event
85
+ this.emit('reviewPromptDisplayed', {
86
+ platform: storeUrl.platform,
87
+ method: 'store-redirect',
88
+ timestamp: Date.now(),
89
+ });
90
+ }
91
+ catch (error) {
92
+ this.logger.error('Failed to open store review', error);
93
+ throw error;
94
+ }
95
+ }
96
+ async getStoreReviewUrl() {
97
+ try {
98
+ this.logger.log('Getting store review URL');
99
+ return await this.platformHandler.getStoreReviewUrl();
100
+ }
101
+ catch (error) {
102
+ this.logger.error('Failed to get store review URL', error);
103
+ throw error;
104
+ }
105
+ }
106
+ async resetReviewPrompts() {
107
+ try {
108
+ this.logger.log('Resetting review prompts');
109
+ await this.rateLimiter.reset();
110
+ await this.conditionsChecker.reset();
111
+ }
112
+ catch (error) {
113
+ this.logger.error('Failed to reset review prompts', error);
114
+ throw error;
115
+ }
116
+ }
117
+ async setReviewConditions(conditions) {
118
+ try {
119
+ this.logger.log('Setting review conditions', conditions);
120
+ await this.conditionsChecker.setConditions(conditions);
121
+ }
122
+ catch (error) {
123
+ this.logger.error('Failed to set review conditions', error);
124
+ throw error;
125
+ }
126
+ }
127
+ async trackSignificantEvent(eventName) {
128
+ try {
129
+ this.logger.log('Tracking significant event', eventName);
130
+ await this.conditionsChecker.trackEvent(eventName);
131
+ // Check if we should prompt for review after this event
132
+ if (this.config.promptAfterPositiveEvents) {
133
+ const canRequest = await this.canRequestReview();
134
+ if (canRequest.canRequest) {
135
+ // Delay the prompt slightly for better UX
136
+ setTimeout(() => {
137
+ this.requestReview();
138
+ }, 2000);
139
+ }
140
+ }
141
+ }
142
+ catch (error) {
143
+ this.logger.error('Failed to track significant event', error);
144
+ throw error;
145
+ }
146
+ }
147
+ async getReviewMetrics() {
148
+ try {
149
+ this.logger.log('Getting review metrics');
150
+ const metrics = await this.rateLimiter.getMetrics();
151
+ const conditions = await this.conditionsChecker.getStatus();
152
+ return Object.assign(Object.assign({}, metrics), conditions);
153
+ }
154
+ catch (error) {
155
+ this.logger.error('Failed to get review metrics', error);
156
+ throw error;
157
+ }
158
+ }
159
+ addListener(eventName, listenerFunc) {
160
+ if (!this.listeners.has(eventName)) {
161
+ this.listeners.set(eventName, new Set());
162
+ }
163
+ this.listeners.get(eventName).add(listenerFunc);
164
+ return {
165
+ remove: async () => {
166
+ const listeners = this.listeners.get(eventName);
167
+ if (listeners) {
168
+ listeners.delete(listenerFunc);
169
+ }
170
+ },
171
+ };
172
+ }
173
+ removeAllListeners(eventName) {
174
+ if (eventName) {
175
+ this.listeners.delete(eventName);
176
+ }
177
+ else {
178
+ this.listeners.clear();
179
+ }
180
+ }
181
+ emit(eventName, data) {
182
+ const listeners = this.listeners.get(eventName);
183
+ if (listeners) {
184
+ listeners.forEach((listener) => {
185
+ try {
186
+ listener(data);
187
+ }
188
+ catch (error) {
189
+ this.logger.error(`Error in ${eventName} listener`, error);
190
+ }
191
+ });
192
+ }
193
+ }
194
+ }
195
+ //# sourceMappingURL=app-review-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-review-manager.js","sourceRoot":"","sources":["../../../src/app-review/app-review-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { AppReviewManager } from './app-review-manager';
2
+ export { ReviewConditionsChecker } from './review-conditions-checker';
3
+ export { ReviewRateLimiter } from './review-rate-limiter';
4
+ export { PlatformReviewHandler } from './platform-review-handler';
5
+ export * from './types';
@@ -0,0 +1,6 @@
1
+ export { AppReviewManager } from './app-review-manager';
2
+ export { ReviewConditionsChecker } from './review-conditions-checker';
3
+ export { ReviewRateLimiter } from './review-rate-limiter';
4
+ export { PlatformReviewHandler } from './platform-review-handler';
5
+ export * from './types';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/app-review/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,cAAc,SAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { PluginConfig } from '../core/config';
2
+ import { StoreReviewUrl, ReviewRequestOptions } from './types';
3
+ import { ReviewResult } from '../definitions';
4
+ export declare class PlatformReviewHandler {
5
+ private config;
6
+ private logger;
7
+ private platform;
8
+ constructor(config: PluginConfig);
9
+ requestReview(options?: ReviewRequestOptions): Promise<ReviewResult>;
10
+ isReviewAvailable(): Promise<boolean>;
11
+ getStoreReviewUrl(): Promise<StoreReviewUrl>;
12
+ openUrl(url: string): Promise<void>;
13
+ getPlatform(): string;
14
+ private requestIOSReview;
15
+ private requestAndroidReview;
16
+ private requestWebReview;
17
+ private showCustomReviewPrompt;
18
+ private simulateReviewRequest;
19
+ private isIOSVersionSupported;
20
+ }
@@ -0,0 +1,138 @@
1
+ import { Logger } from '../core/logger';
2
+ import { Capacitor } from '@capacitor/core';
3
+ export class PlatformReviewHandler {
4
+ constructor(config) {
5
+ this.config = config;
6
+ this.logger = new Logger('PlatformReviewHandler');
7
+ this.platform = Capacitor.getPlatform();
8
+ }
9
+ async requestReview(options) {
10
+ this.logger.log('Requesting review on platform', this.platform);
11
+ // Check if custom UI is requested
12
+ if (options === null || options === void 0 ? void 0 : options.useCustomUI) {
13
+ return this.showCustomReviewPrompt(options);
14
+ }
15
+ // Platform-specific in-app review
16
+ if (this.platform === 'ios') {
17
+ return this.requestIOSReview();
18
+ }
19
+ else if (this.platform === 'android') {
20
+ return this.requestAndroidReview();
21
+ }
22
+ else {
23
+ return this.requestWebReview(options);
24
+ }
25
+ }
26
+ async isReviewAvailable() {
27
+ // Check if in-app review is available on this platform
28
+ if (this.platform === 'ios') {
29
+ // iOS 10.3+ supports in-app reviews
30
+ return this.isIOSVersionSupported();
31
+ }
32
+ else if (this.platform === 'android') {
33
+ // Android with Play Core supports in-app reviews
34
+ return true;
35
+ }
36
+ else {
37
+ // Web can show custom prompts
38
+ return true;
39
+ }
40
+ }
41
+ async getStoreReviewUrl() {
42
+ const platform = this.platform;
43
+ let url = '';
44
+ if (platform === 'ios') {
45
+ const appStoreId = this.config.appStoreId || this.config.iosAppId;
46
+ if (!appStoreId) {
47
+ throw new Error('App Store ID not configured');
48
+ }
49
+ // Deep link to review page
50
+ url = `https://apps.apple.com/app/id${appStoreId}?action=write-review`;
51
+ }
52
+ else if (platform === 'android') {
53
+ const packageName = this.config.packageName;
54
+ if (!packageName) {
55
+ throw new Error('Package name not configured');
56
+ }
57
+ // Deep link to Play Store review
58
+ url = `https://play.google.com/store/apps/details?id=${packageName}&showAllReviews=true`;
59
+ }
60
+ else {
61
+ // Web fallback URL
62
+ url = this.config.webReviewUrl || window.location.origin + '/review';
63
+ }
64
+ return { url, platform: platform };
65
+ }
66
+ async openUrl(url) {
67
+ if (typeof window !== 'undefined' && window.open) {
68
+ window.open(url, '_blank');
69
+ }
70
+ else {
71
+ throw new Error('Cannot open URL on this platform');
72
+ }
73
+ }
74
+ getPlatform() {
75
+ return this.platform;
76
+ }
77
+ async requestIOSReview() {
78
+ // This would be handled by native iOS implementation using StoreKit
79
+ // For web simulation:
80
+ if (this.platform === 'web') {
81
+ return this.simulateReviewRequest('ios');
82
+ }
83
+ // Native implementation would call SKStoreReviewController.requestReview()
84
+ return {
85
+ displayed: true,
86
+ };
87
+ }
88
+ async requestAndroidReview() {
89
+ // This would be handled by native Android implementation using Play Core
90
+ // For web simulation:
91
+ if (this.platform === 'web') {
92
+ return this.simulateReviewRequest('android');
93
+ }
94
+ // Native implementation would use ReviewManager from Play Core
95
+ return {
96
+ displayed: true,
97
+ };
98
+ }
99
+ async requestWebReview(options) {
100
+ // For web, show a custom prompt
101
+ return this.showCustomReviewPrompt(options);
102
+ }
103
+ async showCustomReviewPrompt(options) {
104
+ const message = (options === null || options === void 0 ? void 0 : options.customMessage) || 'Would you like to rate our app?';
105
+ // Create a simple modal for web
106
+ if (typeof window !== 'undefined' && window.confirm) {
107
+ const result = window.confirm(message);
108
+ if (result) {
109
+ // User agreed, open store
110
+ const storeUrl = await this.getStoreReviewUrl();
111
+ await this.openUrl(storeUrl.url);
112
+ }
113
+ return {
114
+ displayed: true,
115
+ };
116
+ }
117
+ return {
118
+ displayed: false,
119
+ reason: 'Custom UI not available',
120
+ };
121
+ }
122
+ simulateReviewRequest(platform) {
123
+ // Simulate native behavior for testing
124
+ this.logger.log(`Simulating ${platform} review request`);
125
+ // Simulate that the prompt was shown
126
+ return {
127
+ displayed: true,
128
+ };
129
+ }
130
+ isIOSVersionSupported() {
131
+ if (this.platform !== 'ios')
132
+ return false;
133
+ // Check iOS version (10.3+ required for SKStoreReviewController)
134
+ // This would be checked in native code
135
+ return true;
136
+ }
137
+ }
138
+ //# sourceMappingURL=platform-review-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-review-handler.js","sourceRoot":"","sources":["../../../src/app-review/platform-review-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { PluginConfig } from '../core/config';
2
+ import { ReviewConditions } from './types';
3
+ import { CanRequestReviewResult } from '../definitions';
4
+ export declare class ReviewConditionsChecker {
5
+ private config;
6
+ private logger;
7
+ private storageKey;
8
+ private defaultConditions;
9
+ constructor(config: PluginConfig);
10
+ checkConditions(): Promise<CanRequestReviewResult>;
11
+ setConditions(conditions: ReviewConditions): Promise<void>;
12
+ trackEvent(eventName: string): Promise<void>;
13
+ trackAppLaunch(): Promise<void>;
14
+ reset(): Promise<void>;
15
+ getStatus(): Promise<any>;
16
+ private initialize;
17
+ private getStoredData;
18
+ private saveStoredData;
19
+ private getDaysSince;
20
+ private getCurrentVersion;
21
+ private evaluateCustomCondition;
22
+ }
@@ -0,0 +1,155 @@
1
+ import { Logger } from '../core/logger';
2
+ export class ReviewConditionsChecker {
3
+ constructor(config) {
4
+ this.storageKey = 'cap_review_conditions';
5
+ this.defaultConditions = {
6
+ minimumDaysSinceInstall: 3,
7
+ minimumDaysSinceLastPrompt: 90,
8
+ minimumAppLaunches: 5,
9
+ minimumSignificantEvents: 3,
10
+ requirePositiveEvents: true,
11
+ maxPromptsPerVersion: 1,
12
+ };
13
+ this.config = config;
14
+ this.logger = new Logger('ReviewConditionsChecker');
15
+ this.initialize();
16
+ }
17
+ async checkConditions() {
18
+ const data = await this.getStoredData();
19
+ const conditions = data.conditions;
20
+ // Check days since install
21
+ const daysSinceInstall = this.getDaysSince(data.installDate);
22
+ if (daysSinceInstall < (conditions.minimumDaysSinceInstall || 0)) {
23
+ return {
24
+ canRequest: false,
25
+ reason: `Only ${daysSinceInstall} days since install, need ${conditions.minimumDaysSinceInstall}`,
26
+ };
27
+ }
28
+ // Check app launches
29
+ if (data.appLaunches < (conditions.minimumAppLaunches || 0)) {
30
+ return {
31
+ canRequest: false,
32
+ reason: `Only ${data.appLaunches} app launches, need ${conditions.minimumAppLaunches}`,
33
+ };
34
+ }
35
+ // Check significant events
36
+ if (conditions.requirePositiveEvents &&
37
+ data.significantEvents.length < (conditions.minimumSignificantEvents || 0)) {
38
+ return {
39
+ canRequest: false,
40
+ reason: `Only ${data.significantEvents.length} significant events, need ${conditions.minimumSignificantEvents}`,
41
+ };
42
+ }
43
+ // Check custom conditions
44
+ if (conditions.customConditions) {
45
+ for (const [key, value] of Object.entries(conditions.customConditions)) {
46
+ if (!this.evaluateCustomCondition(key, value)) {
47
+ return {
48
+ canRequest: false,
49
+ reason: `Custom condition '${key}' not met`,
50
+ };
51
+ }
52
+ }
53
+ }
54
+ return { canRequest: true };
55
+ }
56
+ async setConditions(conditions) {
57
+ const data = await this.getStoredData();
58
+ data.conditions = Object.assign(Object.assign({}, this.defaultConditions), conditions);
59
+ await this.saveStoredData(data);
60
+ }
61
+ async trackEvent(eventName) {
62
+ const data = await this.getStoredData();
63
+ // Add to significant events if not already tracked
64
+ if (!data.significantEvents.includes(eventName)) {
65
+ data.significantEvents.push(eventName);
66
+ await this.saveStoredData(data);
67
+ this.logger.log('Tracked significant event', eventName);
68
+ }
69
+ }
70
+ async trackAppLaunch() {
71
+ const data = await this.getStoredData();
72
+ data.appLaunches++;
73
+ await this.saveStoredData(data);
74
+ this.logger.log('Tracked app launch', data.appLaunches);
75
+ }
76
+ async reset() {
77
+ const data = await this.getStoredData();
78
+ data.significantEvents = [];
79
+ data.appLaunches = 0;
80
+ await this.saveStoredData(data);
81
+ }
82
+ async getStatus() {
83
+ const data = await this.getStoredData();
84
+ return {
85
+ installDate: new Date(data.installDate),
86
+ daysSinceInstall: this.getDaysSince(data.installDate),
87
+ appLaunches: data.appLaunches,
88
+ significantEvents: data.significantEvents,
89
+ currentVersion: await this.getCurrentVersion(),
90
+ conditions: data.conditions,
91
+ };
92
+ }
93
+ async initialize() {
94
+ const data = await this.getStoredData();
95
+ // Check if app version changed
96
+ const currentVersion = await this.getCurrentVersion();
97
+ if (data.lastVersion !== currentVersion) {
98
+ data.lastVersion = currentVersion;
99
+ // Optionally reset some counters on version change
100
+ await this.saveStoredData(data);
101
+ }
102
+ // Track app launch
103
+ await this.trackAppLaunch();
104
+ }
105
+ async getStoredData() {
106
+ try {
107
+ const stored = localStorage.getItem(this.storageKey);
108
+ if (stored) {
109
+ return JSON.parse(stored);
110
+ }
111
+ }
112
+ catch (error) {
113
+ this.logger.error('Failed to read stored conditions', error);
114
+ }
115
+ // Return default data
116
+ return {
117
+ installDate: Date.now(),
118
+ appLaunches: 0,
119
+ significantEvents: [],
120
+ lastVersion: await this.getCurrentVersion(),
121
+ conditions: this.defaultConditions,
122
+ };
123
+ }
124
+ async saveStoredData(data) {
125
+ try {
126
+ localStorage.setItem(this.storageKey, JSON.stringify(data));
127
+ }
128
+ catch (error) {
129
+ this.logger.error('Failed to save conditions data', error);
130
+ }
131
+ }
132
+ getDaysSince(timestamp) {
133
+ const msPerDay = 24 * 60 * 60 * 1000;
134
+ return Math.floor((Date.now() - timestamp) / msPerDay);
135
+ }
136
+ async getCurrentVersion() {
137
+ // This would be provided by the platform
138
+ return '1.0.0';
139
+ }
140
+ evaluateCustomCondition(key, value) {
141
+ // Implement custom condition evaluation logic
142
+ // This can be extended based on specific needs
143
+ switch (key) {
144
+ case 'isPremiumUser':
145
+ return this.config.isPremiumUser === value;
146
+ case 'hasCompletedTutorial':
147
+ return localStorage.getItem('tutorial_completed') === 'true';
148
+ case 'hasMadePurchase':
149
+ return localStorage.getItem('has_purchased') === 'true';
150
+ default:
151
+ return true;
152
+ }
153
+ }
154
+ }
155
+ //# sourceMappingURL=review-conditions-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-conditions-checker.js","sourceRoot":"","sources":["../../../src/app-review/review-conditions-checker.ts"],"names":[],"mappings":"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"}