@umituz/react-native-subscription 2.27.66 → 2.27.68

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 (125) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/CreditLimitCalculator.ts +17 -0
  3. package/src/domains/credits/application/CreditsInitializer.ts +85 -0
  4. package/src/domains/credits/application/DeductCreditsCommand.ts +52 -0
  5. package/src/domains/credits/application/PurchaseMetadataGenerator.ts +59 -0
  6. package/src/domains/credits/application/credit-strategies/CreditAllocationContext.ts +35 -0
  7. package/src/domains/credits/application/credit-strategies/ICreditStrategy.ts +18 -0
  8. package/src/domains/credits/application/credit-strategies/StandardPurchaseCreditStrategy.ts +16 -0
  9. package/src/domains/credits/application/credit-strategies/SyncCreditStrategy.ts +15 -0
  10. package/src/domains/credits/application/credit-strategies/TrialCreditStrategy.ts +18 -0
  11. package/src/{infrastructure/mappers → domains/credits/core}/CreditsMapper.ts +4 -4
  12. package/src/domains/credits/infrastructure/CreditsRepository.ts +102 -0
  13. package/src/{presentation/hooks → domains/credits/presentation}/useCredits.ts +21 -4
  14. package/src/domains/subscription/application/SubscriptionAuthListener.ts +26 -0
  15. package/src/domains/subscription/application/SubscriptionInitializer.ts +77 -0
  16. package/src/{infrastructure/services → domains/subscription/application}/SubscriptionInitializerTypes.ts +21 -1
  17. package/src/domains/subscription/application/SubscriptionSyncService.ts +71 -0
  18. package/src/domains/subscription/application/SubscriptionSyncUtils.ts +16 -0
  19. package/src/{revenuecat/domain/value-objects → domains/subscription/core}/RevenueCatConfig.ts +1 -1
  20. package/src/{domain/types → domains/subscription/core}/RevenueCatData.ts +1 -1
  21. package/src/{domain/entities → domains/subscription/core}/SubscriptionStatus.ts +13 -21
  22. package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +51 -0
  23. package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +67 -0
  24. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +27 -0
  25. package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCat.ts +1 -1
  26. package/src/domains/subscription/infrastructure/managers/SubscriptionInternalState.ts +12 -0
  27. package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +110 -0
  28. package/src/{revenuecat → domains/subscription}/infrastructure/services/PurchaseHandler.ts +1 -1
  29. package/src/{revenuecat → domains/subscription}/infrastructure/services/RestoreHandler.ts +1 -1
  30. package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatInitializer.ts +1 -1
  31. package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatService.ts +2 -2
  32. package/src/{presentation/hooks → domains/subscription/presentation}/usePremium.ts +7 -4
  33. package/src/domains/trial/application/TrialEligibilityService.ts +25 -0
  34. package/src/domains/trial/application/TrialService.ts +69 -0
  35. package/src/{infrastructure/services → domains/trial/core}/TrialTypes.ts +1 -1
  36. package/src/domains/trial/infrastructure/DeviceTrialRepository.ts +30 -0
  37. package/src/index.ts +28 -59
  38. package/src/init/createSubscriptionInitModule.ts +1 -1
  39. package/src/presentation/components/details/PremiumStatusBadge.tsx +1 -3
  40. package/src/presentation/hooks/feedback/useFeedbackSubmit.ts +1 -1
  41. package/src/presentation/hooks/index.ts +11 -11
  42. package/src/shared/application/ports/IRevenueCatService.ts +32 -0
  43. package/src/shared/infrastructure/SubscriptionEventBus.ts +51 -0
  44. package/src/application/README.md +0 -50
  45. package/src/domain/README.md +0 -54
  46. package/src/domain/entities/README.md +0 -50
  47. package/src/domain/entities/SubscriptionStatus.test.ts +0 -149
  48. package/src/domain/errors/README.md +0 -53
  49. package/src/domain/value-objects/README.md +0 -50
  50. package/src/infrastructure/README.md +0 -55
  51. package/src/infrastructure/mappers/README.md +0 -21
  52. package/src/infrastructure/models/README.md +0 -26
  53. package/src/infrastructure/repositories/CreditsRepository.ts +0 -132
  54. package/src/infrastructure/repositories/README.md +0 -99
  55. package/src/infrastructure/services/CreditsInitializer.ts +0 -170
  56. package/src/infrastructure/services/README.md +0 -99
  57. package/src/infrastructure/services/SubscriptionInitializer.ts +0 -176
  58. package/src/infrastructure/services/SubscriptionService.ts +0 -133
  59. package/src/infrastructure/services/TrialService.ts +0 -197
  60. package/src/infrastructure/services/app-service-helpers.ts +0 -111
  61. package/src/revenuecat/README.md +0 -104
  62. package/src/revenuecat/application/README.md +0 -43
  63. package/src/revenuecat/application/ports/IRevenueCatService.ts +0 -76
  64. package/src/revenuecat/application/ports/README.md +0 -41
  65. package/src/revenuecat/domain/README.md +0 -48
  66. package/src/revenuecat/domain/constants/README.md +0 -41
  67. package/src/revenuecat/domain/entities/README.md +0 -42
  68. package/src/revenuecat/domain/errors/README.md +0 -53
  69. package/src/revenuecat/domain/types/README.md +0 -41
  70. package/src/revenuecat/domain/value-objects/README.md +0 -41
  71. package/src/revenuecat/index.ts +0 -13
  72. package/src/revenuecat/infrastructure/handlers/PackageHandler.ts +0 -161
  73. package/src/revenuecat/infrastructure/managers/SubscriptionManager.ts +0 -165
  74. package/src/revenuecat/presentation/README.md +0 -42
  75. /package/src/{domain/entities → domains/credits/core}/Credits.ts +0 -0
  76. /package/src/{infrastructure/models → domains/credits/core}/UserCreditsDocument.ts +0 -0
  77. /package/src/{infrastructure/repositories → domains/credits/infrastructure}/CreditsRepositoryProvider.ts +0 -0
  78. /package/src/{presentation/hooks → domains/credits/presentation}/useDeductCredit.ts +0 -0
  79. /package/src/{revenuecat/domain/constants → domains/subscription/core}/RevenueCatConstants.ts +0 -0
  80. /package/src/{revenuecat/domain/errors → domains/subscription/core}/RevenueCatError.ts +0 -0
  81. /package/src/{revenuecat/domain/types → domains/subscription/core}/RevenueCatTypes.ts +0 -0
  82. /package/src/{domain/entities → domains/subscription/core}/SubscriptionConstants.ts +0 -0
  83. /package/src/{revenuecat → domains/subscription}/infrastructure/README.md +0 -0
  84. /package/src/{revenuecat → domains/subscription}/infrastructure/config/README.md +0 -0
  85. /package/src/{revenuecat → domains/subscription}/infrastructure/handlers/README.md +0 -0
  86. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/README.md +0 -0
  87. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/subscriptionQueryKeys.ts +0 -0
  88. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useCustomerInfo.ts +0 -0
  89. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useInitializeSubscription.ts +0 -0
  90. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePaywallFlow.ts +0 -0
  91. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePurchasePackage.ts +0 -0
  92. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRestorePurchase.ts +0 -0
  93. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCatTrialEligibility.ts +0 -0
  94. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionPackages.ts +0 -0
  95. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionQueries.ts +0 -0
  96. /package/src/{revenuecat → domains/subscription}/infrastructure/managers/README.md +0 -0
  97. /package/src/{revenuecat → domains/subscription}/infrastructure/services/CustomerInfoListenerManager.ts +0 -0
  98. /package/src/{revenuecat → domains/subscription}/infrastructure/services/OfferingsFetcher.ts +0 -0
  99. /package/src/{revenuecat → domains/subscription}/infrastructure/services/README.md +0 -0
  100. /package/src/{revenuecat → domains/subscription}/infrastructure/services/ServiceStateManager.ts +0 -0
  101. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/ApiKeyResolver.ts +0 -0
  102. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/InitializationCache.ts +0 -0
  103. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/PremiumStatusSyncer.ts +0 -0
  104. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/README.md +0 -0
  105. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/RenewalDetector.ts +0 -0
  106. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/UserIdProvider.ts +0 -0
  107. /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthAwarePurchase.ts +0 -0
  108. /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthSubscriptionSync.ts +0 -0
  109. /package/src/{presentation/hooks → domains/subscription/presentation}/useFeatureGate.ts +0 -0
  110. /package/src/{presentation/hooks → domains/subscription/presentation}/usePaywallVisibility.ts +0 -0
  111. /package/src/{presentation/hooks → domains/subscription/presentation}/usePremiumGate.ts +0 -0
  112. /package/src/{presentation/hooks → domains/subscription/presentation}/useSavedPurchaseAutoExecution.ts +0 -0
  113. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.ts +0 -0
  114. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.utils.ts +0 -0
  115. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionStatus.ts +0 -0
  116. /package/src/{infrastructure/services → shared/application}/ActivationHandler.ts +0 -0
  117. /package/src/{infrastructure/services → shared/application}/FeedbackService.ts +0 -0
  118. /package/src/{application → shared/application}/ports/ISubscriptionRepository.ts +0 -0
  119. /package/src/{application → shared/application}/ports/ISubscriptionService.ts +0 -0
  120. /package/src/{application → shared/application}/ports/README.md +0 -0
  121. /package/src/{domain/errors → shared/utils}/InsufficientCreditsError.ts +0 -0
  122. /package/src/{infrastructure → shared}/utils/Logger.ts +0 -0
  123. /package/src/{domain/value-objects → shared/utils}/Result.ts +0 -0
  124. /package/src/{domain/value-objects → shared/utils}/SubscriptionConfig.ts +0 -0
  125. /package/src/{domain/errors → shared/utils}/SubscriptionError.ts +0 -0
