@umituz/react-native-subscription 2.14.98 → 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 -395
  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 +52 -0
  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 +37 -0
  14. package/src/domains/config/domain/entities/README.md +41 -0
  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 +96 -156
  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 +43 -0
  77. package/src/revenuecat/application/ports/README.md +41 -0
  78. package/src/revenuecat/domain/README.md +42 -141
  79. package/src/revenuecat/domain/constants/README.md +41 -0
  80. package/src/revenuecat/domain/entities/README.md +42 -0
  81. package/src/revenuecat/domain/errors/README.md +47 -191
  82. package/src/revenuecat/domain/types/README.md +41 -0
  83. package/src/revenuecat/domain/value-objects/README.md +41 -0
  84. package/src/revenuecat/infrastructure/README.md +41 -0
  85. package/src/revenuecat/infrastructure/config/README.md +32 -23
  86. package/src/revenuecat/infrastructure/handlers/README.md +41 -0
  87. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  88. package/src/revenuecat/infrastructure/services/README.md +42 -0
  89. package/src/revenuecat/infrastructure/utils/README.md +41 -0
  90. package/src/revenuecat/presentation/README.md +42 -0
  91. package/src/revenuecat/presentation/hooks/README.md +29 -35
  92. package/src/utils/README.md +38 -525
@@ -2,401 +2,53 @@
2
2
 
3
3
  Abonelik sisteminin temel domain logic'ini, entity'lerini ve value object'lerini içeren katman.
4
4
 
5
- ## Sorumluluklar
5
+ ## Location
6
6
 
7
- - **Entities**: Domain entity'lerini tanımlama
8
- - **Value Objects**: Değer objelerini oluşturma
9
- - **Domain Errors**: Domain-specific hataları tanımlama
10
- - **Business Rules**: İş kurallarını encapsulate etme
7
+ `src/domain/`
11
8
 
12
- ## Yapı
9
+ ## Strategy
13
10
 
14
- ```
15
- domain/
16
- ├── entities/
17
- │ └── SubscriptionStatus.ts # Abonelik durumu entity'si
18
- ├── value-objects/
19
- │ └── SubscriptionConfig.ts # Konfigürasyon value object
20
- └── errors/
21
- ├── SubscriptionError.ts # Abonelik hataları
22
- └── InsufficientCreditsError.ts # Kredi yetersizlik hatası
23
- ```
11
+ Temel iş kavramlarını, iş kurallarını ve domain logic'ini encapsulate eden katman. Framework-agnostic ve tamamen iş mantığına odaklı.
24
12
 
25
- ## Entities
13
+ ## Restrictions
26
14
 
27
- ### SubscriptionStatus
15
+ ### REQUIRED
28
16
 
29
- Kullanıcının abonelik durumunu temsil eden ana entity:
17
+ - MUST be framework-agnostic (no React, React Native dependencies)
18
+ - MUST encapsulate business rules within entities
19
+ - MUST validate all invariants on entity creation
20
+ - MUST use immutable objects
21
+ - MUST implement type guards for type safety
22
+ - MUST define domain-specific error types
30
23
 
31
- ```typescript
32
- import {
33
- SubscriptionStatus,
34
- SubscriptionStatusType,
35
- createDefaultSubscriptionStatus,
36
- isSubscriptionValid,
37
- } from '@umituz/react-native-subscription';
24
+ ### PROHIBITED
38
25
 
39
- // Varsayılan durum oluştur
40
- const defaultStatus = createDefaultSubscriptionStatus();
41
- // {
42
- // type: 'unknown',
43
- // isActive: false,
44
- // isPremium: false,
45
- // expirationDate: null,
46
- // willRenew: false,
47
- // }
26
+ - MUST NOT contain any framework or UI code
27
+ - MUST NOT have direct dependencies on infrastructure
28
+ - MUST NOT expose mutable state
29
+ - MUST NOT use generic error types
48
30
 
49
- // Premium durumu oluştur
50
- const premiumStatus: SubscriptionStatus = {
51
- type: 'premium',
52
- isActive: true,
53
- isPremium: true,
54
- expirationDate: '2025-12-31T23:59:59Z',
55
- willRenew: true,
56
- productId: 'com.app.premium.annual',
57
- };
31
+ ### CRITICAL
58
32
 
59
- // Abonelik geçerliliğini kontrol et
60
- const isValid = isSubscriptionValid(premiumStatus); // true
61
- ```
33
+ - Keep entities pure and framework-independent
34
+ - Validate all business rules on entity creation
35
+ - Make all objects immutable
36
+ - Encapsulate business logic within entities
37
+ - Use strong typing throughout
62
38
 
