@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.
Files changed (92) hide show
  1. package/README.md +211 -394
  2. package/package.json +1 -1
  3. package/src/application/README.md +46 -225
  4. package/src/application/ports/README.md +42 -97
  5. package/src/domain/README.md +36 -384
  6. package/src/domain/constants/README.md +0 -56
  7. package/src/domain/entities/README.md +43 -169
  8. package/src/domain/errors/README.md +33 -287
  9. package/src/domain/value-objects/README.md +43 -179
  10. package/src/domains/README.md +50 -238
  11. package/src/domains/README.md.bak +274 -0
  12. package/src/domains/config/README.md +93 -383
  13. package/src/domains/config/domain/README.md +23 -376
  14. package/src/domains/config/domain/entities/README.md +34 -343
  15. package/src/domains/paywall/README.md +99 -369
  16. package/src/domains/paywall/components/README.md +34 -178
  17. package/src/domains/paywall/entities/README.md +34 -193
  18. package/src/domains/paywall/hooks/README.md +34 -122
  19. package/src/domains/wallet/README.md +34 -275
  20. package/src/domains/wallet/README.md.bak +209 -0
  21. package/src/domains/wallet/domain/README.md +34 -101
  22. package/src/domains/wallet/domain/entities/README.md +34 -115
  23. package/src/domains/wallet/domain/errors/README.md +34 -151
  24. package/src/domains/wallet/infrastructure/README.md +34 -89
  25. package/src/domains/wallet/presentation/components/README.md +34 -224
  26. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  27. package/src/infrastructure/README.md +37 -496
  28. package/src/infrastructure/mappers/README.md +0 -13
  29. package/src/infrastructure/repositories/README.md +74 -360
  30. package/src/infrastructure/services/README.md +95 -370
  31. package/src/presentation/README.md +123 -408
  32. package/src/presentation/README.md.bak +172 -0
  33. package/src/presentation/components/README.md +151 -179
  34. package/src/presentation/components/README.md.bak +217 -0
  35. package/src/presentation/components/details/CreditRow.md +65 -310
  36. package/src/presentation/components/details/DetailRow.md +63 -255
  37. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  38. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  39. package/src/presentation/components/details/README.md +97 -447
  40. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  41. package/src/presentation/components/feedback/README.md +97 -445
  42. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  43. package/src/presentation/components/paywall/README.md +50 -186
  44. package/src/presentation/components/sections/README.md +97 -466
  45. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  46. package/src/presentation/hooks/README.md +154 -741
  47. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  48. package/src/presentation/hooks/useAuthGate.md +61 -375
  49. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  50. package/src/presentation/hooks/useCreditChecker.md +73 -378
  51. package/src/presentation/hooks/useCredits.md +74 -313
  52. package/src/presentation/hooks/useCredits.md.bak +231 -0
  53. package/src/presentation/hooks/useCreditsGate.md +66 -318
  54. package/src/presentation/hooks/useDeductCredit.md +0 -76
  55. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  56. package/src/presentation/hooks/useFeatureGate.md +105 -150
  57. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  58. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  59. package/src/presentation/hooks/usePaywall.md +61 -306
  60. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  61. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  62. package/src/presentation/hooks/usePremium.md +84 -226
  63. package/src/presentation/hooks/usePremiumGate.md +60 -395
  64. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  65. package/src/presentation/hooks/useSubscription.md +66 -422
  66. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  67. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  68. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  69. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  70. package/src/presentation/hooks/useUserTier.md +63 -328
  71. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  72. package/src/presentation/screens/README.md +48 -190
  73. package/src/presentation/types/README.md +0 -16
  74. package/src/presentation/utils/README.md +0 -21
  75. package/src/revenuecat/README.md +99 -518
  76. package/src/revenuecat/application/README.md +35 -150
  77. package/src/revenuecat/application/ports/README.md +34 -162
  78. package/src/revenuecat/domain/README.md +42 -141
  79. package/src/revenuecat/domain/constants/README.md +34 -176
  80. package/src/revenuecat/domain/entities/README.md +34 -374
  81. package/src/revenuecat/domain/errors/README.md +47 -191
  82. package/src/revenuecat/domain/types/README.md +34 -366
  83. package/src/revenuecat/domain/value-objects/README.md +34 -434
  84. package/src/revenuecat/infrastructure/README.md +34 -43
  85. package/src/revenuecat/infrastructure/config/README.md +32 -23
  86. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  87. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  88. package/src/revenuecat/infrastructure/services/README.md +35 -318
  89. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  90. package/src/revenuecat/presentation/README.md +34 -176
  91. package/src/revenuecat/presentation/hooks/README.md +29 -35
  92. package/src/utils/README.md +38 -525