@@ -1,161 +0,0 @@
1
- /**
2
- * Package Handler
3
- * Handles package operations (fetch, purchase, restore, premium status)
4
- */
5
-
6
- import type { PurchasesPackage, CustomerInfo } from "react-native-purchases";
7
- import type { IRevenueCatService } from "../../application/ports/IRevenueCatService";
8
- import { getPremiumEntitlement } from "../../domain/types/RevenueCatTypes";
9
-
10
- export interface PremiumStatus {
11
- isPremium: boolean;
12
- expirationDate: Date | null;
13
- }
14
-
15
- export interface RestoreResultInfo {
16
- success: boolean;
17
- productId: string | null;
18
- }
19
-
20
- export class PackageHandler {
21
- constructor(
22
- private service: IRevenueCatService | null,
23
- private entitlementId: string
24
- ) { }
25
-
26
- setService(service: IRevenueCatService | null): void {
27
- this.service = service;
28
- }
29
-
30
- async fetchPackages(): Promise<PurchasesPackage[]> {
31
- if (__DEV__) {
32
- console.log('[DEBUG PackageHandler] fetchPackages called', {
33
- hasService: !!this.service,
34
- isInitialized: this.service?.isInitialized(),
35
- });
36
- }
37
- if (!this.service?.isInitialized()) {
38
- if (__DEV__) {
39
- console.log('[DEBUG PackageHandler] Service not initialized, returning empty');
40
- }
41
- return [];
42
- }
43
-
44
- try {
45
- const offering = await this.service.fetchOfferings();
46
-
47
- if (__DEV__) {
48
- console.log('[DEBUG PackageHandler] fetchOfferings result:', {
49
- hasOffering: !!offering,
50
- identifier: offering?.identifier,
51
- packagesCount: offering?.availablePackages?.length ?? 0,
52
- packages: offering?.availablePackages?.map(p => ({
53
- identifier: p.identifier,
54
- productIdentifier: p.product.identifier,
55
- offeringIdentifier: p.offeringIdentifier
56
- }))
57
- });
58
- }
59
-
60
- return offering?.availablePackages ?? [];
61
- } catch (error) {
62
- if (__DEV__) {
63
- console.error('[DEBUG PackageHandler] fetchOfferings failed:', error);
64
- }
65
- return [];
66
- }
67
- }
68
-
69
- async purchase(pkg: PurchasesPackage, userId: string): Promise<boolean> {
70
- if (__DEV__) {
71
- console.log('[DEBUG PackageHandler] purchase() called', {
72
- productId: pkg.product.identifier,
73
- userId,
74
- serviceExists: !!this.service,
75
- isInitialized: this.service?.isInitialized(),
76
- });
77
- }
78
-
79
- if (!this.service?.isInitialized()) {
80
- if (__DEV__) {
81
- console.log('[DEBUG PackageHandler] Service not initialized', {
82
- productId: pkg.product.identifier,
83
- });
84
- }
85
- return false;
86
- }
87
-
88
- try {
89
- if (__DEV__) {
90
- console.log('[DEBUG PackageHandler] Calling service.purchasePackage...');
91
- }
92
- const result = await this.service.purchasePackage(pkg, userId);
93
- if (__DEV__) {
94
- console.log('[DEBUG PackageHandler] Purchase result:', {
95
- success: result.success,
96
- productId: pkg.product.identifier,
97
- isPremium: result.isPremium,
98
- });
99
- }
100
- return result.success;
101
- } catch (error) {
102
- if (__DEV__) {
103
- console.error('[DEBUG PackageHandler] Purchase failed:', {
104
- error,
105
- productId: pkg.product.identifier,
106
- });
107
- }
108
- return false;
109
- }
110
- }
111
-
112
- async restore(userId: string): Promise<RestoreResultInfo> {
113
- if (!this.service?.isInitialized()) {
114
- return { success: false, productId: null };
115
- }
116
-
117
- try {
118
- const result = await this.service.restorePurchases(userId);
119
-
120
- // Extract product ID from active entitlement
121
- let productId: string | null = null;
122
- if (result.success && result.customerInfo) {
123
- const entitlement = getPremiumEntitlement(
124
- result.customerInfo,
125
- this.entitlementId
126
- );
127
- if (entitlement) {
128
- productId = entitlement.productIdentifier;
129
- }
130
- }
131
-
132
- return { success: result.success, productId };
133
- } catch (error) {
134
- if (__DEV__) {
135
- console.error('[DEBUG PackageHandler] Restore failed:', {
136
- error,
137
- userId,
138
- });
139
- }
140
- return { success: false, productId: null };
141
- }
142
- }
143
-
144
- checkPremiumStatusFromInfo(customerInfo: CustomerInfo): PremiumStatus {
145
- const entitlement = getPremiumEntitlement(customerInfo, this.entitlementId);
146
-
147
- if (entitlement) {
148
- return {
149
- isPremium: true,
150
- expirationDate: entitlement.expirationDate
151
- ? new Date(entitlement.expirationDate)
152
- : null,
153
- };
154
- }
155
-
156
- return {
157
- isPremium: false,
158
- expirationDate: null,
159
- };
160
- }
161
- }
@@ -1,165 +0,0 @@
1
- /**
2
- * Subscription Manager
3
- * Facade for subscription operations
4
- * Coordinates UserIdProvider, InitializationCache, and PackageHandler
5
- */
6
-
7
- import type { PurchasesPackage } from "react-native-purchases";
8
- import type { RevenueCatConfig } from "../../domain/value-objects/RevenueCatConfig";
9
- import type { IRevenueCatService } from "../../application/ports/IRevenueCatService";
10
- import { initializeRevenueCatService, getRevenueCatService } from "../services/RevenueCatService";
11
- import { UserIdProvider } from "../utils/UserIdProvider";
12
- import { InitializationCache } from "../utils/InitializationCache";
13
- import { PackageHandler } from "../handlers/PackageHandler";
14
- import type { PremiumStatus, RestoreResultInfo } from "../handlers/PackageHandler";
15
-
16
- export interface SubscriptionManagerConfig {
17
- config: RevenueCatConfig;
18
- apiKey: string;
19
- getAnonymousUserId?: () => Promise<string>;
20
- }
21
-
22
- class SubscriptionManagerImpl {
23
- private managerConfig: SubscriptionManagerConfig | null = null;
24
- private serviceInstance: IRevenueCatService | null = null;
25
- private userIdProvider = new UserIdProvider();
26
- private initCache = new InitializationCache();
27
- private packageHandler: PackageHandler | null = null;
28
-
29
- configure(config: SubscriptionManagerConfig): void {
30
- this.managerConfig = config;
31
- this.packageHandler = new PackageHandler(null, config.config.entitlementIdentifier);
32
-
33
- if (config.getAnonymousUserId) {
34
- this.userIdProvider.configure(config.getAnonymousUserId);
35
- }
36
- }
37
-
38
- private ensureConfigured(): void {
39
- if (!this.managerConfig || !this.packageHandler) {
40
- throw new Error("SubscriptionManager not configured");
41
- }
42
- }
43
-
44
- private async performInitialization(userId: string): Promise<boolean> {
45
- this.ensureConfigured();
46
-
47
- await initializeRevenueCatService(this.managerConfig!.config);
48
- this.serviceInstance = getRevenueCatService();
49
-
50
- if (!this.serviceInstance) {
51
- return false;
52
- }
53
-
54
- this.packageHandler!.setService(this.serviceInstance);
55
-
56
- const result = await this.serviceInstance.initialize(userId);
57
- return result.success;
58
- }
59
-
60
- async initialize(userId?: string): Promise<boolean> {
61
- this.ensureConfigured();
62
-
63
- const effectiveUserId = userId || (await this.userIdProvider.getOrCreateAnonymousUserId());
64
-
65
- // Atomic check-and-acquire to prevent race conditions
66
- const { shouldInit, existingPromise } = this.initCache.tryAcquireInitialization(effectiveUserId);
67
-
68
- if (!shouldInit && existingPromise) {
69
- return existingPromise;
70
- }
71
-
72
- const promise = this.performInitialization(effectiveUserId);
73
- this.initCache.setPromise(promise, effectiveUserId);
74
-
75
- return promise;
76
- }
77
-
78
- isConfigured(): boolean {
79
- return this.managerConfig !== null && this.packageHandler !== null;
80
- }
81
-
82
- isInitialized(): boolean {
83
- return this.serviceInstance?.isInitialized() ?? false;
84
- }
85
-
86
- isInitializedForUser(userId: string): boolean {
87
- return this.serviceInstance?.isInitialized() === true &&
88
- this.initCache.getCurrentUserId() === userId;
89
- }
90
-
91
- getEntitlementId(): string | null {
92
- return this.managerConfig?.config.entitlementIdentifier || null;
93
- }
94
-
95
- async getPackages(): Promise<PurchasesPackage[]> {
96
- if (__DEV__) {
97
- console.log('[DEBUG SubscriptionManager] getPackages called', {
98
- isConfigured: this.isConfigured(),
99
- isInitialized: this.isInitialized(),
100
- hasServiceInstance: !!this.serviceInstance,
101
- });
102
- }
103
- this.ensureConfigured();
104
- if (!this.serviceInstance) {
105
- this.serviceInstance = getRevenueCatService();
106
- this.packageHandler!.setService(this.serviceInstance);
107
- }
108
- return this.packageHandler!.fetchPackages();
109
- }
110
-
111
- async purchasePackage(pkg: PurchasesPackage): Promise<boolean> {
112
- if (__DEV__) {
113
- console.log('[DEBUG SubscriptionManager] purchasePackage called', {
114
- productId: pkg.product.identifier,
115
- isConfigured: this.isConfigured(),
116
- isInitialized: this.isInitialized(),
117
- });
118
- }
119
- this.ensureConfigured();
120
- const userId = this.initCache.getCurrentUserId();
121
- if (__DEV__) {
122
- console.log('[DEBUG SubscriptionManager] userId from cache:', userId);
123
- }
124
- if (!userId) {
125
- if (__DEV__) {
126
- console.log('[DEBUG SubscriptionManager] No userId, returning false');
127
- }
128
- return false;
129
- }
130
- return this.packageHandler!.purchase(pkg, userId);
131
- }
132
-
133
- async restore(): Promise<RestoreResultInfo> {
134
- this.ensureConfigured();
135
- const userId = this.initCache.getCurrentUserId();
136
- if (!userId) return { success: false, productId: null };
137
- return this.packageHandler!.restore(userId);
138
- }
139
-
140
- async checkPremiumStatus(): Promise<PremiumStatus> {
141
- this.ensureConfigured();
142
- const userId = this.initCache.getCurrentUserId();
143
- if (!userId) return { isPremium: false, expirationDate: null };
144
-
145
- const customerInfo = await this.serviceInstance?.getCustomerInfo();
146
- if (customerInfo) {
147
- return this.packageHandler!.checkPremiumStatusFromInfo(customerInfo);
148
- }
149
-
150
- return { isPremium: false, expirationDate: null };
151
- }
152
-
153
- async reset(): Promise<void> {
154
- if (this.serviceInstance) {
155
- await this.serviceInstance.reset();
156
- }
157
- this.initCache.reset();
158
- this.userIdProvider.reset();
159
- this.serviceInstance = null;
160
- }
161
- }
162
-
163
- export const SubscriptionManager = new SubscriptionManagerImpl();
164
-
165
- export type { PremiumStatus };
@@ -1,42 +0,0 @@
1
- # RevenueCat Presentation
2
-
3
- ## Location
4
- Presentation layer for RevenueCat integration.
5
-
6
- ## Strategy
7
- This directory contains React hooks, components, and utilities for integrating RevenueCat functionality into the UI layer with proper loading states, error handling, and caching.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must show loading states during async operations
13
- - Must handle and display errors appropriately
14
- - Must cache customer info and offerings
15
- - Must re-render on entitlement changes
16
-
17
- ### PROHIBITED
18
- - DO NOT skip loading states
19
- - DO NOT show technical errors to users
20
- - DO NOT ignore cache invalidation
21
- - DO NOT prevent re-renders on state changes
22
-
23
- ### CRITICAL SAFETY
24
- - All async operations MUST show loading states
25
- - All errors MUST be handled and displayed appropriately
26
- - Data MUST be cached appropriately
27
- - UI MUST re-render on entitlement changes
28
-
29
- ## AI Agent Guidelines
30
- 1. Always show loading states during async operations
31
- 2. Handle and display errors appropriately to users
32
- 3. Update UI optimistically where possible
33
- 4. Cache customer info and offerings appropriately
34
- 5. Re-render on entitlement changes
35
- 6. Provide clear feedback during purchases
36
- 7. Validate data before displaying to users
37
-
38
- ## Related Documentation
39
- - [RevenueCat Integration](../README.md)
40
- - [RevenueCat Application](../application/README.md)
41
- - [RevenueCat Infrastructure](../infrastructure/README.md)
42
- - [RevenueCat Domain](../domain/README.md)
File without changes