63
- **SubscriptionStatusType:**
39
+ ## AI Agent Guidelines
64
40
 
65
- ```typescript
66
- type SubscriptionStatusType =
67
- | 'unknown' // Durum bilinmiyor
68
- | 'guest' // Misafir kullanıcı
69
- | 'free' // Free kullanıcı
70
- | 'premium'; // Premium kullanıcı
71
- ```
41
+ When working with domain layer:
42
+ 1. Immutable Objects - entity'leri immutable olarak tasarlayın
43
+ 2. Validation - entity creation'da validation yapın
44
+ 3. Encapsulation - business logic'i entity içinde tutun
45
+ 4. Type Safety - strong typing kullanın
46
+ 5. Domain Events - önemli domain olaylarını event olarak yayınlayın
47
+ 6. Error Handling - domain-specific hatalar tanımlayın
72
48
 
73
- ## Value Objects
49
+ ## Related Documentation
74
50
 
75
- ### SubscriptionConfig
76
-
77
- Abonelik konfigürasyonu için value object:
78
-
79
- ```typescript
80
- import type { SubscriptionConfig } from '@umituz/react-native-subscription';
81
-
82
- const config: SubscriptionConfig = {
83
- revenueCatApiKey: 'your_api_key',
84
- revenueCatEntitlementId: 'premium',
85
-
86
- plans: {
87
- monthly: monthlyPlan,
88
- annual: annualPlan,
89
- },
90
-
91
- defaultPlan: 'monthly',
92
-
93
- features: {
94
- requireAuth: true,
95
- allowRestore: true,
96
- syncWithFirebase: true,
97
- },
98
-
99
- ui: {
100
- showAnnualDiscount: true,
101
- highlightPopularPlan: true,
102
- },
103
-
104
- // Optional callbacks
105
- onStatusChanged: (userId, newStatus) => {
106
- console.log(`Status changed for ${userId}:`, newStatus);
107
- },
108
-
109
- onError: (error) => {
110
- console.error('Subscription error:', error);
111
- },
112
- };
113
- ```
114
-
115
- ## Domain Errors
116
-
117
- ### SubscriptionError
118
-
119
- Abonelik işlemleri için hata sınıfı:
120
-
121
- ```typescript
122
- import {
123
- SubscriptionError,
124
- SubscriptionValidationError,
125
- SubscriptionRepositoryError,
126
- } from '@umituz/react-native-subscription';
127
-
128
- // Doğrulama hatası
129
- throw new SubscriptionValidationError('Invalid user ID');
130
-
131
- // Repository hatası
132
- throw new SubscriptionRepositoryError('Database connection failed');
133
-
134
- // Genel hata
135
- throw new SubscriptionError('Subscription operation failed');
136
- ```
137
-
138
- ### InsufficientCreditsError
139
-
140
- Kredi yetersizliği hatası:
141
-
142
- ```typescript
143
- import {
144
- InsufficientCreditsError,
145
- type CreditErrorContext,
146
- } from '@umituz/react-native-subscription';
147
-
148
- const context: CreditErrorContext = {
149
- required: 10,
150
- available: 5,
151
- featureId: 'ai_generation',
152
- currency: 'USD',
153
- };
154
-
155
- throw new InsufficientCreditsError(
156
- 'Not enough credits',
157
- context
158
- );
159
-
160
- // Hata yakalama
161
- try {
162
- await deductCredits(userId, 10);
163
- } catch (error) {
164
- if (error instanceof InsufficientCreditsError) {
165
- console.log(`Required: ${error.context.required}`);
166
- console.log(`Available: ${error.context.available}`);
167
- // Paywall göster
168
- showPaywall();
169
- }
170
- }
171
- ```
172
-
173
- ## Helper Functions
174
-
175
- ### SubscriptionStatus Helpers
176
-
177
- ```typescript
178
- import {
179
- createDefaultSubscriptionStatus,
180
- isSubscriptionValid,
181
- isSubscriptionActive,
182
- isUserPremium,
183
- getSubscriptionTier,
184
- } from '@umituz/react-native-subscription';
185
-
186
- // Varsayılan durum oluştur
187
- const status = createDefaultSubscriptionStatus();
188
-
189
- // Geçerlilik kontrolü
190
- const isValid = isSubscriptionValid(status);
191
-
192
- // Aktif kontrolü
193
- const isActive = isSubscriptionActive(status);
194
-
195
- // Premium kontrolü
196
- const isPremium = isUserPremium(status);
197
-
198
- // Tier bilgisi
199
- const tier = getSubscriptionTier(status); // 'free', 'premium'
200
- ```
201
-
202
- ## Factory Functions
203
-
204
- ### Entity Factory
205
-
206
- ```typescript
207
- import { SubscriptionStatus } from '@umituz/react-native-subscription';
208
-
209
- // Factory method ile oluştur
210
- const status = SubscriptionStatus.create({
211
- type: 'premium',
212
- isActive: true,
213
- isPremium: true,
214
- expirationDate: '2025-12-31T23:59:59Z',
215
- willRenew: true,
216
- });
217
-
218
- // Validation içerir
219
- try {
220
- const invalid = SubscriptionStatus.create({
221
- type: 'premium',
222
- isActive: false, // Çelişki: premium ama aktif değil
223
- isPremium: true,
224
- });
225
- } catch (error) {
226
- console.error('Validation error:', error.message);
227
- }
228
- ```
229
-
230
- ## Type Guards
231
-
232
- Domain entities için type guard'lar:
233
-
234
- ```typescript
235
- import {
236
- isSubscriptionStatus,
237
- isValidSubscriptionStatus,
238
- } from '@umituz/react-native-subscription';
239
-
240
- // Type guard
241
- const obj = { type: 'premium', isActive: true, isPremium: true };
242
-
243
- if (isSubscriptionStatus(obj)) {
244
- // obj artık SubscriptionStatus tipinde
245
- console.log(obj.type); // Type-safe!
246
- }
247
-
248
- // Validasyon + type guard
249
- if (isValidSubscriptionStatus(obj)) {
250
- // Geçerli bir SubscriptionStatus
251
- }
252
- ```
253
-
254
- ## Domain Rules
255
-
256
- ### Business Rule Examples
257
-
258
- ```typescript
259
- import { SubscriptionStatus } from '@umituz/react-native-subscription';
260
-
261
- class SubscriptionDomain {
262
- // Kural: Premium kullanıcı her zaman aktif olmalı
263
- static validatePremiumStatus(status: SubscriptionStatus): boolean {
264
- if (status.isPremium && !status.isActive) {
265
- throw new Error('Premium users must be active');
266
- }
267
- return true;
268
- }
269
-
270
- // Kural: Abonelik tarihi geçmişse aktif olmamalı
271
- static validateExpiration(status: SubscriptionStatus): boolean {
272
- if (status.expirationDate) {
273
- const isExpired = new Date(status.expirationDate) < new Date();
274
- if (isExpired && status.isActive) {
275
- throw new Error('Expired subscription cannot be active');
276
- }
277
- }
278
- return true;
279
- }
280
-
281
- // Kural: Lifetime aboneliklerin son kullanma tarihi olmamalı
282
- static validateLifetime(status: SubscriptionStatus): boolean {
283
- if (status.type === 'premium' && status.willRenew === false) {
284
- if (status.expirationDate !== null) {
285
- throw new Error('Lifetime subscriptions cannot have expiration date');
286
- }
287
- }
288
- return true;
289
- }
290
- }
291
- ```
292
-
293
- ## Best Practices
294
-
295
- 1. **Immutable Objects**: Entity'leri immutable olarak tasarlayın
296
- 2. **Validation**: Entity creation'da validation yapın
297
- 3. **Encapsulation**: Business logic'i entity içinde tutun
298
- 4. **Type Safety**: Strong typing kullanın
299
- 5. **Domain Events**: Önemli domain olaylarını event olarak yayınlayın
300
- 6. **Error Handling**: Domain-specific hatalar tanımlayın
301
-
302
- ## Örnek: Domain Service
303
-
304
- ```typescript
305
- import {
306
- SubscriptionStatus,
307
- SubscriptionError,
308
- isSubscriptionValid,
309
- } from '@umituz/react-native-subscription';
310
-
311
- class SubscriptionDomainService {
312
- // Abonelik aktifleştirme
313
- activateSubscription(
314
- currentStatus: SubscriptionStatus,
315
- productId: string,
316
- expiresAt: string
317
- ): SubscriptionStatus {
318
- // Business rule: Zaten aktifse hata
319
- if (currentStatus.isActive) {
320
- throw new SubscriptionError('Subscription is already active');
321
- }
322
-
323
- // Yeni durum oluştur
324
- const newStatus: SubscriptionStatus = {
325
- type: 'premium',
326
- isActive: true,
327
- isPremium: true,
328
- expirationDate: expiresAt,
329
- willRenew: productId.includes('monthly') || productId.includes('annual'),
330
- productId,
331
- };
332
-
333
- return newStatus;
334
- }
335
-
336
- // Abonelik iptali
337
- deactivateSubscription(
338
- status: SubscriptionStatus
339
- ): SubscriptionStatus {
340
- if (!status.isActive) {
341
- throw new SubscriptionError('Subscription is not active');
342
- }
343
-
344
- return {
345
- ...status,
346
- isActive: false,
347
- willRenew: false,
348
- };
349
- }
350
-
351
- // Abonelik yenileme
352
- renewSubscription(
353
- status: SubscriptionStatus,
354
- newExpirationDate: string
355
- ): SubscriptionStatus {
356
- if (!status.willRenew) {
357
- throw new SubscriptionError('Subscription is set to not renew');
358
- }
359
-
360
- return {
361
- ...status,
362
- expirationDate: newExpirationDate,
363
- isActive: true,
364
- };
365
- }
366
- }
367
- ```
368
-
369
- ## Testing
370
-
371
- Domain entities test edilebilir olmalı:
372
-
373
- ```typescript
374
- import { SubscriptionStatus, isSubscriptionValid } from '@umituz/react-native-subscription';
375
-
376
- describe('SubscriptionStatus', () => {
377
- it('should create valid premium status', () => {
378
- const status = SubscriptionStatus.create({
379
- type: 'premium',
380
- isActive: true,
381
- isPremium: true,
382
- expirationDate: '2025-12-31T23:59:59Z',
383
- willRenew: true,
384
- });
385
-
386
- expect(status.type).toBe('premium');
387
- expect(status.isPremium).toBe(true);
388
- });
389
-
390
- it('should validate expiration', () => {
391
- const expired = SubscriptionStatus.create({
392
- type: 'premium',
393
- isActive: true,
394
- isPremium: true,
395
- expirationDate: '2020-01-01T00:00:00Z',
396
- willRenew: true,
397
- });
398
-
399
- expect(isSubscriptionValid(expired)).toBe(false);
400
- });
401
- });
402
- ```
51
+ - [Domain Entities](./entities/README.md)
52
+ - [Value Objects](./value-objects/README.md)
53
+ - [Domain Errors](./errors/README.md)
54
+ - [Application Layer](../application/README.md)
@@ -10,70 +10,14 @@ This directory contains constant definitions for subscription tiers, package per
10
10
 