@@ -2,175 +2,49 @@
2
2
 
3
3
  Core domain entities for subscription management.
4
4
 
5
- ## Purpose
6
-
7
- Domain entities represent the core business concepts and rules of the subscription system. They are framework-agnostic and contain only business logic.
8
-
9
- ## Entities
10
-
11
- ### SubscriptionStatus
12
-
13
- Represents the subscription state of a user.
14
-
15
- ```typescript
16
- interface SubscriptionStatus {
17
- type: SubscriptionStatusType;
18
- isActive: boolean;
19
- isPremium: boolean;
20
- expirationDate: string | null;
21
- willRenew: boolean;
22
- productId?: string;
23
- }
24
-
25
- type SubscriptionStatusType =
26
- | 'unknown'
27
- | 'guest'
28
- | 'free'
29
- | 'premium';
30
- ```
31
-
32
- **Usage:**
33
- ```typescript
34
- import { SubscriptionStatus } from '@umituz/react-native-subscription/domain';
35
-
36
- const status = SubscriptionStatus.create({
37
- type: 'premium',
38
- isActive: true,
39
- isPremium: true,
40
- expirationDate: '2025-12-31',
41
- willRenew: true,
42
- });
43
- ```
44
-
45
- ## Design Principles
46
-
47
- ### 1. Self-Validation
48
-
49
- Entities validate themselves on creation:
50
-
51
- ```typescript
52
- class SubscriptionStatus {
53
- private constructor(data: SubscriptionStatusData) {
54
- this.validate(data);
55
- // ...
56
- }
57
-
58
- private validate(data: SubscriptionStatusData): void {
59
- if (data.isPremium && !data.isActive) {
60
- throw new ValidationError('Premium users must be active');
61
- }
62
- }
63
- }
64
- ```
65
-
66
- ### 2. Immutable State
67
-
68
- Entities cannot be modified after creation:
69
-
70
- ```typescript
71
- const status = SubscriptionStatus.create({...});
72
- // status.isActive = false; // Error: Cannot assign to read-only property
73
- ```
74
-
75
- ### 3. Business Rules
76
-
77
- Business logic is encapsulated in entities:
78
-
79
- ```typescript
80
- class SubscriptionStatus {
81
- isExpired(): boolean {
82
- if (!this.expirationDate) return false;
83
- return new Date(this.expirationDate) < new Date();
84
- }
85
-
86
- requiresRenewal(): boolean {
87
- return this.isPremium && this.expirationDate && this.willRenew;
88
- }
89
- }
90
- ```
91
-
92
- ## Creating Entities
93
-
94
- ### Factory Method
95
-
96
- ```typescript
97
- const status = SubscriptionStatus.create({
98
- type: 'premium',
99
- isActive: true,
100
- isPremium: true,
101
- expirationDate: null,
102
- willRenew: false,
103
- });
104
- ```
105
-
106
- ### Validation
107
-
108
- ```typescript
109
- try {
110
- const status = SubscriptionStatus.create({
111
- type: 'premium',
112
- isActive: false, // Invalid!
113
- isPremium: true,
114
- });
115
- } catch (error) {
116
- console.error('Validation failed:', error.message);
117
- }
118
- ```
119
-
120
- ## Domain Services
121
-
122
- Business operations that don't naturally fit in entities:
123
-
124
- ```typescript
125
- class SubscriptionDomainService {
126
- canUpgrade(currentStatus: SubscriptionStatus): boolean {
127
- return !currentStatus.isPremium;
128
- }
129
-
130
- calculateDaysUntilExpiry(status: SubscriptionStatus): number | null {
131
- if (!status.expirationDate) return null;
132
- const diff = new Date(status.expirationDate).getTime() - Date.now();
133
- return Math.ceil(diff / (1000 * 60 * 60 * 24));
134
- }
135
- }
136
- ```
137
-
138
- ## Best Practices
139
-
140
- 1. **Keep entities pure** - No framework dependencies
141
- 2. **Validate invariants** - Ensure valid state
142
- 3. **Use value objects** - For complex attributes
143
- 4. **Encapsulate logic** - Keep business rules inside entities
144
- 5. **Make immutable** - Prevent direct state modification
145
-
146
- ## Testing
147
-
148
- ```typescript
149
- describe('SubscriptionStatus', () => {
150
- it('should create valid premium status', () => {
151
- const status = SubscriptionStatus.create({
152
- type: 'premium',
153
- isActive: true,
154
- isPremium: true,
155
- });
156
-
157
- expect(status.isPremium).toBe(true);
158
- });
159
-
160
- it('should reject invalid premium status', () => {
161
- expect(() => {
162
- SubscriptionStatus.create({
163
- type: 'premium',
164
- isActive: false,
165
- isPremium: true,
166
- });
167
- }).toThrow();
168
- });
169
- });
170
- ```
171
-
172
- ## Related
5
+ ## Location
6
+
7
+ `src/domain/entities/`
8
+
9
+ ## Strategy
10
+
11
+ Domain entities represent the core business concepts and rules of the subscription system. They are framework-agnostic and contain only business logic, ensuring pure domain modeling.
12
+
13
+ ## Restrictions
14
+
15
+ ### REQUIRED
16
+
17
+ - MUST validate themselves on creation
18
+ - MUST remain immutable after creation
19
+ - MUST encapsulate business logic internally
20
+ - MUST use value objects for complex attributes
21
+ - MUST be framework-agnostic
22
+
23
+ ### PROHIBITED
24
+
25
+ - MUST NOT have framework dependencies
26
+ - MUST NOT expose internal state directly
27
+ - MUST NOT allow direct state modification
28
+ - MUST NOT contain infrastructure concerns
29
+
30
+ ### CRITICAL
31
+
32
+ - Always validate invariants to ensure valid state
33
+ - Prevent direct state modification through immutability
34
+ - Keep business rules encapsulated within entities
35
+ - Maintain purity - no external dependencies
36
+
37
+ ## AI Agent Guidelines
38
+
39
+ When working with domain entities:
40
+ 1. Keep entities pure - no framework dependencies
41
+ 2. Validate invariants - ensure valid state
42
+ 3. Use value objects - for complex attributes
43
+ 4. Encapsulate logic - keep business rules inside entities
44
+ 5. Make immutable - prevent direct state modification
45
+
46
+ ## Related Documentation
173
47
 
