@umituz/react-native-subscription 2.14.99 → 2.14.100
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.
- package/README.md +211 -394
- package/package.json +1 -1
- package/src/application/README.md +46 -225
- package/src/application/ports/README.md +42 -97
- package/src/domain/README.md +36 -384
- package/src/domain/constants/README.md +0 -56
- package/src/domain/entities/README.md +43 -169
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +50 -238
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +23 -376
- package/src/domains/config/domain/entities/README.md +34 -343
- package/src/domains/paywall/README.md +99 -369
- package/src/domains/paywall/components/README.md +34 -178
- package/src/domains/paywall/entities/README.md +34 -193
- package/src/domains/paywall/hooks/README.md +34 -122
- package/src/domains/wallet/README.md +34 -275
- package/src/domains/wallet/README.md.bak +209 -0
- package/src/domains/wallet/domain/README.md +34 -101
- package/src/domains/wallet/domain/entities/README.md +34 -115
- package/src/domains/wallet/domain/errors/README.md +34 -151
- package/src/domains/wallet/infrastructure/README.md +34 -89
- package/src/domains/wallet/presentation/components/README.md +34 -224
- package/src/domains/wallet/presentation/hooks/README.md +34 -248
- package/src/infrastructure/README.md +37 -496
- package/src/infrastructure/mappers/README.md +0 -13
- package/src/infrastructure/repositories/README.md +74 -360
- package/src/infrastructure/services/README.md +95 -370
- package/src/presentation/README.md +123 -408
- package/src/presentation/README.md.bak +172 -0
- package/src/presentation/components/README.md +151 -179
- package/src/presentation/components/README.md.bak +217 -0
- package/src/presentation/components/details/CreditRow.md +65 -310
- package/src/presentation/components/details/DetailRow.md +63 -255
- package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
- package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
- package/src/presentation/components/details/README.md +97 -447
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
- package/src/presentation/components/feedback/README.md +97 -445
- package/src/presentation/components/paywall/PaywallModal.md +66 -416
- package/src/presentation/components/paywall/README.md +50 -186
- package/src/presentation/components/sections/README.md +97 -466
- package/src/presentation/components/sections/SubscriptionSection.md +92 -244
- package/src/presentation/hooks/README.md +154 -741
- package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
- package/src/presentation/hooks/useAuthGate.md +61 -375
- package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
- package/src/presentation/hooks/useCreditChecker.md +73 -378
- package/src/presentation/hooks/useCredits.md +74 -313
- package/src/presentation/hooks/useCredits.md.bak +231 -0
- package/src/presentation/hooks/useCreditsGate.md +66 -318
- package/src/presentation/hooks/useDeductCredit.md +0 -76
- package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
- package/src/presentation/hooks/useFeatureGate.md +105 -150
- package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
- package/src/presentation/hooks/useInitializeCredits.md +64 -430
- package/src/presentation/hooks/usePaywall.md +61 -306
- package/src/presentation/hooks/usePaywallOperations.md +64 -458
- package/src/presentation/hooks/usePaywallVisibility.md +67 -316
- package/src/presentation/hooks/usePremium.md +84 -226
- package/src/presentation/hooks/usePremiumGate.md +60 -395
- package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
- package/src/presentation/hooks/useSubscription.md +66 -422
- package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
- package/src/presentation/hooks/useSubscriptionGate.md +80 -164
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
- package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
- package/src/presentation/hooks/useUserTier.md +63 -328
- package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
- package/src/presentation/screens/README.md +48 -190
- package/src/presentation/types/README.md +0 -16
- package/src/presentation/utils/README.md +0 -21
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +35 -150
- package/src/revenuecat/application/ports/README.md +34 -162
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +34 -176
- package/src/revenuecat/domain/entities/README.md +34 -374
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +34 -366
- package/src/revenuecat/domain/value-objects/README.md +34 -434
- package/src/revenuecat/infrastructure/README.md +34 -43
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +34 -211
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +35 -318
- package/src/revenuecat/infrastructure/utils/README.md +34 -375
- package/src/revenuecat/presentation/README.md +34 -176
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
|
@@ -1,157 +1,42 @@
|
|
|
1
1
|
# RevenueCat Application Layer
|
|
2
2
|
|
|
3
|
+
## Location
|
|
3
4
|
Application layer for RevenueCat integration, containing use cases and orchestration logic.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
## Use Cases
|
|
41
|
-
|
|
42
|
-
### Purchase Flow
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
async function purchasePremiumPackage(userId: string) {
|
|
46
|
-
const service = getRevenueCatService();
|
|
47
|
-
|
|
48
|
-
// 1. Get offerings
|
|
49
|
-
const offerings = await service.getOfferings();
|
|
50
|
-
const package = offerings.current?.monthly;
|
|
51
|
-
|
|
52
|
-
if (!package) {
|
|
53
|
-
throw new Error('No package available');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 2. Purchase
|
|
57
|
-
const result = await service.purchasePackage(package);
|
|
58
|
-
|
|
59
|
-
// 3. Handle result
|
|
60
|
-
if (result.error) {
|
|
61
|
-
throw new Error(result.error.message);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// 4. Update local state
|
|
65
|
-
await updateSubscriptionStatus(userId, result.customerInfo);
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Restore Purchases
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
async function restoreUserPurchases() {
|
|
73
|
-
const service = getRevenueCatService();
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const result = await service.restorePurchases();
|
|
77
|
-
|
|
78
|
-
if (result.error) {
|
|
79
|
-
throw new Error(result.error.message);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Update local subscription status
|
|
83
|
-
await updateSubscriptionStatusFromRestored(result.customerInfo);
|
|
84
|
-
|
|
85
|
-
return { success: true, customerInfo: result.customerInfo };
|
|
86
|
-
} catch (error) {
|
|
87
|
-
return { success: false, error };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Check Entitlement
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
async function checkPremiumAccess(userId: string): Promise<boolean> {
|
|
96
|
-
const service = getRevenueCatService();
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
const hasPremium = await service.checkEntitlement('premium');
|
|
100
|
-
|
|
101
|
-
if (hasPremium) {
|
|
102
|
-
await activatePremiumStatus(userId);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return hasPremium;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error('Failed to check entitlement:', error);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Best Practices
|
|
114
|
-
|
|
115
|
-
1. **Error Handling**: Always handle RevenueCat errors gracefully
|
|
116
|
-
2. **User ID**: Provide user ID when available for better tracking
|
|
117
|
-
3. **Entitlements**: Use entitlements instead of product IDs for flexibility
|
|
118
|
-
4. **Offerings**: Check if offerings are available before purchasing
|
|
119
|
-
5. **Validation**: Validate customer info after purchases
|
|
120
|
-
6. **Sync**: Keep local state synchronized with RevenueCat
|
|
121
|
-
7. **Timeouts**: Handle network timeouts appropriately
|
|
122
|
-
8. **Logging**: Log all RevenueCat operations for debugging
|
|
123
|
-
|
|
124
|
-
## Error Handling
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
import { PurchaseError } from '../domain/errors';
|
|
128
|
-
|
|
129
|
-
async function safePurchase(pkg: PurchasesPackage) {
|
|
130
|
-
try {
|
|
131
|
-
const result = await service.purchasePackage(pkg);
|
|
132
|
-
|
|
133
|
-
if (result.error) {
|
|
134
|
-
// Map RevenueCat errors to domain errors
|
|
135
|
-
if (result.error.code === 'PURCHASE_CANCELLED') {
|
|
136
|
-
throw new PurchaseError('User cancelled purchase');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
throw new PurchaseError(result.error.message);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return result;
|
|
143
|
-
} catch (error) {
|
|
144
|
-
if (error instanceof PurchaseError) {
|
|
145
|
-
throw error;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
throw new PurchaseError('Purchase failed', { cause: error });
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Related
|
|
154
|
-
|
|
6
|
+
## Strategy
|
|
7
|
+
This directory contains use cases and application-level operations for managing RevenueCat subscriptions and purchases with proper error handling and state synchronization.
|
|
8
|
+
|
|
9
|
+
## Restrictions
|
|
10
|
+
|
|
11
|
+
### REQUIRED
|
|
12
|
+
- Must handle RevenueCat errors gracefully
|
|
13
|
+
- Must provide user ID when available
|
|
14
|
+
- Must use entitlements instead of product IDs
|
|
15
|
+
- Must keep local state synchronized
|
|
16
|
+
|
|
17
|
+
### PROHIBITED
|
|
18
|
+
- DO NOT ignore RevenueCat errors
|
|
19
|
+
- DO NOT skip user ID provision
|
|
20
|
+
- DO NOT use product IDs directly
|
|
21
|
+
- DO NOT allow state desynchronization
|
|
22
|
+
|
|
23
|
+
### CRITICAL SAFETY
|
|
24
|
+
- All errors MUST be handled gracefully
|
|
25
|
+
- User IDs MUST be provided when available
|
|
26
|
+
- Entitlements MUST be used for flexibility
|
|
27
|
+
- Local state MUST stay synchronized
|
|
28
|
+
|
|
29
|
+
## AI Agent Guidelines
|
|
30
|
+
1. Always handle RevenueCat errors with proper recovery
|
|
31
|
+
2. Provide user ID when available for better tracking
|
|
32
|
+
3. Use entitlements instead of product IDs for flexibility
|
|
33
|
+
4. Check if offerings are available before purchasing
|
|
34
|
+
5. Validate customer info after purchases
|
|
35
|
+
6. Keep local state synchronized with RevenueCat
|
|
36
|
+
7. Handle network timeouts appropriately
|
|
37
|
+
8. Log all RevenueCat operations for debugging
|
|
38
|
+
|
|
39
|
+
## Related Documentation
|
|
155
40
|
- [RevenueCat Integration](../README.md)
|
|
156
41
|
- [RevenueCat Domain](../domain/README.md)
|
|
157
42
|
- [RevenueCat Infrastructure](../infrastructure/README.md)
|
|
@@ -1,169 +1,41 @@
|
|
|
1
1
|
# RevenueCat Application Ports
|
|
2
2
|
|
|
3
|
+
## Location
|
|
3
4
|
Interface definitions for RevenueCat service layer.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
checkEntitlement(entitlementId: string): Promise<boolean>;
|
|
39
|
-
checkEntitlementInfo(entitlementId: string): Promise<EntitlementInfo | null>;
|
|
40
|
-
|
|
41
|
-
// Subscriber Attributes
|
|
42
|
-
setAttributes(attributes: SubscriberAttributes): Promise<void>;
|
|
43
|
-
setEmail(email: string): Promise<void>;
|
|
44
|
-
setPhoneNumber(phoneNumber: string): Promise<void>;
|
|
45
|
-
|
|
46
|
-
// Log Out
|
|
47
|
-
logOut(): Promise<void>;
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### IRevenueCatPurchaseHandler
|
|
52
|
-
|
|
53
|
-
Handles purchase callbacks and results.
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
interface IRevenueCatPurchaseHandler {
|
|
57
|
-
onPurchaseStarted?(package: PurchasesPackage): void;
|
|
58
|
-
onPurchaseSuccess?(result: PurchaseResult): void;
|
|
59
|
-
onPurchaseError?(error: PurchaseError): void;
|
|
60
|
-
onPurchaseCancelled?(result: PurchaseResult): void;
|
|
61
|
-
onRestoreStarted?(): void;
|
|
62
|
-
onRestoreSuccess?(result: RestoreResult): void;
|
|
63
|
-
onRestoreError?(error: Error): void;
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### IRevenueCatCustomerInfoListener
|
|
68
|
-
|
|
69
|
-
Listens to customer info changes.
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
interface IRevenueCatCustomerInfoListener {
|
|
73
|
-
onCustomerInfoChanged(customerInfo: CustomerInfo): void;
|
|
74
|
-
onEntitlementsChanged(entitlements: EntitlementInfos): void;
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Usage
|
|
79
|
-
|
|
80
|
-
### Injecting Dependencies
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
import type { IRevenueCatService } from './ports/IRevenueCatService';
|
|
84
|
-
|
|
85
|
-
class PurchaseManager {
|
|
86
|
-
constructor(
|
|
87
|
-
private revenueCatService: IRevenueCatService
|
|
88
|
-
) {}
|
|
89
|
-
|
|
90
|
-
async purchasePremium() {
|
|
91
|
-
const offerings = await this.revenueCatService.getOfferings();
|
|
92
|
-
const package = offerings.current?.monthly;
|
|
93
|
-
|
|
94
|
-
if (!package) {
|
|
95
|
-
throw new Error('No package available');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return await this.revenueCatService.purchasePackage(package);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Implementing Ports
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
import type { IRevenueCatService } from './ports/IRevenueCatService';
|
|
107
|
-
import { Purchases } from '@revenuecat/purchases-capacitor';
|
|
108
|
-
|
|
109
|
-
class RevenueCatServiceImpl implements IRevenueCatService {
|
|
110
|
-
async configure(params: {
|
|
111
|
-
apiKey: string;
|
|
112
|
-
userId?: string;
|
|
113
|
-
observerMode?: boolean;
|
|
114
|
-
}): Promise<void> {
|
|
115
|
-
await Purchases.configure({
|
|
116
|
-
apiKey: params.apiKey,
|
|
117
|
-
appUserID: params.userId,
|
|
118
|
-
observerMode: params.observerMode ?? false,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async purchasePackage(pkg: PurchasesPackage): Promise<PurchaseResult> {
|
|
123
|
-
return await Purchases.purchasePackage({
|
|
124
|
-
aPackage: pkg,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ... other implementations
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Provide implementation
|
|
132
|
-
const revenueCatService: IRevenueCatService = new RevenueCatServiceImpl();
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Benefits of Ports
|
|
136
|
-
|
|
137
|
-
1. **Testability**: Easy to mock for testing
|
|
138
|
-
2. **Flexibility**: Can swap implementations
|
|
139
|
-
3. **Decoupling**: Application layer doesn't depend on concrete implementations
|
|
140
|
-
4. **Maintainability**: Clear contracts between layers
|
|
141
|
-
|
|
142
|
-
## Testing with Mocks
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import type { IRevenueCatService } from './ports/IRevenueCatService';
|
|
146
|
-
|
|
147
|
-
const mockRevenueCatService: IRevenueCatService = {
|
|
148
|
-
configure: vi.fn().mockResolvedValue(undefined),
|
|
149
|
-
purchasePackage: vi.fn().mockResolvedValue({
|
|
150
|
-
customerInfo: mockCustomerInfo,
|
|
151
|
-
}),
|
|
152
|
-
restorePurchases: vi.fn().mockResolvedValue({
|
|
153
|
-
customerInfo: mockCustomerInfo,
|
|
154
|
-
}),
|
|
155
|
-
getCustomerInfo: vi.fn().mockResolvedValue(mockCustomerInfo),
|
|
156
|
-
getOfferings: vi.fn().mockResolvedValue(mockOfferings),
|
|
157
|
-
checkEntitlement: vi.fn().mockResolvedValue(true),
|
|
158
|
-
// ... other methods
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// Use in tests
|
|
162
|
-
const manager = new PurchaseManager(mockRevenueCatService);
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Related
|
|
166
|
-
|
|
6
|
+
## Strategy
|
|
7
|
+
This directory defines the ports (interfaces) that the RevenueCat infrastructure must implement, following the Dependency Inversion Principle for testability and flexibility.
|
|
8
|
+
|
|
9
|
+
## Restrictions
|
|
10
|
+
|
|
11
|
+
### REQUIRED
|
|
12
|
+
- Must define clear interfaces for all operations
|
|
13
|
+
- Must support mocking for testing
|
|
14
|
+
- Must enable implementation swapping
|
|
15
|
+
- Must maintain contracts between layers
|
|
16
|
+
|
|
17
|
+
### PROHIBITED
|
|
18
|
+
- DO NOT depend on concrete implementations
|
|
19
|
+
- DO NOT create interfaces without clear purpose
|
|
20
|
+
- DO NOT break interface contracts
|
|
21
|
+
- DO NOT couple application to infrastructure
|
|
22
|
+
|
|
23
|
+
### CRITICAL SAFETY
|
|
24
|
+
- All dependencies MUST be inverted
|
|
25
|
+
- Interfaces MUST be clearly defined
|
|
26
|
+
- Implementations MUST be swappable
|
|
27
|
+
- Contracts MUST be maintained
|
|
28
|
+
|
|
29
|
+
## AI Agent Guidelines
|
|
30
|
+
1. Define clear interfaces for all RevenueCat operations
|
|
31
|
+
2. Design interfaces for easy mocking in tests
|
|
32
|
+
3. Enable implementation swapping when needed
|
|
33
|
+
4. Keep application layer decoupled from infrastructure
|
|
34
|
+
5. Maintain clear contracts between layers
|
|
35
|
+
6. Document interface behavior thoroughly
|
|
36
|
+
7. Test with mock implementations
|
|
37
|
+
|
|
38
|
+
## Related Documentation
|
|
167
39
|
- [RevenueCat Application Layer](../README.md)
|
|
168
40
|
- [RevenueCat Infrastructure](../infrastructure/README.md)
|
|
169
41
|
- [RevenueCat Domain](../domain/README.md)
|
|
@@ -2,146 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
Domain entities and types for RevenueCat integration.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
annual?: PackageInfo;
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### PackageInfo
|
|
51
|
-
Represents a purchasable package.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
interface PackageInfo {
|
|
55
|
-
identifier: string;
|
|
56
|
-
packageType: PackageType;
|
|
57
|
-
product: ProductInfo;
|
|
58
|
-
offeringIdentifier: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
interface ProductInfo {
|
|
62
|
-
identifier: string;
|
|
63
|
-
title: string;
|
|
64
|
-
description: string;
|
|
65
|
-
price: number;
|
|
66
|
-
pricePerMonth?: number;
|
|
67
|
-
currencyCode: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
type PackageType = 'WEEKLY' | 'MONTHLY' | 'THREE_MONTHLY' | 'SIX_MONTHLY' | 'ANNUAL' | 'LIFETIME';
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Constants
|
|
74
|
-
|
|
75
|
-
### Entitlement Identifiers
|
|
76
|
-
|
|
77
|
-
```typescript
|
|
78
|
-
export const ENTITLEMENT_IDS = {
|
|
79
|
-
PREMIUM: 'premium',
|
|
80
|
-
PRO: 'pro',
|
|
81
|
-
BASIC: 'basic',
|
|
82
|
-
} as const;
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Package Periods
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
export const PACKAGE_PERIODS = {
|
|
89
|
-
WEEKLY: 'weekly',
|
|
90
|
-
MONTHLY: 'monthly',
|
|
91
|
-
ANNUAL: 'annual',
|
|
92
|
-
LIFETIME: 'lifetime',
|
|
93
|
-
} as const;
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Helper Functions
|
|
97
|
-
|
|
98
|
-
### Get Package Period
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
function getPackagePeriod(packageType: PackageType): PackagePeriod {
|
|
102
|
-
const periodMap: Record<PackageType, PackagePeriod> = {
|
|
103
|
-
WEEKLY: 'monthly',
|
|
104
|
-
MONTHLY: 'monthly',
|
|
105
|
-
THREE_MONTHLY: 'monthly',
|
|
106
|
-
SIX_MONTHLY: 'monthly',
|
|
107
|
-
ANNUAL: 'annual',
|
|
108
|
-
LIFETIME: 'lifetime',
|
|
109
|
-
};
|
|
110
|
-
return periodMap[packageType];
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Calculate Price Per Month
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
function calculatePricePerMonth(packageInfo: PackageInfo): number | null {
|
|
118
|
-
if (!packageInfo.product.pricePerMonth) {
|
|
119
|
-
return packageInfo.product.price;
|
|
120
|
-
}
|
|
121
|
-
return packageInfo.product.pricePerMonth;
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Format Price
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
function formatPrice(price: number, currencyCode: string): string {
|
|
129
|
-
return new Intl.NumberFormat('en-US', {
|
|
130
|
-
style: 'currency',
|
|
131
|
-
currency: currencyCode,
|
|
132
|
-
}).format(price);
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Best Practices
|
|
137
|
-
|
|
138
|
-
1. **Type Mapping**: Map RevenueCat types to domain types
|
|
139
|
-
2. **Null Safety**: Handle optional properties safely
|
|
140
|
-
3. **Validation**: Validate RevenueCat data
|
|
141
|
-
4. **Formatting**: Format prices and dates consistently
|
|
142
|
-
5. **Constants**: Use constants for identifiers
|
|
143
|
-
|
|
144
|
-
## Related
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
`src/revenuecat/domain/`
|
|
8
|
+
|
|
9
|
+
## Strategy
|
|
10
|
+
|
|
11
|
+
Domain-specific entities representing RevenueCat concepts like entitlements, offerings, and packages, with proper type mapping and validation.
|
|
12
|
+
|
|
13
|
+
## Restrictions
|
|
14
|
+
|
|
15
|
+
### REQUIRED
|
|
16
|
+
|
|
17
|
+
- MUST map RevenueCat types to domain types
|
|
18
|
+
- MUST handle optional properties safely (null safety)
|
|
19
|
+
- MUST validate RevenueCat data
|
|
20
|
+
- MUST format prices and dates consistently
|
|
21
|
+
- MUST use constants for identifiers
|
|
22
|
+
|
|
23
|
+
### PROHIBITED
|
|
24
|
+
|
|
25
|
+
- MUST NOT expose RevenueCat implementation details to other layers
|
|
26
|
+
- MUST NOT leak RevenueCat SDK types outside this module
|
|
27
|
+
- MUST NOT assume all properties are present (null safety)
|
|
28
|
+
|
|
29
|
+
### CRITICAL
|
|
30
|
+
|
|
31
|
+
- Always validate RevenueCat data before use
|
|
32
|
+
- Handle all optional properties safely
|
|
33
|
+
- Use constants for all identifiers
|
|
34
|
+
- Maintain consistent formatting for prices and dates
|
|
35
|
+
|
|
36
|
+
## AI Agent Guidelines
|
|
37
|
+
|
|
38
|
+
When working with RevenueCat domain:
|
|
39
|
+
1. Type Mapping - map RevenueCat types to domain types
|
|
40
|
+
2. Null Safety - handle optional properties safely
|
|
41
|
+
3. Validation - validate RevenueCat data
|
|
42
|
+
4. Formatting - format prices and dates consistently
|
|
43
|
+
5. Constants - use constants for identifiers
|
|
44
|
+
|
|
45
|
+
## Related Documentation
|
|
145
46
|
|
|
146
47
|
- [RevenueCat README](../README.md)
|
|
147
|
-
- [Subscription Manager](
|
|
48
|
+
- [Subscription Manager](../../infrastructure/managers/README.md)
|