@umituz/react-native-subscription 2.14.99 → 2.14.101

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 (98) hide show
  1. package/README.md +211 -394
  2. package/package.json +3 -3
  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/entities/SubscriptionStatus.ts +1 -1
  9. package/src/domain/errors/README.md +33 -287
  10. package/src/domain/value-objects/README.md +43 -179
  11. package/src/domains/README.md +50 -238
  12. package/src/domains/README.md.bak +274 -0
  13. package/src/domains/config/README.md +93 -383
  14. package/src/domains/config/domain/README.md +23 -376
  15. package/src/domains/config/domain/entities/README.md +34 -343
  16. package/src/domains/paywall/README.md +99 -369
  17. package/src/domains/paywall/components/README.md +34 -178
  18. package/src/domains/paywall/entities/README.md +34 -193
  19. package/src/domains/paywall/hooks/README.md +34 -122
  20. package/src/domains/wallet/README.md +34 -275
  21. package/src/domains/wallet/README.md.bak +209 -0
  22. package/src/domains/wallet/domain/README.md +34 -101
  23. package/src/domains/wallet/domain/entities/README.md +34 -115
  24. package/src/domains/wallet/domain/errors/README.md +34 -151
  25. package/src/domains/wallet/infrastructure/README.md +34 -89
  26. package/src/domains/wallet/presentation/components/README.md +34 -224
  27. package/src/domains/wallet/presentation/components/TransactionItem.tsx +1 -1
  28. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  29. package/src/infrastructure/README.md +37 -496
  30. package/src/infrastructure/mappers/README.md +0 -13
  31. package/src/infrastructure/repositories/README.md +74 -360
  32. package/src/infrastructure/services/ActivationHandler.ts +1 -1
  33. package/src/infrastructure/services/README.md +95 -370
  34. package/src/infrastructure/services/SubscriptionService.ts +1 -1
  35. package/src/presentation/README.md +123 -408
  36. package/src/presentation/README.md.bak +172 -0
  37. package/src/presentation/components/README.md +151 -179
  38. package/src/presentation/components/README.md.bak +217 -0
  39. package/src/presentation/components/details/CreditRow.md +65 -310
  40. package/src/presentation/components/details/DetailRow.md +63 -255
  41. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  42. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  43. package/src/presentation/components/details/README.md +97 -447
  44. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  45. package/src/presentation/components/feedback/README.md +97 -445
  46. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  47. package/src/presentation/components/paywall/README.md +50 -186
  48. package/src/presentation/components/sections/README.md +97 -466
  49. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  50. package/src/presentation/hooks/README.md +154 -741
  51. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  52. package/src/presentation/hooks/useAuthGate.md +61 -375
  53. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  54. package/src/presentation/hooks/useCreditChecker.md +73 -378
  55. package/src/presentation/hooks/useCredits.md +74 -313
  56. package/src/presentation/hooks/useCredits.md.bak +231 -0
  57. package/src/presentation/hooks/useCreditsGate.md +66 -318
  58. package/src/presentation/hooks/useDeductCredit.md +0 -76
  59. package/src/presentation/hooks/useDeductCredit.ts +1 -1
  60. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  61. package/src/presentation/hooks/useFeatureGate.md +105 -150
  62. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  63. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  64. package/src/presentation/hooks/usePaywall.md +61 -306
  65. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  66. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  67. package/src/presentation/hooks/usePremium.md +84 -226
  68. package/src/presentation/hooks/usePremiumGate.md +60 -395
  69. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  70. package/src/presentation/hooks/useSubscription.md +66 -422
  71. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  72. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  73. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  74. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  75. package/src/presentation/hooks/useUserTier.md +63 -328
  76. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  77. package/src/presentation/screens/README.md +48 -190
  78. package/src/presentation/types/README.md +0 -16
  79. package/src/presentation/utils/README.md +0 -21
  80. package/src/presentation/utils/subscriptionDateUtils.ts +1 -1
  81. package/src/revenuecat/README.md +99 -518
  82. package/src/revenuecat/application/README.md +35 -150
  83. package/src/revenuecat/application/ports/README.md +34 -162
  84. package/src/revenuecat/domain/README.md +42 -141
  85. package/src/revenuecat/domain/constants/README.md +34 -176
  86. package/src/revenuecat/domain/entities/README.md +34 -374
  87. package/src/revenuecat/domain/errors/README.md +47 -191
  88. package/src/revenuecat/domain/types/README.md +34 -366
  89. package/src/revenuecat/domain/value-objects/README.md +34 -434
  90. package/src/revenuecat/infrastructure/README.md +34 -43
  91. package/src/revenuecat/infrastructure/config/README.md +32 -23
  92. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  93. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  94. package/src/revenuecat/infrastructure/services/README.md +35 -318
  95. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  96. package/src/revenuecat/presentation/README.md +34 -176
  97. package/src/revenuecat/presentation/hooks/README.md +29 -35
  98. package/src/utils/README.md +38 -525
