@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,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)