@umituz/react-native-subscription 1.0.6 → 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 (83) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +10 -0
  3. package/lib/application/ports/ISubscriptionRepository.d.ts +25 -0
  4. package/lib/application/ports/ISubscriptionRepository.d.ts.map +1 -0
  5. package/lib/application/ports/ISubscriptionRepository.js +9 -0
  6. package/lib/application/ports/ISubscriptionRepository.js.map +1 -0
  7. package/lib/application/ports/ISubscriptionService.d.ts +28 -0
  8. package/lib/application/ports/ISubscriptionService.d.ts.map +1 -0
  9. package/lib/application/ports/ISubscriptionService.js +6 -0
  10. package/lib/application/ports/ISubscriptionService.js.map +1 -0
  11. package/lib/domain/entities/SubscriptionStatus.d.ts +31 -0
  12. package/lib/domain/entities/SubscriptionStatus.d.ts.map +1 -0
  13. package/lib/domain/entities/SubscriptionStatus.js +39 -0
  14. package/lib/domain/entities/SubscriptionStatus.js.map +1 -0
  15. package/lib/domain/errors/SubscriptionError.d.ts +18 -0
  16. package/lib/domain/errors/SubscriptionError.d.ts.map +1 -0
  17. package/lib/domain/errors/SubscriptionError.js +30 -0
  18. package/lib/domain/errors/SubscriptionError.js.map +1 -0
  19. package/lib/domain/value-objects/SubscriptionConfig.d.ts +15 -0
  20. package/lib/domain/value-objects/SubscriptionConfig.d.ts.map +1 -0
  21. package/lib/domain/value-objects/SubscriptionConfig.js +6 -0
  22. package/lib/domain/value-objects/SubscriptionConfig.js.map +1 -0
  23. package/lib/index.d.ts +33 -0
  24. package/lib/index.d.ts.map +1 -0
  25. package/lib/index.js +43 -0
  26. package/lib/index.js.map +1 -0
  27. package/lib/infrastructure/services/ActivationHandler.d.ts +20 -0
  28. package/lib/infrastructure/services/ActivationHandler.d.ts.map +1 -0
  29. package/lib/infrastructure/services/ActivationHandler.js +71 -0
  30. package/lib/infrastructure/services/ActivationHandler.js.map +1 -0
  31. package/lib/infrastructure/services/SubscriptionService.d.ts +22 -0
  32. package/lib/infrastructure/services/SubscriptionService.d.ts.map +1 -0
  33. package/lib/infrastructure/services/SubscriptionService.js +110 -0
  34. package/lib/infrastructure/services/SubscriptionService.js.map +1 -0
  35. package/lib/presentation/hooks/useSubscription.d.ts +33 -0
  36. package/lib/presentation/hooks/useSubscription.d.ts.map +1 -0
  37. package/lib/presentation/hooks/useSubscription.js +129 -0
  38. package/lib/presentation/hooks/useSubscription.js.map +1 -0
  39. package/lib/utils/dateUtils.d.ts +39 -0
  40. package/lib/utils/dateUtils.d.ts.map +1 -0
  41. package/lib/utils/dateUtils.js +117 -0
  42. package/lib/utils/dateUtils.js.map +1 -0
  43. package/lib/utils/dateValidationUtils.d.ts +20 -0
  44. package/lib/utils/dateValidationUtils.d.ts.map +1 -0
  45. package/lib/utils/dateValidationUtils.js +39 -0
  46. package/lib/utils/dateValidationUtils.js.map +1 -0
  47. package/lib/utils/periodUtils.d.ts +38 -0
  48. package/lib/utils/periodUtils.d.ts.map +1 -0
  49. package/lib/utils/periodUtils.js +70 -0
  50. package/lib/utils/periodUtils.js.map +1 -0
  51. package/lib/utils/planDetectionUtils.d.ts +17 -0
  52. package/lib/utils/planDetectionUtils.d.ts.map +1 -0
  53. package/lib/utils/planDetectionUtils.js +31 -0
  54. package/lib/utils/planDetectionUtils.js.map +1 -0
  55. package/lib/utils/priceUtils.d.ts +23 -0
  56. package/lib/utils/priceUtils.d.ts.map +1 -0
  57. package/lib/utils/priceUtils.js +29 -0
  58. package/lib/utils/priceUtils.js.map +1 -0
  59. package/lib/utils/subscriptionConstants.d.ts +62 -0
  60. package/lib/utils/subscriptionConstants.d.ts.map +1 -0
  61. package/lib/utils/subscriptionConstants.js +61 -0
  62. package/lib/utils/subscriptionConstants.js.map +1 -0
  63. package/package.json +13 -3
  64. package/src/application/ports/ISubscriptionRepository.ts +10 -0
  65. package/src/application/ports/ISubscriptionService.ts +10 -0
  66. package/src/domain/entities/SubscriptionStatus.test.ts +106 -0
  67. package/src/domain/entities/SubscriptionStatus.ts +10 -0
  68. package/src/domain/errors/SubscriptionError.ts +10 -0
  69. package/src/domain/value-objects/SubscriptionConfig.ts +0 -0
  70. package/src/index.ts +9 -2
  71. package/src/infrastructure/services/ActivationHandler.ts +108 -0
  72. package/src/infrastructure/services/SubscriptionService.ts +58 -177
  73. package/src/presentation/hooks/useSubscription.ts +22 -2
  74. package/src/utils/dateUtils.test.ts +116 -0
  75. package/src/utils/dateUtils.ts +12 -76
  76. package/src/utils/dateValidationUtils.test.ts +142 -0
  77. package/src/utils/dateValidationUtils.ts +53 -0
  78. package/src/utils/periodUtils.ts +0 -0
  79. package/src/utils/planDetectionUtils.test.ts +47 -0
  80. package/src/utils/planDetectionUtils.ts +40 -0
  81. package/src/utils/priceUtils.test.ts +35 -0
  82. package/src/utils/priceUtils.ts +0 -0
  83. package/src/utils/subscriptionConstants.ts +0 -0