@@ -2,513 +2,54 @@
2
2
 
3
3
  Abonelik sisteminin dış dünya ile iletişimini sağlayan implementations ve repositories içeren katman.
4
4
 
5
- ## Sorumluluklar
5
+ ## Location
6
6
 
7
- - **Repositories**: Veri erişim implementasyonları
8
- - **Services**: Dış servis entegrasyonları (Firebase, RevenueCat, vb.)
9
- - **Managers**: Karmaşık operasyon yöneticileri
10
- - **Handlers**: Özel durum ve event yöneticileri
7
+ `src/infrastructure/`
11
8
 
12
- ## Yapı
9
+ ## Strategy
13
10
 
14
- ```
15
- infrastructure/
16
- ├── repositories/
17
- │ └── CreditsRepositoryProvider.ts # Kredi repository konfigürasyonu
18
- ├── services/
19
- │ ├── SubscriptionService.ts # Abonelik servisi implementasyonu
20
- │ └── SubscriptionInitializer.ts # Abonelik başlatıcı
21
- └── [other implementations]
22
- ```
11
+ Dış servis entegrasyonlarını (Firebase, RevenueCat), veri erişim implementasyonlarını ve karmaşık operasyon yöneticilerini içeren katman. Dependency injection ve test edilebilirlik sağlar.
23
12
 
24
- ## Repositories
13
+ ## Restrictions
25
14
 
26
- ### CreditsRepositoryProvider
15
+ ### REQUIRED
27
16
 
28
- Kredi repository'sini konfigüre etmek ve yönetmek için:
17
+ - MUST implement all port interfaces from application layer
18
+ - MUST handle all errors gracefully and propagate appropriately
19
+ - MUST validate all inputs before processing
20
+ - MUST implement caching for frequently accessed data
21
+ - MUST support logging for debugging and monitoring
22
+ - MUST be testable with mock implementations
29
23
 