174
48
  - [Value Objects](../value-objects/README.md)
175
49
  - [Domain Errors](../errors/README.md)
176
- - [Domain Layer](../../README.md)
50
+ - [Domain Layer](../README.md)
@@ -2,306 +2,52 @@
2
2
 
3
3
  Domain-specific error types for subscription system.
4
4
 
5
- ## Purpose
5
+ ## Location
6
6
 
7
- Domain errors provide typed, contextual error handling for business logic failures. They make error handling explicit and type-safe.
7
+ `src/domain/errors/`
8
8
 
9
- ## Error Hierarchy
9
+ ## Strategy
10
10
 
11
- ```
12
- Error (JavaScript)
13
- └── SubscriptionError (Domain base)
14
- ├── SubscriptionValidationError
15
- ├── SubscriptionRepositoryError
16
- ├── SubscriptionOperationError
17
- └── InsufficientCreditsError
18
- ```
11
+ Domain errors provide typed, contextual error handling for business logic failures. They make error handling explicit and type-safe, enabling precise error management.
19
12
 
20
- ## Error Types
13
+ ## Restrictions
21
14
 
22
- ### SubscriptionError
15
+ ### REQUIRED
23
16
 
24
- Base error for all subscription-related errors.
17
+ - MUST use specific error types (not generic Error)
18
+ - MUST include contextual information
19
+ - MUST document all error codes
20
+ - MUST handle errors gracefully with user-friendly messages
21
+ - MUST log errors for debugging
22
+ - MUST use type guards for type-safe error handling
25
23
 
26
- ```typescript
27
- class SubscriptionError extends Error {
28
- constructor(
29
- message: string,
30
- public readonly code: string,
31
- public readonly context?: Record<string, any>
32
- ) {
33
- super(message);
34
- this.name = 'SubscriptionError';
35
- }
36
- }
37
- ```
24
+ ### PROHIBITED
38
25
 
39
- ### SubscriptionValidationError
26
+ - MUST NOT swallow errors without handling
27
+ - MUST NOT use generic Error class
28
+ - MUST NOT expose sensitive information in error messages
29
+ - MUST NOT ignore error conditions
40
30
 