package/LICENSE CHANGED
@@ -20,3 +20,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
22
 
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
package/README.md CHANGED
@@ -204,3 +204,13 @@ initializeRevenueCatService({
204
204
 
205
205
  MIT
206
206
 
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Subscription Repository Interface
3
+ * Port for database operations
4
+ *
5
+ * SECURITY: Apps must implement this interface with their database.
6
+ * Never expose database credentials or allow direct database access.
7
+ */
8
+ import type { SubscriptionStatus } from '../../domain/entities/SubscriptionStatus';
9
+ export interface ISubscriptionRepository {
10
+ /**
11
+ * Get subscription status for a user
12
+ * Returns null if user not found
13
+ */
14
+ getSubscriptionStatus(userId: string): Promise<SubscriptionStatus | null>;
15
+ /**
16
+ * Update subscription status for a user
17
+ */
18
+ updateSubscriptionStatus(userId: string, status: Partial<SubscriptionStatus>): Promise<SubscriptionStatus>;
19
+ /**
20
+ * Check if subscription is valid (not expired)
21
+ * SECURITY: Always validate expiration server-side
22
+ */
23
+ isSubscriptionValid(status: SubscriptionStatus): boolean;
24
+ }
25
+ //# sourceMappingURL=ISubscriptionRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISubscriptionRepository.d.ts","sourceRoot":"","sources":["../../../src/application/ports/ISubscriptionRepository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAEnF,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAE1E;;OAEG;IACH,wBAAwB,CACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;CAC1D"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Subscription Repository Interface
3
+ * Port for database operations
4
+ *
5
+ * SECURITY: Apps must implement this interface with their database.
6
+ * Never expose database credentials or allow direct database access.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=ISubscriptionRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISubscriptionRepository.js","sourceRoot":"","sources":["../../../src/application/ports/ISubscriptionRepository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Subscription Service Interface
3
+ * Port for subscription operations
4
+ */
5
+ import type { SubscriptionStatus } from '../../domain/entities/SubscriptionStatus';
6
+ export interface ISubscriptionService {
7
+ /**
8
+ * Get subscription status for a user
9
+ */
10
+ getSubscriptionStatus(userId: string): Promise<SubscriptionStatus>;
11
+ /**
12
+ * Check if user has active subscription
13
+ */
14
+ isPremium(userId: string): Promise<boolean>;
15
+ /**
16
+ * Activate subscription
17
+ */
18
+ activateSubscription(userId: string, productId: string, expiresAt: string | null): Promise<SubscriptionStatus>;
19
+ /**
20
+ * Deactivate subscription
21
+ */
22
+ deactivateSubscription(userId: string): Promise<SubscriptionStatus>;
23
+ /**
24
+ * Update subscription status
25
+ */
26
+ updateSubscriptionStatus(userId: string, updates: Partial<SubscriptionStatus>): Promise<SubscriptionStatus>;
27
+ }
28
+ //# sourceMappingURL=ISubscriptionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISubscriptionService.d.ts","sourceRoot":"","sources":["../../../src/application/ports/ISubscriptionService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAEnF,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEnE;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5C;;OAEG;IACH,oBAAoB,CAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEpE;;OAEG;IACH,wBAAwB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Subscription Service Interface
3
+ * Port for subscription operations
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=ISubscriptionService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISubscriptionService.js","sourceRoot":"","sources":["../../../src/application/ports/ISubscriptionService.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Subscription Status Entity
3
+ * Represents subscription status for a user
4
+ *
5
+ * SECURITY: This is a read-only entity from database.
6
+ * Never trust client-side subscription status - always validate server-side.
7
+ */
8
+ export interface SubscriptionStatus {
9
+ /** Whether user has active subscription */
10
+ isPremium: boolean;
11
+ /** Subscription expiration date (ISO string) */
12
+ expiresAt: string | null;
13
+ /** Product ID of the subscription */
14
+ productId: string | null;
15
+ /** When subscription was purchased (ISO string) */
16
+ purchasedAt: string | null;
17
+ /** External service customer ID (e.g., RevenueCat customer ID) */
18
+ customerId: string | null;
19
+ /** Last sync time with external service (ISO string) */
20
+ syncedAt: string | null;
21
+ }
22
+ /**
23
+ * Create default subscription status (free user)
24
+ */
25
+ export declare function createDefaultSubscriptionStatus(): SubscriptionStatus;
26
+ /**
27
+ * Check if subscription status is valid (not expired)
28
+ * SECURITY: Always validate expiration server-side
29
+ */
30
+ export declare function isSubscriptionValid(status: SubscriptionStatus | null): boolean;
31
+ //# sourceMappingURL=SubscriptionStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionStatus.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/SubscriptionStatus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IAEnB,gDAAgD;IAChD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB,qCAAqC;IACrC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB,mDAAmD;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,kEAAkE;IAClE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,kBAAkB,CASpE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAgB9E"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Subscription Status Entity
3
+ * Represents subscription status for a user
4
+ *
5
+ * SECURITY: This is a read-only entity from database.
6
+ * Never trust client-side subscription status - always validate server-side.
7
+ */
8
+ /**
9
+ * Create default subscription status (free user)
10
+ */
11
+ export function createDefaultSubscriptionStatus() {
12
+ return {
13
+ isPremium: false,
14
+ expiresAt: null,
15
+ productId: null,
16
+ purchasedAt: null,
17
+ customerId: null,
18
+ syncedAt: null,
19
+ };
20
+ }
21
+ /**
22
+ * Check if subscription status is valid (not expired)
23
+ * SECURITY: Always validate expiration server-side
24
+ */
25
+ export function isSubscriptionValid(status) {
26
+ if (!status || !status.isPremium) {
27
+ return false;
28
+ }
29
+ if (!status.expiresAt) {
30
+ // Lifetime subscription (no expiration)
31
+ return true;
32
+ }
33
+ const expirationDate = new Date(status.expiresAt);
34
+ const now = new Date();
35
+ // Add 1 day buffer for clock skew and timezone issues
36
+ const bufferMs = 24 * 60 * 60 * 1000;
37
+ return expirationDate.getTime() > now.getTime() - bufferMs;
38
+ }
39
+ //# sourceMappingURL=SubscriptionStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionStatus.js","sourceRoot":"","sources":["../../../src/domain/entities/SubscriptionStatus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH;;GAEG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAiC;IACnE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,wCAAwC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,sDAAsD;IACtD,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACrC,OAAO,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Subscription Errors
3
+ * Domain-specific errors for subscription operations
4
+ */
5
+ export declare class SubscriptionError extends Error {
6
+ readonly code: string;
7
+ constructor(message: string, code: string);
8
+ }
9
+ export declare class SubscriptionRepositoryError extends SubscriptionError {
10
+ constructor(message: string);
11
+ }
12
+ export declare class SubscriptionValidationError extends SubscriptionError {
13
+ constructor(message: string);
14
+ }
15
+ export declare class SubscriptionConfigurationError extends SubscriptionError {
16
+ constructor(message: string);
17
+ }
18
+ //# sourceMappingURL=SubscriptionError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionError.d.ts","sourceRoot":"","sources":["../../../src/domain/errors/SubscriptionError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,iBAAkB,SAAQ,KAAK;aACG,IAAI,EAAE,MAAM;gBAA7C,OAAO,EAAE,MAAM,EAAkB,IAAI,EAAE,MAAM;CAI1D;AAED,qBAAa,2BAA4B,SAAQ,iBAAiB;gBACpD,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,2BAA4B,SAAQ,iBAAiB;gBACpD,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,8BAA+B,SAAQ,iBAAiB;gBACvD,OAAO,EAAE,MAAM;CAI5B"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Subscription Errors
3
+ * Domain-specific errors for subscription operations
4
+ */
5
+ export class SubscriptionError extends Error {
6
+ constructor(message, code) {
7
+ super(message);
8
+ this.code = code;
9
+ this.name = 'SubscriptionError';
10
+ }
11
+ }
12
+ export class SubscriptionRepositoryError extends SubscriptionError {
13
+ constructor(message) {
14
+ super(message, 'REPOSITORY_ERROR');
15
+ this.name = 'SubscriptionRepositoryError';
16
+ }
17
+ }
18
+ export class SubscriptionValidationError extends SubscriptionError {
19
+ constructor(message) {
20
+ super(message, 'VALIDATION_ERROR');
21
+ this.name = 'SubscriptionValidationError';
22
+ }
23
+ }
24
+ export class SubscriptionConfigurationError extends SubscriptionError {
25
+ constructor(message) {
26
+ super(message, 'CONFIGURATION_ERROR');
27
+ this.name = 'SubscriptionConfigurationError';
28
+ }
29
+ }
30
+ //# sourceMappingURL=SubscriptionError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionError.js","sourceRoot":"","sources":["../../../src/domain/errors/SubscriptionError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe,EAAkB,IAAY;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,SAAI,GAAJ,IAAI,CAAQ;QAEvD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,iBAAiB;IAChE,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,iBAAiB;IAChE,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,OAAO,8BAA+B,SAAQ,iBAAiB;IACnE,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Subscription Configuration Value Object
3
+ * Configuration for subscription service
4
+ */
5
+ import type { SubscriptionStatus } from '../entities/SubscriptionStatus';
6
+ import type { ISubscriptionRepository } from '../../application/ports/ISubscriptionRepository';
7
+ export interface SubscriptionConfig {
8
+ /** Repository implementation for database operations */
9
+ repository: ISubscriptionRepository;
10
+ /** Optional callback when subscription status changes */
11
+ onStatusChanged?: (userId: string, status: SubscriptionStatus) => Promise<void> | void;
12
+ /** Optional callback for error logging */
13
+ onError?: (error: Error, context: string) => Promise<void> | void;
14
+ }
15
+ //# sourceMappingURL=SubscriptionConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionConfig.d.ts","sourceRoot":"","sources":["../../../src/domain/value-objects/SubscriptionConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAE/F,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,UAAU,EAAE,uBAAuB,CAAC;IAEpC,yDAAyD;IACzD,eAAe,CAAC,EAAE,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,kBAAkB,KACvB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE1B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACnE"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Subscription Configuration Value Object
3
+ * Configuration for subscription service
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=SubscriptionConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionConfig.js","sourceRoot":"","sources":["../../../src/domain/value-objects/SubscriptionConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * React Native Subscription - Public API
3
+ *
4
+ * Domain-Driven Design (DDD) Architecture
5
+ *
6
+ * This is the SINGLE SOURCE OF TRUTH for all subscription operations.
7
+ * ALL imports from the Subscription package MUST go through this file.
8
+ *
9
+ * Architecture:
10
+ * - domain: Entities, value objects, errors (business logic)
11
+ * - application: Ports (interfaces)
12
+ * - infrastructure: Subscription service implementation
13
+ * - presentation: Hooks (React integration)
14
+ *
15
+ * Usage:
16
+ * import { initializeSubscriptionService, useSubscription } from '@umituz/react-native-subscription';
17
+ */
18
+ export { SubscriptionError, SubscriptionRepositoryError, SubscriptionValidationError, SubscriptionConfigurationError, } from './domain/errors/SubscriptionError';
19
+ export { createDefaultSubscriptionStatus, isSubscriptionValid, } from './domain/entities/SubscriptionStatus';
20
+ export type { SubscriptionStatus } from './domain/entities/SubscriptionStatus';
21
+ export type { SubscriptionConfig } from './domain/value-objects/SubscriptionConfig';
22
+ export type { ISubscriptionRepository } from './application/ports/ISubscriptionRepository';
23
+ export type { ISubscriptionService } from './application/ports/ISubscriptionService';
24
+ export { SubscriptionService, initializeSubscriptionService, getSubscriptionService, resetSubscriptionService, } from './infrastructure/services/SubscriptionService';
25
+ export { useSubscription } from './presentation/hooks/useSubscription';
26
+ export type { UseSubscriptionResult } from './presentation/hooks/useSubscription';
27
+ export { formatExpirationDate, calculateExpirationDate, } from './utils/dateUtils';
28
+ export { isSubscriptionExpired, getDaysUntilExpiration, } from './utils/dateValidationUtils';
29
+ export { extractPlanFromProductId, } from './utils/planDetectionUtils';
30
+ export { formatPrice } from './utils/priceUtils';
31
+ export { getPeriodText } from './utils/periodUtils';
32
+ export { SUBSCRIPTION_PLAN_TYPES, MIN_SUBSCRIPTION_DURATIONS_DAYS, SUBSCRIPTION_PERIOD_DAYS, DATE_CONSTANTS, SUBSCRIPTION_PERIOD_UNITS, PRODUCT_ID_KEYWORDS, type SubscriptionPlanType, } from './utils/subscriptionConstants';
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,GACpB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAMpF,YAAY,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAC3F,YAAY,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAMrF,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,+CAA+C,CAAC;AAMvD,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAOlF,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,wBAAwB,EACxB,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,oBAAoB,GAC1B,MAAM,+BAA+B,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * React Native Subscription - Public API
3
+ *
4
+ * Domain-Driven Design (DDD) Architecture
5
+ *
6
+ * This is the SINGLE SOURCE OF TRUTH for all subscription operations.
7
+ * ALL imports from the Subscription package MUST go through this file.
8
+ *
9
+ * Architecture:
10
+ * - domain: Entities, value objects, errors (business logic)
11
+ * - application: Ports (interfaces)
12
+ * - infrastructure: Subscription service implementation
13
+ * - presentation: Hooks (React integration)
14
+ *
15
+ * Usage:
16
+ * import { initializeSubscriptionService, useSubscription } from '@umituz/react-native-subscription';
17
+ */
18
+ // =============================================================================
19
+ // DOMAIN LAYER - Business Logic
20
+ // =============================================================================
21
+ export { SubscriptionError, SubscriptionRepositoryError, SubscriptionValidationError, SubscriptionConfigurationError, } from './domain/errors/SubscriptionError';
22
+ export { createDefaultSubscriptionStatus, isSubscriptionValid, } from './domain/entities/SubscriptionStatus';
23
+ // =============================================================================
24
+ // INFRASTRUCTURE LAYER - Implementation
25
+ // =============================================================================
26
+ export { SubscriptionService, initializeSubscriptionService, getSubscriptionService, resetSubscriptionService, } from './infrastructure/services/SubscriptionService';
27
+ // =============================================================================
28
+ // PRESENTATION LAYER - Hooks
29
+ // =============================================================================
30
+ export { useSubscription } from './presentation/hooks/useSubscription';
31
+ // =============================================================================
32
+ // UTILS
33
+ // =============================================================================
34
+ // Date utilities
35
+ export { formatExpirationDate, calculateExpirationDate, } from './utils/dateUtils';
36
+ export { isSubscriptionExpired, getDaysUntilExpiration, } from './utils/dateValidationUtils';
37
+ export { extractPlanFromProductId, } from './utils/planDetectionUtils';
38
+ // Price utilities
39
+ export { formatPrice } from './utils/priceUtils';
40
+ // Period utilities
41
+ export { getPeriodText } from './utils/periodUtils';
42
+ export { SUBSCRIPTION_PLAN_TYPES, MIN_SUBSCRIPTION_DURATIONS_DAYS, SUBSCRIPTION_PERIOD_DAYS, DATE_CONSTANTS, SUBSCRIPTION_PERIOD_UNITS, PRODUCT_ID_KEYWORDS, } from './utils/subscriptionConstants';
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,gFAAgF;AAChF,gCAAgC;AAChC,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,GACpB,MAAM,sCAAsC,CAAC;AAY9C,gFAAgF;AAChF,wCAAwC;AACxC,gFAAgF;AAEhF,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,+CAA+C,CAAC;AAEvD,gFAAgF;AAChF,6BAA6B;AAC7B,gFAAgF;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAGvE,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,iBAAiB;AACjB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,kBAAkB;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,wBAAwB,EACxB,cAAc,EACd,yBAAyB,EACzB,mBAAmB,GAEpB,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Activation Handler
3
+ * Handles subscription activation and deactivation
4
+ */
5
+ import type { ISubscriptionRepository } from "../../application/ports/ISubscriptionRepository";
6
+ import type { SubscriptionStatus } from "../../domain/entities/SubscriptionStatus";
7
+ export interface ActivationHandlerConfig {
8
+ repository: ISubscriptionRepository;
9
+ onStatusChanged?: (userId: string, status: SubscriptionStatus) => Promise<void> | void;
10
+ onError?: (error: Error, context: string) => Promise<void> | void;
11
+ }
12
+ /**
13
+ * Activate subscription for user
14
+ */
15
+ export declare function activateSubscription(config: ActivationHandlerConfig, userId: string, productId: string, expiresAt: string | null): Promise<SubscriptionStatus>;
16
+ /**
17
+ * Deactivate subscription for user
18
+ */
19
+ export declare function deactivateSubscription(config: ActivationHandlerConfig, userId: string): Promise<SubscriptionStatus>;
20
+ //# sourceMappingURL=ActivationHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivationHandler.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/services/ActivationHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAGnF,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,uBAAuB,CAAC;IACpC,eAAe,CAAC,EAAE,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,kBAAkB,KACvB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACnE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAuB7B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,uBAAuB,EAC/B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC,CAqB7B"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Activation Handler
3
+ * Handles subscription activation and deactivation
4
+ */
5
+ import { SubscriptionRepositoryError } from "../../domain/errors/SubscriptionError";
6
+ /**
7
+ * Activate subscription for user
8
+ */
9
+ export async function activateSubscription(config, userId, productId, expiresAt) {
10
+ try {
11
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
12
+ console.log("[Subscription] Activating subscription in handler", { userId, productId, expiresAt });
13
+ }
14
+ const updatedStatus = await config.repository.updateSubscriptionStatus(userId, {
15
+ isPremium: true,
16
+ productId,
17
+ expiresAt,
18
+ purchasedAt: new Date().toISOString(),
19
+ syncedAt: new Date().toISOString(),
20
+ });
21
+ await notifyStatusChange(config, userId, updatedStatus);
22
+ return updatedStatus;
23
+ }
24
+ catch (error) {
25
+ await handleError(config, error, "activateSubscription");
26
+ throw new SubscriptionRepositoryError("Failed to activate subscription");
27
+ }
28
+ }
29
+ /**
30
+ * Deactivate subscription for user
31
+ */
32
+ export async function deactivateSubscription(config, userId) {
33
+ try {
34
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
35
+ console.log("[Subscription] Deactivating subscription in handler", { userId });
36
+ }
37
+ const updatedStatus = await config.repository.updateSubscriptionStatus(userId, {
38
+ isPremium: false,
39
+ expiresAt: null,
40
+ productId: null,
41
+ });
42
+ await notifyStatusChange(config, userId, updatedStatus);
43
+ return updatedStatus;
44
+ }
45
+ catch (error) {
46
+ await handleError(config, error, "deactivateSubscription");
47
+ throw new SubscriptionRepositoryError("Failed to deactivate subscription");
48
+ }
49
+ }
50
+ async function notifyStatusChange(config, userId, status) {
51
+ if (!config.onStatusChanged)
52
+ return;
53
+ try {
54
+ await config.onStatusChanged(userId, status);
55
+ }
56
+ catch (error) {
57
+ await handleError(config, error, "onStatusChanged");
58
+ }
59
+ }
60
+ async function handleError(config, error, context) {
61
+ if (!config.onError)
62
+ return;
63
+ try {
64
+ const err = error instanceof Error ? error : new Error("Unknown error");
65
+ await config.onError(err, `ActivationHandler.${context}`);
66
+ }
67
+ catch {
68
+ // Ignore callback errors
69
+ }
70
+ }
71
+ //# sourceMappingURL=ActivationHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivationHandler.js","sourceRoot":"","sources":["../../../src/infrastructure/services/ActivationHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAWpF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAA+B,EAC/B,MAAc,EACd,SAAiB,EACjB,SAAwB;IAExB,IAAI,CAAC;QACH,IAAI,OAAO,UAAU,KAAK,WAAW,IAAK,UAAkB,CAAC,OAAO,EAAE,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACrG,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,wBAAwB,CACpE,MAAM,EACN;YACE,SAAS,EAAE,IAAI;YACf,SAAS;YACT,SAAS;YACT,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACrC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CACF,CAAC;QAEF,MAAM,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;QACxD,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC;QACzD,MAAM,IAAI,2BAA2B,CAAC,iCAAiC,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA+B,EAC/B,MAAc;IAEd,IAAI,CAAC;QACH,IAAI,OAAO,UAAU,KAAK,WAAW,IAAK,UAAkB,CAAC,OAAO,EAAE,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,qDAAqD,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,wBAAwB,CACpE,MAAM,EACN;YACE,SAAS,EAAE,KAAK;YAChB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;SAChB,CACF,CAAC;QAEF,MAAM,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;QACxD,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;QAC3D,MAAM,IAAI,2BAA2B,CAAC,mCAAmC,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,MAA+B,EAC/B,MAAc,EACd,MAA0B;IAE1B,IAAI,CAAC,MAAM,CAAC,eAAe;QAAE,OAAO;IAEpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAA+B,EAC/B,KAAc,EACd,OAAe;IAEf,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO;IAE5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACxE,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,qBAAqB,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Subscription Service Implementation
3
+ * Database-first subscription management
4
+ */
5
+ import type { ISubscriptionService } from "../../application/ports/ISubscriptionService";
6
+ import type { SubscriptionStatus } from "../../domain/entities/SubscriptionStatus";
7
+ import type { SubscriptionConfig } from "../../domain/value-objects/SubscriptionConfig";
8
+ export declare class SubscriptionService implements ISubscriptionService {
9
+ private repository;
10
+ private handlerConfig;
11
+ constructor(config: SubscriptionConfig);
12
+ getSubscriptionStatus(userId: string): Promise<SubscriptionStatus>;
13
+ isPremium(userId: string): Promise<boolean>;
14
+ activateSubscription(userId: string, productId: string, expiresAt: string | null): Promise<SubscriptionStatus>;
15
+ deactivateSubscription(userId: string): Promise<SubscriptionStatus>;
16
+ updateSubscriptionStatus(userId: string, updates: Partial<SubscriptionStatus>): Promise<SubscriptionStatus>;
17
+ private handleError;
18
+ }
19
+ export declare function initializeSubscriptionService(config: SubscriptionConfig): SubscriptionService;
20
+ export declare function getSubscriptionService(): SubscriptionService | null;
21
+ export declare function resetSubscriptionService(): void;
22
+ //# sourceMappingURL=SubscriptionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionService.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/services/SubscriptionService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAMnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAOxF,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,aAAa,CAA0B;gBAEnC,MAAM,EAAE,kBAAkB;IAahC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyBlE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3C,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAYxB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAOnE,wBAAwB,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACnC,OAAO,CAAC,kBAAkB,CAAC;YA2BhB,WAAW;CAU1B;AAID,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,kBAAkB,GACzB,mBAAmB,CAKrB;AAED,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAMnE;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Subscription Service Implementation
3
+ * Database-first subscription management
4
+ */
5
+ import { createDefaultSubscriptionStatus } from "../../domain/entities/SubscriptionStatus";
6
+ import { SubscriptionRepositoryError, SubscriptionValidationError, } from "../../domain/errors/SubscriptionError";
7
+ import { activateSubscription, deactivateSubscription, } from "./ActivationHandler";
8
+ export class SubscriptionService {
9
+ constructor(config) {
10
+ if (!config.repository) {
11
+ throw new SubscriptionValidationError("Repository is required");
12
+ }
13
+ this.repository = config.repository;
14
+ this.handlerConfig = {
15
+ repository: config.repository,
16
+ onStatusChanged: config.onStatusChanged,
17
+ onError: config.onError,
18
+ };
19
+ }
20
+ async getSubscriptionStatus(userId) {
21
+ try {
22
+ const status = await this.repository.getSubscriptionStatus(userId);
23
+ if (!status) {
24
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
25
+ console.log("[Subscription] No status found for user, returning default");
26
+ }
27
+ return createDefaultSubscriptionStatus();
28
+ }
29
+ const isValid = this.repository.isSubscriptionValid(status);
30
+ if (!isValid && status.isPremium) {
31
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
32
+ console.log("[Subscription] Expired subscription found, deactivating");
33
+ }
34
+ return await this.deactivateSubscription(userId);
35
+ }
36
+ return status;
37
+ }
38
+ catch (error) {
39
+ await this.handleError(error, "getSubscriptionStatus");
40
+ return createDefaultSubscriptionStatus();
41
+ }
42
+ }
43
+ async isPremium(userId) {
44
+ const status = await this.getSubscriptionStatus(userId);
45
+ return this.repository.isSubscriptionValid(status);
46
+ }
47
+ async activateSubscription(userId, productId, expiresAt) {
48
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
49
+ console.log("[Subscription] Activating subscription", { userId, productId, expiresAt });
50
+ }
51
+ return activateSubscription(this.handlerConfig, userId, productId, expiresAt);
52
+ }
53
+ async deactivateSubscription(userId) {
54
+ if (typeof globalThis !== 'undefined' && globalThis.__DEV__) {
55
+ console.log("[Subscription] Deactivating subscription", { userId });
56
+ }
57
+ return deactivateSubscription(this.handlerConfig, userId);
58
+ }
59
+ async updateSubscriptionStatus(userId, updates) {
60
+ try {
61
+ const updatesWithSync = {
62
+ ...updates,
63
+ syncedAt: new Date().toISOString(),
64
+ };
65
+ const updatedStatus = await this.repository.updateSubscriptionStatus(userId, updatesWithSync);
66
+ if (this.handlerConfig.onStatusChanged) {
67
+ try {
68
+ await this.handlerConfig.onStatusChanged(userId, updatedStatus);
69
+ }
70
+ catch (error) {
71
+ await this.handleError(error, "updateSubscriptionStatus.callback");
72
+ }
73
+ }
74
+ return updatedStatus;
75
+ }
76
+ catch (error) {
77
+ await this.handleError(error, "updateSubscriptionStatus");
78
+ throw new SubscriptionRepositoryError("Failed to update subscription");
79
+ }
80
+ }
81
+ async handleError(error, context) {
82
+ if (!this.handlerConfig.onError)
83
+ return;
84
+ try {
85
+ const err = error instanceof Error ? error : new Error("Unknown error");
86
+ await this.handlerConfig.onError(err, `SubscriptionService.${context}`);
87
+ }
88
+ catch {
89
+ // Ignore callback errors
90
+ }
91
+ }
92
+ }
93
+ let subscriptionServiceInstance = null;
94
+ export function initializeSubscriptionService(config) {
95
+ if (!subscriptionServiceInstance) {
96
+ subscriptionServiceInstance = new SubscriptionService(config);
97
+ }
98
+ return subscriptionServiceInstance;
99
+ }
100
+ export function getSubscriptionService() {
101
+ if (!subscriptionServiceInstance && typeof globalThis !== 'undefined' && globalThis.__DEV__) {
102
+ // eslint-disable-next-line no-console
103
+ console.warn("[Subscription] Service not initialized");
104
+ }
105
+ return subscriptionServiceInstance;
106
+ }
107
+ export function resetSubscriptionService() {
108
+ subscriptionServiceInstance = null;
109
+ }
110
+ //# sourceMappingURL=SubscriptionService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionService.js","sourceRoot":"","sources":["../../../src/infrastructure/services/SubscriptionService.ts"],"names":[],"mappings":"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"}