30
- ```typescript
31
- import {
32
- configureCreditsRepository,
33
- getCreditsRepository,
34
- getCreditsConfig,
35
- resetCreditsRepository,
36
- isCreditsRepositoryConfigured,
37
- type CreditsConfig,
38
- } from '@umituz/react-native-subscription';
24
+ ### PROHIBITED
39
25
 
40
- // Repository konfigürasyonu
41
- const config: CreditsConfig = {
42
- initialCredits: 100,
26
+ - MUST NOT contain business logic (belongs in domain/application)
27
+ - MUST NOT bypass error handling
28
+ - MUST NOT expose implementation details to other layers
29
+ - MUST NOT create tight coupling with external services
43
30
 
44
- creditPackages: [
45
- {
46
- id: 'credits_small',
47
- productId: 'com.app.credits.small',
48
- amount: 100,
49
- price: 0.99,
50
- currency: 'USD',
51
- },
52
- {
53
- id: 'credits_medium',
54
- productId: 'com.app.credits.medium',
55
- amount: 500,
56
- price: 3.99,
57
- currency: 'USD',
58
- },
59
- ],
31
+ ### CRITICAL
60
32
 
61
- creditCosts: {
62
- ai_generation: 1,
63
- ai_analysis: 2,
64
- premium_feature: 5,
65
- },
33
+ - Always validate inputs before processing
34
+ - Implement proper error handling for all external calls
35
+ - Use dependency injection for all external dependencies
36
+ - Ensure all implementations are mockable for testing
37
+ - Implement retry logic for network operations
66
38
 
67
- expiration: {
68
- enabled: true,
69
- daysUntilExpiration: 365,
70
- },
71
- };
39
+ ## AI Agent Guidelines
72
40
 
73
- // Repository'i konfigüre et
74
- configureCreditsRepository({
75
- firebase: firebaseInstance,
76
- storage: storageInstance,
77
- config,
78
- });
41
+ When working with infrastructure layer:
42
+ 1. Dependency Injection - repository'leri constructor'da alın
43
+ 2. Error Handling - tüm hataları yakalayın ve uygun şekilde handle edin
44
+ 3. Caching - sık kullanılan verileri cache'leyin
45
+ 4. Validation - girdileri validate edin
46
+ 5. Logging - önemli operasyonları log'layın
47
+ 6. Testing - mock implementasyonlarla test edilebilir yapın
48
+ 7. Retry Logic - network hataları için retry logic ekleyin
79
49
 
80
- // Repository'e eriş
81
- const repository = getCreditsRepository();
82
- const creditsConfig = getCreditsConfig();
50
+ ## Related Documentation
83
51
 
84
- // Konfigürasyon kontrolü
85
- if (isCreditsRepositoryConfigured()) {
86
- // Repository kullanıma hazır
87
- }
88
-
89
- // Reset (test için)
90
- resetCreditsRepository();
91
- ```
92
-
93
- ### CreditsRepository
94
-
95
- Kendi repository implementasyonunuzu oluşturun:
96
-
97
- ```typescript
98
- import {
99
- createCreditsRepository,
100
- type CreditsRepository,
101
- type UserCredits,
102
- type CreditsResult,
103
- } from '@umituz/react-native-subscription';
104
-
105
- class MyCreditsRepository implements CreditsRepository {
106
- async getCredits(userId: string): Promise<UserCredits> {
107
- // Veritabanından kredi bilgilerini getir
108
- const doc = await db.collection('credits').doc(userId).get();
109
- return doc.data();
110
- }
111
-
112
- async addCredits(
113
- userId: string,
114
- amount: number,
115
- reason: string
116
- ): Promise<CreditsResult> {
117
- // Kredi ekle
118
- await db.collection('credits').doc(userId).update({
119
- balance: firebase.firestore.FieldValue.increment(amount),
120
- lastUpdated: new Date().toISOString(),
121
- });
122
-
123
- return {
124
- success: true,
125
- newBalance: currentBalance + amount,
126
- transaction: {
127
- id: generateId(),
128
- amount,
129
- reason,
130
- timestamp: new Date().toISOString(),
131
- },
132
- };
133
- }
134
-
135
- async deductCredits(
136
- userId: string,
137
- amount: number,
138
- reason: string
139
- ): Promise<CreditsResult> {
140
- // Bakiye kontrolü
141
- const current = await this.getCredits(userId);
142
- if (current.balance < amount) {
143
- return {
144
- success: false,
145
- error: 'Insufficient credits',
146
- };
147
- }
148
-
149
- // Kredi düş
150
- await db.collection('credits').doc(userId).update({
151
- balance: firebase.firestore.FieldValue.increment(-amount),
152
- lastUpdated: new Date().toISOString(),
153
- });
154
-
155
- return {
156
- success: true,
157
- newBalance: current.balance - amount,
158
- transaction: {
159
- id: generateId(),
160
- amount: -amount,
161
- reason,
162
- timestamp: new Date().toISOString(),
163
- },
164
- };
165
- }
166
- }
167
-
168
- // Repository oluştur ve kullan
169
- const repository = new MyCreditsRepository();
170
- ```
171
-
172
- ## Services
173
-
174
- ### SubscriptionService
175
-
176
- Abonelik servisi implementasyonu:
177
-
178
- ```typescript
179
- import {
180
- SubscriptionService,
181
- initializeSubscriptionService,
182
- type SubscriptionConfig,
183
- } from '@umituz/react-native-subscription';
184
-
185
- // Manuel oluşturma
186
- const service = new SubscriptionService({
187
- repository: myRepository,
188
- onStatusChanged: (userId, newStatus) => {
189
- console.log(`User ${userId}: ${newStatus.type}`);
190
- },
191
- onError: (error) => {
192
- console.error('Error:', error);
193
- },
194
- });
195
-
196
- // Helper ile başlatma
197
- await initializeSubscriptionService({
198
- repository: myRepository,
199
- firebase: firebaseInstance,
200
- revenueCatApiKey: 'your_api_key',
201
- });
202
-
203
- // Kullanım
204
- const status = await service.getSubscriptionStatus('user-123');
205
- const isPremium = await service.isPremium('user-123');
206
- ```
207
-
208
- ### SubscriptionInitializer
209
-
210
- Uygulamanın başında abonlik sistemini başlatmak için:
211
-
212
- ```typescript
213
- import {
214
- initializeSubscription,
215
- type SubscriptionInitConfig,
216
- type CreditPackageConfig,
217
- } from '@umituz/react-native-subscription';
218
-
219
- const config: SubscriptionInitConfig = {
220
- revenueCatApiKey: process.env.REVENUECAT_API_KEY,
221
- revenueCatEntitlementId: 'premium',
222
-
223
- // Opsiyonel kredi konfigürasyonu
224
- creditPackages: [
225
- {
226
- id: 'small',
227
- productId: 'com.app.credits.100',
228
- amount: 100,
229
- price: 0.99,
230
- },
231
- {
232
- id: 'medium',
233
- productId: 'com.app.credits.500',
234
- amount: 500,
235
- price: 3.99,
236
- },
237
- ],
238
-
239
- // Callback'ler
240
- onInitialized: () => {
241
- console.log('Subscription system initialized');
242
- },
243
- onError: (error) => {
244
- console.error('Initialization error:', error);
245
- },
246
- };
247
-
248
- // Başlat
249
- await initializeSubscription(config);
250
- ```
251
-
252
- ## Firebase Integration
253
-
254
- ### Firestore Repository
255
-
256
- Firebase Firestore ile repository implementasyonu:
257
-
258
- ```typescript
259
- import firestore from '@react-native-firebase/firestore';
260
- import type { ISubscriptionRepository } from '@umituz/react-native-subscription';
261
-
262
- class FirestoreSubscriptionRepository implements ISubscriptionRepository {
263
- private collection = firestore().collection('subscriptions');
264
-
265
- async getSubscriptionStatus(userId: string) {
266
- const doc = await this.collection.doc(userId).get();
267
- if (!doc.exists) return null;
268
- return doc.data();
269
- }
270
-
271
- async saveSubscriptionStatus(userId: string, status: any) {
272
- await this.collection.doc(userId).set(status, { merge: true });
273
- }
274
-
275
- async deleteSubscriptionStatus(userId: string) {
276
- await this.collection.doc(userId).delete();
277
- }
278
-
279
- isSubscriptionValid(status: any): boolean {
280
- if (!status.isActive) return false;
281
- if (!status.expirationDate) return true;
282
- return new Date(status.expirationDate) > new Date();
283
- }
284
-
285
- // Real-time updates
286
- subscribeToStatus(
287
- userId: string,
288
- callback: (status: any) => void
289
- ): () => void {
290
- const unsubscribe = this.collection
291
- .doc(userId)
292
- .onSnapshot((doc) => {
293
- if (doc.exists) {
294
- callback(doc.data());
295
- }
296
- });
297
-
298
- return unsubscribe;
299
- }
300
- }
301
- ```
302
-
303
- ## Error Handling
304
-
305
- Infrastructure hatalarını yönetme:
306
-
307
- ```typescript
308
- import {
309
- SubscriptionRepositoryError,
310
- SubscriptionValidationError,
311
- } from '@umituz/react-native-subscription';
312
-
313
- class SafeRepository {
314
- async getSubscriptionStatus(userId: string) {
315
- try {
316
- if (!userId || userId.length === 0) {
317
- throw new SubscriptionValidationError('Invalid user ID');
318
- }
319
-
320
- const data = await this.fetchFromDatabase(userId);
321
-
322
- if (!data) {
323
- return null;
324
- }
325
-
326
- return data;
327
- } catch (error) {
328
- if (error instanceof SubscriptionValidationError) {
329
- // Validation hatası
330
- console.error('Validation failed:', error.message);
331
- throw error;
332
- } else {
333
- // Beklenmedik hata
334
- throw new SubscriptionRepositoryError(
335
- 'Failed to get subscription status',
336
- error
337
- );
338
- }
339
- }
340
- }
341
- }
342
- ```
343
-
344
- ## Caching
345
-
346
- Performans için caching implementasyonu:
347
-
348
- ```typescript
349
- class CachedRepository {
350
- private cache = new Map<string, any>();
351
- private cacheTimeout = 5 * 60 * 1000; // 5 dakika
352
-
353
- async getSubscriptionStatus(userId: string) {
354
- // Cache kontrolü
355
- const cached = this.cache.get(userId);
356
- if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
357
- return cached.data;
358
- }
359
-
360
- // Veritabanından getir
361
- const data = await this.fetchFromDatabase(userId);
362
-
363
- // Cache'e kaydet
364
- this.cache.set(userId, {
365
- data,
366
- timestamp: Date.now(),
367
- });
368
-
369
- return data;
370
- }
371
-
372
- invalidateCache(userId: string) {
373
- this.cache.delete(userId);
374
- }
375
-
376
- clearCache() {
377
- this.cache.clear();
378
- }
379
- }
380
- ```
381
-
382
- ## Testing
383
-
384
- Mock repository ile test:
385
-
386
- ```typescript
387
- class MockSubscriptionRepository {
388
- private data = new Map<string, any>();
389
-
390
- async getSubscriptionStatus(userId: string) {
391
- return this.data.get(userId) || null;
392
- }
393
-
394
- async saveSubscriptionStatus(userId: string, status: any) {
395
- this.data.set(userId, status);
396
- }
397
-
398
- async deleteSubscriptionStatus(userId: string) {
399
- this.data.delete(userId);
400
- }
401
-
402
- isSubscriptionValid(status: any): boolean {
403
- return status?.isActive ?? false;
404
- }
405
-
406
- // Test helper
407
- __setTestData(userId: string, status: any) {
408
- this.data.set(userId, status);
409
- }
410
-
411
- __clearData() {
412
- this.data.clear();
413
- }
414
- }
415
-
416
- // Testlerde
417
- const mockRepo = new MockSubscriptionRepository();
418
- const service = new SubscriptionService({
419
- repository: mockRepo,
420
- });
421
-
422
- mockRepo.__setTestData('user-123', {
423
- type: 'premium',
424
- isActive: true,
425
- isPremium: true,
426
- });
427
-
428
- const status = await service.getSubscriptionStatus('user-123');
429
- expect(status?.type).toBe('premium');
430
- ```
431
-
432
- ## Best Practices
433
-
434
- 1. **Dependency Injection**: Repository'leri constructor'da alın
435
- 2. **Error Handling**: Tüm hataları yakalayın ve uygun şekilde handle edin
436
- 3. **Caching**: Sık kullanılan verileri cache'leyin
437
- 4. **Validation**: Girdileri validate edin
438
- 5. **Logging**: Önemli operasyonları log'layın
439
- 6. **Testing**: Mock implementasyonlarla test edilebilir yapın
440
- 7. **Retry Logic**: Network hataları için retry logic ekleyin
441
-
442
- ## Örnek: Full Implementation
443
-
444
- ```typescript
445
- import {
446
- SubscriptionService,
447
- type ISubscriptionRepository,
448
- SubscriptionStatus,
449
- } from '@umituz/react-native-subscription';
450
- import firestore from '@react-native-firebase/firestore';
451
-
452
- class FirestoreRepository implements ISubscriptionRepository {
453
- private db = firestore();
454
-
455
- async getSubscriptionStatus(userId: string): Promise<SubscriptionStatus | null> {
456
- try {
457
- const doc = await this.db
458
- .collection('subscriptions')
459
- .doc(userId)
460
- .get();
461
-
462
- if (!doc.exists) return null;
463
- return doc.data() as SubscriptionStatus;
464
- } catch (error) {
465
- console.error('Error fetching subscription:', error);
466
- throw error;
467
- }
468
- }
469
-
470
- async saveSubscriptionStatus(
471
- userId: string,
472
- status: SubscriptionStatus
473
- ): Promise<void> {
474
- try {
475
- await this.db
476
- .collection('subscriptions')
477
- .doc(userId)
478
- .set(status, { merge: true });
479
- } catch (error) {
480
- console.error('Error saving subscription:', error);
481
- throw error;
482
- }
483
- }
484
-
485
- async deleteSubscriptionStatus(userId: string): Promise<void> {
486
- try {
487
- await this.db
488
- .collection('subscriptions')
489
- .doc(userId)
490
- .delete();
491
- } catch (error) {
492
- console.error('Error deleting subscription:', error);
493
- throw error;
494
- }
495
- }
496
-
497
- isSubscriptionValid(status: SubscriptionStatus): boolean {
498
- if (!status.isActive) return false;
499
- if (!status.expirationDate) return true;
500
- return new Date(status.expirationDate) > new Date();
501
- }
502
- }
503
-
504
- // Kullanım
505
- const repository = new FirestoreRepository();
506
- const service = new SubscriptionService({
507
- repository,
508
- onStatusChanged: (userId, status) => {
509
- console.log(`Status changed for ${userId}`);
510
- },
511
- });
512
-
513
- await service.activateSubscription('user-123', 'premium_monthly', null);
514
- ```
52
+ - [Application Layer](../application/README.md)
53
+ - [Domain Layer](../domain/README.md)
54
+ - [Repositories](./repositories/README.md)
55
+ - [Services](./services/README.md)
@@ -15,19 +15,6 @@ This directory contains mapper functions that transform data between different l
15
15
 
16
16
  Mappers provide clean separation between layers:
17
17
 
18
- ```
19
- External API → Mapper → Domain Entity
20
- Domain Entity → Mapper → DTO/Model
21
- ```
22
-
23
- ## Usage
24
-
25
- ```typescript
26
- import { mapToSubscriptionStatus } from './mappers/subscriptionMapper';
27
-
28
- const entity = mapToSubscriptionStatus(apiResponse);
29
- ```
30
-
31
18
  ## Related
32
19
 
33
20
  - [Models](../models/README.md)