@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
|
@@ -2,196 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
Domain-specific errors for RevenueCat operations.
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
function getEntitlement(customerInfo: CustomerInfo, id: string): Entitlement {
|
|
53
|
-
const entitlement = customerInfo.entitlements.active[id];
|
|
54
|
-
if (!entitlement) {
|
|
55
|
-
throw new EntitlementNotFoundError(id);
|
|
56
|
-
}
|
|
57
|
-
return entitlement;
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### ConfigurationError
|
|
62
|
-
Thrown when RevenueCat configuration is invalid.
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
class ConfigurationError extends Error {
|
|
66
|
-
constructor(missingConfig: string[]) {
|
|
67
|
-
super(
|
|
68
|
-
`RevenueCat not configured: ${missingConfig.join(', ')}`,
|
|
69
|
-
'CONFIGURATION_ERROR'
|
|
70
|
-
);
|
|
71
|
-
this.name = 'ConfigurationError';
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**Usage:**
|
|
77
|
-
```typescript
|
|
78
|
-
function validateRevenueCatConfig(config: any) {
|
|
79
|
-
const required = ['apiKey'];
|
|
80
|
-
const missing = required.filter(key => !config[key]);
|
|
81
|
-
|
|
82
|
-
if (missing.length > 0) {
|
|
83
|
-
throw new ConfigurationError(missing);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### OfferingNotFoundError
|
|
89
|
-
Thrown when requested offering is not available.
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
class OfferingNotFoundError extends Error {
|
|
93
|
-
constructor(public offeringId: string) {
|
|
94
|
-
super(
|
|
95
|
-
`Offering not found: ${offeringId}`,
|
|
96
|
-
'OFFERING_NOT_FOUND'
|
|
97
|
-
);
|
|
98
|
-
this.name = 'OfferingNotFoundError';
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Error Handling Pattern
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
import {
|
|
107
|
-
PurchaseError,
|
|
108
|
-
EntitlementNotFoundError,
|
|
109
|
-
ConfigurationError
|
|
110
|
-
} from './errors';
|
|
111
|
-
|
|
112
|
-
async function handlePurchase(package: Package) {
|
|
113
|
-
try {
|
|
114
|
-
const result = await Purchases.purchasePackage(package);
|
|
115
|
-
return { success: true, result };
|
|
116
|
-
} catch (error) {
|
|
117
|
-
if (error instanceof UserCancelledError) {
|
|
118
|
-
// User cancelled - not really an error
|
|
119
|
-
return { success: false, cancelled: true };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (error instanceof PurchaseError) {
|
|
123
|
-
switch (error.code) {
|
|
124
|
-
case 'PURCHASE_CANCELLED':
|
|
125
|
-
analytics.track('purchase_cancelled');
|
|
126
|
-
break;
|
|
127
|
-
case 'NETWORK_ERROR':
|
|
128
|
-
showRetryDialog();
|
|
129
|
-
break;
|
|
130
|
-
case 'STORE_PROBLEM':
|
|
131
|
-
showStoreProblemDialog();
|
|
132
|
-
break;
|
|
133
|
-
default:
|
|
134
|
-
showErrorDialog(error.message);
|
|
135
|
-
}
|
|
136
|
-
return { success: false, error };
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Unexpected error
|
|
140
|
-
console.error('Unexpected purchase error:', error);
|
|
141
|
-
return { success: false, error };
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Error Recovery
|
|
147
|
-
|
|
148
|
-
### Retry Logic
|
|
149
|
-
```typescript
|
|
150
|
-
async function purchaseWithRetry(pkg: Package, maxRetries = 3) {
|
|
151
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
152
|
-
try {
|
|
153
|
-
const result = await Purchases.purchasePackage(pkg);
|
|
154
|
-
return result;
|
|
155
|
-
} catch (error) {
|
|
156
|
-
if (error instanceof PurchaseError) {
|
|
157
|
-
if (error.code === 'NETWORK_ERROR' && i < maxRetries - 1) {
|
|
158
|
-
await delay(1000 * (i + 1)); // Exponential backoff
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
throw error;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### User-Friendly Messages
|
|
169
|
-
```typescript
|
|
170
|
-
function getUserFriendlyMessage(error: Error): string {
|
|
171
|
-
if (error instanceof PurchaseError) {
|
|
172
|
-
const messages: Record<string, string> = {
|
|
173
|
-
PURCHASE_CANCELLED: 'Purchase was cancelled',
|
|
174
|
-
NETWORK_ERROR: 'Network error. Please check your connection.',
|
|
175
|
-
STORE_PROBLEM: 'There was an issue with the app store.',
|
|
176
|
-
PURCHASE_INVALID: 'Purchase data is invalid.',
|
|
177
|
-
};
|
|
178
|
-
return messages[error.code] || 'An error occurred';
|
|
179
|
-
}
|
|
180
|
-
return error.message;
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Best Practices
|
|
185
|
-
|
|
186
|
-
1. **Specific Errors**: Use specific error types
|
|
187
|
-
2. **Error Codes**: Include machine-readable codes
|
|
188
|
-
3. **Context**: Include relevant data in error
|
|
189
|
-
4. **Recovery**: Implement recovery strategies
|
|
190
|
-
5. **User Feedback**: Convert errors to user-friendly messages
|
|
191
|
-
6. **Logging**: Log errors for debugging
|
|
192
|
-
7. **Analytics**: Track errors for monitoring
|
|
193
|
-
|
|
194
|
-
## Related
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
`src/revenuecat/domain/errors/`
|
|
8
|
+
|
|
9
|
+
## Strategy
|
|
10
|
+
|
|
11
|
+
Custom error classes for RevenueCat-specific error conditions, providing typed error handling for purchase, entitlement, configuration, and offering failures.
|
|
12
|
+
|
|
13
|
+
## Restrictions
|
|
14
|
+
|
|
15
|
+
### REQUIRED
|
|
16
|
+
|
|
17
|
+
- MUST use specific error types (not generic errors)
|
|
18
|
+
- MUST include machine-readable error codes
|
|
19
|
+
- MUST include relevant contextual data
|
|
20
|
+
- MUST implement recovery strategies
|
|
21
|
+
- MUST convert errors to user-friendly messages
|
|
22
|
+
- MUST log errors for debugging
|
|
23
|
+
- MUST track errors for analytics
|
|
24
|
+
|
|
25
|
+
### PROHIBITED
|
|
26
|
+
|
|
27
|
+
- MUST NOT expose sensitive RevenueCat API keys or tokens
|
|
28
|
+
- MUST NOT leak raw RevenueCat errors to users
|
|
29
|
+
- MUST NOT ignore error conditions
|
|
30
|
+
|
|
31
|
+
### CRITICAL
|
|
32
|
+
|
|
33
|
+
- Always implement specific error types
|
|
34
|
+
- Include machine-readable codes for programmatic handling
|
|
35
|
+
- Provide recovery strategies where applicable
|
|
36
|
+
- Convert technical errors to user-friendly messages
|
|
37
|
+
- Log all errors for debugging and monitoring
|
|
38
|
+
|
|
39
|
+
## AI Agent Guidelines
|
|
40
|
+
|
|
41
|
+
When working with RevenueCat errors:
|
|
42
|
+
1. Specific Errors - use specific error types
|
|
43
|
+
2. Error Codes - include machine-readable codes
|
|
44
|
+
3. Context - include relevant data in error
|
|
45
|
+
4. Recovery - implement recovery strategies
|
|
46
|
+
5. User Feedback - convert errors to user-friendly messages
|
|
47
|
+
6. Logging - log errors for debugging
|
|
48
|
+
7. Analytics - track errors for monitoring
|
|
49
|
+
|
|
50
|
+
## Related Documentation
|
|
195
51
|
|
|
196
52
|
- [RevenueCat Domain](../README.md)
|
|
197
|
-
- [RevenueCat Services](
|
|
53
|
+
- [RevenueCat Services](../../infrastructure/services/README.md)
|
|
@@ -1,373 +1,41 @@
|
|
|
1
1
|
# RevenueCat Domain Types
|
|
2
2
|
|
|
3
|
+
## Location
|
|
3
4
|
Type definitions and type utilities for RevenueCat integration.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
| 'PRODUCT_ALREADY_OWNED'
|
|
39
|
-
| 'RECEIPT_ALREADY_IN_USE'
|
|
40
|
-
| 'INVALID_OFFERINGS_ERROR'
|
|
41
|
-
| 'INVALID_ELIGIBILITY_ERROR'
|
|
42
|
-
| 'INELIGIBLE_FOR_INTRO_PRICING'
|
|
43
|
-
| 'EXPIRED_RECEIPT_ERROR';
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### PackageType
|
|
47
|
-
|
|
48
|
-
Available package types.
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
type PackageType =
|
|
52
|
-
| 'monthly'
|
|
53
|
-
| 'annual'
|
|
54
|
-
| 'lifetime'
|
|
55
|
-
| 'weekly'
|
|
56
|
-
| 'single_purchase';
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### ProductType
|
|
60
|
-
|
|
61
|
-
Types of products.
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
type ProductType =
|
|
65
|
-
| 'subscription'
|
|
66
|
-
| 'non_subscription'
|
|
67
|
-
| 'consumable';
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### PeriodType
|
|
71
|
-
|
|
72
|
-
Subscription period types.
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
type PeriodType =
|
|
76
|
-
| 'normal'
|
|
77
|
-
| 'trial'
|
|
78
|
-
| 'intro';
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Store
|
|
82
|
-
|
|
83
|
-
Available app stores.
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
type Store =
|
|
87
|
-
| 'app_store'
|
|
88
|
-
| 'play_store'
|
|
89
|
-
| 'stripe'
|
|
90
|
-
| 'mac_app_store'
|
|
91
|
-
| 'play_store_amazon'
|
|
92
|
-
| 'promotional';
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### SubscriptionStatus
|
|
96
|
-
|
|
97
|
-
Subscription status representation.
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
type SubscriptionStatus =
|
|
101
|
-
| 'active'
|
|
102
|
-
| 'expired'
|
|
103
|
-
| 'cancelled'
|
|
104
|
-
| 'in_billing_retry'
|
|
105
|
-
| 'paused';
|
|
106
|
-
|
|
107
|
-
interface SubscriptionInfo {
|
|
108
|
-
status: SubscriptionStatus;
|
|
109
|
-
expiresAt: Date | null;
|
|
110
|
-
willRenew: boolean;
|
|
111
|
-
periodType: PeriodType;
|
|
112
|
-
isTrial: boolean;
|
|
113
|
-
isIntro: boolean;
|
|
114
|
-
isSandbox: boolean;
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Type Guards
|
|
119
|
-
|
|
120
|
-
### isPurchasesError
|
|
121
|
-
|
|
122
|
-
Check if an error is a PurchasesError.
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
function isPurchasesError(error: unknown): error is PurchasesError {
|
|
126
|
-
return (
|
|
127
|
-
typeof error === 'object' &&
|
|
128
|
-
error !== null &&
|
|
129
|
-
'code' in error &&
|
|
130
|
-
'message' in error
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### isActiveEntitlement
|
|
136
|
-
|
|
137
|
-
Check if entitlement is active.
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
function isActiveEntitlement(
|
|
141
|
-
entitlement: EntitlementInfo | null
|
|
142
|
-
): entitlement is EntitlementInfo & { isActive: true } {
|
|
143
|
-
return entitlement?.isActive === true;
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### isSubscriptionProduct
|
|
148
|
-
|
|
149
|
-
Check if product is a subscription.
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
function isSubscriptionProduct(
|
|
153
|
-
product: Product
|
|
154
|
-
): product is Product & { type: 'subscription' } {
|
|
155
|
-
return product.type === 'subscription';
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### isConsumableProduct
|
|
160
|
-
|
|
161
|
-
Check if product is consumable.
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
function isConsumableProduct(
|
|
165
|
-
product: Product
|
|
166
|
-
): product is Product & { type: 'consumable' } {
|
|
167
|
-
return product.type === 'consumable';
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## Utility Types
|
|
172
|
-
|
|
173
|
-
### PurchaseResult
|
|
174
|
-
|
|
175
|
-
Result of a purchase operation.
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
type PurchaseResult =
|
|
179
|
-
| { success: true; customerInfo: CustomerInfo; transaction: Transaction }
|
|
180
|
-
| { success: false; error: PurchasesError };
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### RestoreResult
|
|
184
|
-
|
|
185
|
-
Result of a restore operation.
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
type RestoreResult =
|
|
189
|
-
| { success: true; customerInfo: CustomerInfo }
|
|
190
|
-
| { success: false; error: PurchasesError };
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### EntitlementCheckResult
|
|
194
|
-
|
|
195
|
-
Result of checking an entitlement.
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
type EntitlementCheckResult =
|
|
199
|
-
| { hasAccess: true; entitlement: EntitlementInfo }
|
|
200
|
-
| { hasAccess: false; reason: 'not_entitled' | 'expired' | 'cancelled' };
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### OfferingConfig
|
|
204
|
-
|
|
205
|
-
Configuration for an offering.
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
interface OfferingConfig {
|
|
209
|
-
identifier: string;
|
|
210
|
-
metadata?: {
|
|
211
|
-
highlight?: boolean;
|
|
212
|
-
recommended?: boolean;
|
|
213
|
-
discount_percentage?: number;
|
|
214
|
-
features?: string[];
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### PurchaseConfig
|
|
220
|
-
|
|
221
|
-
Configuration for purchase flow.
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
interface PurchaseConfig {
|
|
225
|
-
onPurchaseStarted?: () => void;
|
|
226
|
-
onPurchaseSuccess?: (result: PurchaseResult) => void;
|
|
227
|
-
onPurchaseError?: (error: PurchasesError) => void;
|
|
228
|
-
onPurchaseCancelled?: () => void;
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Usage Examples
|
|
233
|
-
|
|
234
|
-
### Using Type Guards
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
import { isPurchasesError, isActiveEntitlement } from './types';
|
|
238
|
-
|
|
239
|
-
try {
|
|
240
|
-
const result = await purchasePackage(pkg);
|
|
241
|
-
} catch (error) {
|
|
242
|
-
if (isPurchasesError(error)) {
|
|
243
|
-
// Now TypeScript knows error is PurchasesError
|
|
244
|
-
console.error('Error code:', error.code);
|
|
245
|
-
console.error('Message:', error.message);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Checking entitlements
|
|
250
|
-
const premium = customerInfo.entitlements.premium;
|
|
251
|
-
if (isActiveEntitlement(premium)) {
|
|
252
|
-
// TypeScript knows premium is active
|
|
253
|
-
console.log('Premium expires:', premium.expirationDate);
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Using Utility Types
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
async function handlePurchase(
|
|
261
|
-
pkg: Package
|
|
262
|
-
): Promise<PurchaseResult> {
|
|
263
|
-
try {
|
|
264
|
-
const result = await revenueCatService.purchasePackage(pkg);
|
|
265
|
-
return {
|
|
266
|
-
success: true,
|
|
267
|
-
customerInfo: result.customerInfo,
|
|
268
|
-
transaction: result.transaction,
|
|
269
|
-
};
|
|
270
|
-
} catch (error) {
|
|
271
|
-
if (isPurchasesError(error)) {
|
|
272
|
-
return {
|
|
273
|
-
success: false,
|
|
274
|
-
error,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
throw error;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Usage
|
|
282
|
-
const result = await handlePurchase(selectedPackage);
|
|
283
|
-
|
|
284
|
-
if (result.success) {
|
|
285
|
-
console.log('Purchased:', result.transaction?.transactionIdentifier);
|
|
286
|
-
} else {
|
|
287
|
-
console.error('Failed:', result.error.message);
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Checking Entitlements
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
function checkEntitlement(
|
|
295
|
-
customerInfo: CustomerInfo,
|
|
296
|
-
entitlementId: string
|
|
297
|
-
): EntitlementCheckResult {
|
|
298
|
-
const entitlement = customerInfo.entitlements[entitlementId];
|
|
299
|
-
|
|
300
|
-
if (!entitlement) {
|
|
301
|
-
return { hasAccess: false, reason: 'not_entitled' };
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (!entitlement.isActive) {
|
|
305
|
-
if (entitlement.expirationDate && entitlement.expirationDate < new Date()) {
|
|
306
|
-
return { hasAccess: false, reason: 'expired' };
|
|
307
|
-
}
|
|
308
|
-
if (entitlement.unsubscribeDetectedAt) {
|
|
309
|
-
return { hasAccess: false, reason: 'cancelled' };
|
|
310
|
-
}
|
|
311
|
-
return { hasAccess: false, reason: 'not_entitled' };
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
return { hasAccess: true, entitlement };
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Usage
|
|
318
|
-
const check = checkEntitlement(customerInfo, 'premium');
|
|
319
|
-
|
|
320
|
-
if (check.hasAccess) {
|
|
321
|
-
console.log('Premium active');
|
|
322
|
-
} else {
|
|
323
|
-
console.log('Reason:', check.reason);
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Type Assertions
|
|
328
|
-
|
|
329
|
-
### Assert Subscription Status
|
|
330
|
-
|
|
331
|
-
```typescript
|
|
332
|
-
function getSubscriptionStatus(
|
|
333
|
-
entitlement: EntitlementInfo | null
|
|
334
|
-
): SubscriptionStatus {
|
|
335
|
-
if (!entitlement || !entitlement.isActive) {
|
|
336
|
-
return 'expired';
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (entitlement.billingIssueDetectedAt) {
|
|
340
|
-
return 'in_billing_retry';
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (entitlement.unsubscribeDetectedAt && !entitlement.willRenew) {
|
|
344
|
-
return 'cancelled';
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return 'active';
|
|
348
|
-
}
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### Assert Product Type
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
function getProductPrice(
|
|
355
|
-
product: Product
|
|
356
|
-
): string | null {
|
|
357
|
-
if (isSubscriptionProduct(product)) {
|
|
358
|
-
return product.price.formattedPrice;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (isConsumableProduct(product)) {
|
|
362
|
-
return product.price.formattedPrice;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return null;
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Related
|
|
370
|
-
|
|
6
|
+
## Strategy
|
|
7
|
+
This directory contains TypeScript type definitions, type guards, and utility types used throughout the RevenueCat integration for type safety and compile-time checks.
|
|
8
|
+
|
|
9
|
+
## Restrictions
|
|
10
|
+
|
|
11
|
+
### REQUIRED
|
|
12
|
+
- Must use type guards for runtime checks
|
|
13
|
+
- Must provide utility types for common operations
|
|
14
|
+
- Must maintain type safety throughout
|
|
15
|
+
- Must use strict TypeScript types
|
|
16
|
+
|
|
17
|
+
### PROHIBITED
|
|
18
|
+
- DO NOT use `any` type
|
|
19
|
+
- DO NOT bypass type guards
|
|
20
|
+
- DO NOT ignore type safety
|
|
21
|
+
- DO NOT use loose type definitions
|
|
22
|
+
|
|
23
|
+
### CRITICAL SAFETY
|
|
24
|
+
- All type checks MUST use type guards
|
|
25
|
+
- All types MUST be strictly defined
|
|
26
|
+
- Type assertions MUST be safe
|
|
27
|
+
- Utility types MUST be used appropriately
|
|
28
|
+
|
|
29
|
+
## AI Agent Guidelines
|
|
30
|
+
1. Use type guards for runtime type checking
|
|
31
|
+
2. Define utility types for common operations
|
|
32
|
+
3. Maintain strict type safety throughout codebase
|
|
33
|
+
4. Provide clear type definitions for all RevenueCat concepts
|
|
34
|
+
5. Use type assertions only when safe
|
|
35
|
+
6. Test type guards thoroughly
|
|
36
|
+
7. Document complex types with comments
|
|
37
|
+
|
|
38
|
+
## Related Documentation
|
|
371
39
|
- [RevenueCat Domain](../README.md)
|
|
372
40
|
- [RevenueCat Entities](../entities/README.md)
|
|
373
41
|
- [RevenueCat Value Objects](../value-objects/README.md)
|