41
- Thrown when validation fails.
31
+ ### CRITICAL
42
32
 
43
- ```typescript
44
- throw new SubscriptionValidationError('Invalid user ID');
45
- ```
33
+ - Always handle or rethrow errors
34
+ - Include relevant context in error objects
35
+ - Use type guards to enable type-safe error handling
36
+ - Show user-friendly messages while logging technical details
46
37
 
47
- ### SubscriptionRepositoryError
38
+ ## AI Agent Guidelines
48
39
 
49
- Thrown when repository operations fail.
40
+ When working with domain errors:
41
+ 1. Use specific error types - don't use generic Error
42
+ 2. Include context - add relevant data to errors
43
+ 3. Document error codes - list all possible errors
44
+ 4. Handle gracefully - show user-friendly messages
45
+ 5. Log errors - track for debugging
46
+ 6. Don't swallow errors - always handle or rethrow
47
+ 7. Use type guards - enable type-safe error handling
50
48
 
51
- ```typescript
52
- throw new SubscriptionRepositoryError('Database connection failed');
53
- ```
54
-
55
- ### InsufficientCreditsError
56
-
57
- Thrown when user doesn't have enough credits.
58
-
59
- ```typescript
60
- throw new InsufficientCreditsError(
61
- 'Not enough credits',
62
- {
63
- required: 10,
64
- available: 5,
65
- featureId: 'export',
66
- }
67
- );
68
- ```
69
-
70
- ## Usage
71
-
72
- ### Throwing Errors
73
-
74
- ```typescript
75
- function deductCredits(amount: number) {
76
- if (amount <= 0) {
77
- throw new SubscriptionValidationError(
78
- 'Amount must be positive',
79
- 'INVALID_AMOUNT',
80
- { amount }
81
- );
82
- }
83
-
84
- if (currentBalance < amount) {
85
- throw new InsufficientCreditsError(
86
- 'Insufficient credits',
87
- {
88
- required: amount,
89
- available: currentBalance,
90
- }
91
- );
92
- }
93
- }
94
- ```
95
-
96
- ### Catching Errors
97
-
98
- ```typescript
99
- try {
100
- await purchasePackage(packageToPurchase);
101
- } catch (error) {
102
- if (error instanceof InsufficientCreditsError) {
103
- console.log(`Need ${error.context.required} credits`);
104
- showPaywall();
105
- } else if (error instanceof SubscriptionValidationError) {
106
- console.error('Validation error:', error.message);
107
- } else if (error instanceof SubscriptionError) {
108
- console.error('Subscription error:', error.code, error.message);
109
- } else {
110
- console.error('Unexpected error:', error);
111
- }
112
- }
113
- ```
114
-
115
- ### Type Guards
116
-
117
- ```typescript
118
- function isSubscriptionError(error: unknown): error is SubscriptionError {
119
- return error instanceof SubscriptionError;
120
- }
121
-
122
- function isInsufficientCreditsError(error: unknown): error is InsufficientCreditsError {
123
- return error instanceof InsufficientCreditsError;
124
- }
125
- ```
126
-
127
- ## Error Codes
128
-
129
- | Code | Description |
130
- |------|-------------|
131
- | `INVALID_USER_ID` | User ID is invalid or missing |
132
- | `INVALID_PRODUCT_ID` | Product ID is not recognized |
133
- | `INVALID_AMOUNT` | Amount is invalid (e.g., negative) |
134
- | `INSUFFICIENT_CREDITS` | User doesn't have enough credits |
135
- | `SUBSCRIPTION_EXPIRED` | Subscription has expired |
136
- | `SUBSCRIPTION_NOT_FOUND` | Subscription doesn't exist |
137
- | `REPOSITORY_ERROR` | Database/repository error |
138
- | `NETWORK_ERROR` | Network connectivity issue |
139
- | `PURCHASE_CANCELLED` | User cancelled purchase |
140
- | `PURCHASE_FAILED` | Purchase operation failed |
141
-
142
- ## Error Context
143
-
144
- Errors can include contextual information:
145
-
146
- ```typescript
147
- interface InsufficientCreditsContext {
148
- required: number;
149
- available: number;
150
- featureId?: string;
151
- currency?: string;
152
- }
153
-
154
- throw new InsufficientCreditsError(
155
- 'Insufficient credits',
156
- {
157
- required: 10,
158
- available: 5,
159
- featureId: 'export',
160
- currency: 'credits',
161
- }
162
- );
163
- ```
164
-
165
- ## Custom Errors
166
-
167
- Create your own domain errors:
168
-
169
- ```typescript
170
- class FeatureAccessError extends SubscriptionError {
171
- constructor(
172
- featureId: string,
173
- public readonly requiredTier: UserTier,
174
- public readonly currentTier: UserTier
175
- ) {
176
- super(
177
- `Feature "${featureId}" requires ${requiredTier} tier`,
178
- 'FEATURE_ACCESS_DENIED',
179
- { featureId, requiredTier, currentTier }
180
- );
181
- this.name = 'FeatureAccessError';
182
- }
183
- }
184
-
185
- // Usage
186
- if (!canAccessFeature('advanced_analytics')) {
187
- throw new FeatureAccessError(
188
- 'advanced_analytics',
189
- 'premium',
190
- userTier
191
- );
192
- }
193
- ```
194
-
195
- ## Error Handling Patterns
196
-
197
- ### 1. Try-Catch with Type Guards
198
-
199
- ```typescript
200
- try {
201
- await executeOperation();
202
- } catch (error) {
203
- if (error instanceof InsufficientCreditsError) {
204
- handleInsufficientCredits(error);
205
- } else if (error instanceof SubscriptionError) {
206
- handleSubscriptionError(error);
207
- } else {
208
- handleUnexpectedError(error);
209
- }
210
- }
211
- ```
212
-
213
- ### 2. Result Type
214
-
215
- ```typescript
216
- type Result<T, E extends Error = Error> =
217
- | { success: true; data: T }
218
- | { success: false; error: E };
219
-
220
- async function deductCredits(
221
- amount: number
222
- ): Promise<Result<number, InsufficientCreditsError>> {
223
- if (currentBalance < amount) {
224
- return {
225
- success: false,
226
- error: new InsufficientCreditsError('...', {...}),
227
- };
228
- }
229
-
230
- return { success: true, data: newBalance };
231
- }
232
-
233
- // Usage
234
- const result = await deductCredits(10);
235
- if (result.success) {
236
- console.log('New balance:', result.data);
237
- } else {
238
- console.error('Error:', result.error.message);
239
- }
240
- ```
241
-
242
- ### 3. Error Boundary
243
-
244
- ```typescript
245
- class SubscriptionErrorBoundary extends React.Component {
246
- state = { hasError: false, error: null };
247
-
248
- static getDerivedStateFromError(error: Error) {
249
- return { hasError: true, error };
250
- }
251
-
252
- componentDidCatch(error: Error, errorInfo: any) {
253
- if (error instanceof SubscriptionError) {
254
- analytics().logEvent('subscription_error', {
255
- code: error.code,
256
- message: error.message,
257
- });
258
- }
259
- }
260
-
261
- render() {
262
- if (this.state.hasError) {
263
- return <ErrorFallback error={this.state.error} />;
264
- }
265
-
266
- return this.props.children;
267
- }
268
- }
269
- ```
270
-
271
- ## Best Practices
272
-
273
- 1. **Use specific error types** - Don't use generic Error
274
- 2. **Include context** - Add relevant data to errors
275
- 3. **Document error codes** - List all possible errors
276
- 4. **Handle gracefully** - Show user-friendly messages
277
- 5. **Log errors** - Track for debugging
278
- 6. **Don't swallow errors** - Always handle or rethrow
279
- 7. **Use type guards** - Enable type-safe error handling
280
-
281
- ## Testing
282
-
283
- ```typescript
284
- describe('InsufficientCreditsError', () => {
285
- it('should create error with context', () => {
286
- const error = new InsufficientCreditsError('Not enough credits', {
287
- required: 10,
288
- available: 5,
289
- });
290
-
291
- expect(error.context.required).toBe(10);
292
- expect(error.context.available).toBe(5);
293
- });
294
-
295
- it('should be instance of SubscriptionError', () => {
296
- const error = new InsufficientCreditsError('...', {...});
297
-
298
- expect(error).toBeInstanceOf(SubscriptionError);
299
- });
300
- });
301
- ```
302
-
303
- ## Related
49
+ ## Related Documentation
304
50
 
305
51
  - [Domain Entities](../entities/README.md)
306
52
  - [Value Objects](../value-objects/README.md)
307
- - [Domain Layer](../../README.md)
53
+ - [Domain Layer](../README.md)