11
11
  ### Subscription Tiers
12
12
 
13
- ```typescript
14
- export const SUBSCRIPTION_TIERS = {
15
- GUEST: 'guest',
16
- FREE: 'free',
17
- PREMIUM: 'premium',
18
- } as const;
19
-
20
- export type SubscriptionTier = typeof SUBSCRIPTION_TIERS[keyof typeof SUBSCRIPTION_TIERS];
21
- ```
22
-
23
13
  ### Package Periods
24
14
 
25
- ```typescript
26
- export const PACKAGE_PERIODS = {
27
- MONTHLY: 'monthly',
28
- ANNUAL: 'annual',
29
- LIFETIME: 'lifetime',
30
- } as const;
31
-
32
- export type PackagePeriod = typeof PACKAGE_PERIODS[keyof typeof PACKAGE_PERIODS];
33
- ```
34
-
35
15
  ### Error Codes
36
16
 
37
- ```typescript
38
- export const ERROR_CODES = {
39
- CREDITS_EXHAUSTED: 'CREDITS_EXHAUSTED',
40
- USER_NOT_AUTHENTICATED: 'USER_NOT_AUTHENTICATED',
41
- SUBSCRIPTION_EXPIRED: 'SUBSCRIPTION_EXPIRED',
42
- INVALID_PACKAGE: 'INVALID_PACKAGE',
43
- PURCHASE_FAILED: 'PURCHASE_FAILED',
44
- DUPLICATE_PURCHASE: 'DUPLICATE_PURCHASE',
45
- } as const;
46
- ```
47
-
48
17
  ### Credit Limits
49
18
 
50
- ```typescript
51
- export const CREDIT_LIMITS = {
52
- MAX_MONTHLY_CREDITS: 100,
53
- MAX_BONUS_CREDITS: 1000,
54
- MIN_CREDITS: 0,
55
- } as const;
56
- ```
57
-
58
19
  ### Time Periods
59
20
 
60
- ```typescript
61
- export const TIME_PERIODS = {
62
- CREDIT_RESET_DAYS: 30,
63
- EXPIRATION_WARNING_DAYS: 7,
64
- EXPIRATION_CRITICAL_DAYS: 3,
65
- } as const;
66
- ```
67
-
68
- ## Usage
69
-
70
- ```typescript
71
- import { SUBSCRIPTION_TIERS, PACKAGE_PERIODS } from './constants';
72
-
73
- const tier: SubscriptionTier = SUBSCRIPTION_TIERS.PREMIUM;
74
- const period: PackagePeriod = PACKAGE_PERIODS.ANNUAL;
75
- ```
76
-
77
21
  ## Related
78
22
 
79
23
  - [Domain README](../README.md)