@billdog.io/react-native 1.0.0-beta.2

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 (309) hide show
  1. package/BillDogReactNative.podspec +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +330 -0
  4. package/android/build.gradle +99 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/kotlin/io/billdog/reactnative/BillDogABTestModule.kt +317 -0
  7. package/android/src/main/kotlin/io/billdog/reactnative/BillDogAnalyticsModule.kt +389 -0
  8. package/android/src/main/kotlin/io/billdog/reactnative/BillDogModule.kt +817 -0
  9. package/android/src/main/kotlin/io/billdog/reactnative/BillDogPaywallViewManager.kt +383 -0
  10. package/android/src/main/kotlin/io/billdog/reactnative/BillDogSurveyModule.kt +427 -0
  11. package/android/src/main/kotlin/io/billdog/reactnative/BillDogVirtualCurrencyModule.kt +407 -0
  12. package/android/src/main/kotlin/io/billdog/virtualcurrency/BillDogVirtualCurrencyPackage.kt +44 -0
  13. package/dist/AdvancedPaywallCache.d.ts +70 -0
  14. package/dist/AdvancedPaywallCache.js +344 -0
  15. package/dist/BillDog.d.ts +255 -0
  16. package/dist/BillDog.js +918 -0
  17. package/dist/BillDogConfiguration.d.ts +145 -0
  18. package/dist/BillDogConfiguration.js +229 -0
  19. package/dist/ComponentRenderer.d.ts +17 -0
  20. package/dist/ComponentRenderer.js +886 -0
  21. package/dist/LayoutEngine.d.ts +101 -0
  22. package/dist/LayoutEngine.js +394 -0
  23. package/dist/LocalizationResolver.d.ts +99 -0
  24. package/dist/LocalizationResolver.js +266 -0
  25. package/dist/NativePaywallView.d.ts +36 -0
  26. package/dist/NativePaywallView.js +59 -0
  27. package/dist/PaywallCache.d.ts +74 -0
  28. package/dist/PaywallCache.js +293 -0
  29. package/dist/PaywallStateManager.d.ts +62 -0
  30. package/dist/PaywallStateManager.js +147 -0
  31. package/dist/PaywallView.d.ts +42 -0
  32. package/dist/PaywallView.js +275 -0
  33. package/dist/ProductVariableProvider.d.ts +60 -0
  34. package/dist/ProductVariableProvider.js +239 -0
  35. package/dist/VariableResolver.d.ts +120 -0
  36. package/dist/VariableResolver.js +379 -0
  37. package/dist/WebViewPaywall.d.ts +75 -0
  38. package/dist/WebViewPaywall.js +360 -0
  39. package/dist/animations/presets.d.ts +49 -0
  40. package/dist/animations/presets.js +367 -0
  41. package/dist/components/AccoladeCpsComponent.d.ts +13 -0
  42. package/dist/components/AccoladeCpsComponent.js +248 -0
  43. package/dist/components/AccordionComponent.d.ts +10 -0
  44. package/dist/components/AccordionComponent.js +187 -0
  45. package/dist/components/AnimatedWrapper.d.ts +35 -0
  46. package/dist/components/AnimatedWrapper.js +277 -0
  47. package/dist/components/CarouselComponent.d.ts +23 -0
  48. package/dist/components/CarouselComponent.js +484 -0
  49. package/dist/components/ChartCurveComponent.d.ts +13 -0
  50. package/dist/components/ChartCurveComponent.js +333 -0
  51. package/dist/components/CheckboxComponent.d.ts +9 -0
  52. package/dist/components/CheckboxComponent.js +172 -0
  53. package/dist/components/ConfettiComponent.d.ts +9 -0
  54. package/dist/components/ConfettiComponent.js +172 -0
  55. package/dist/components/CountdownComponent.d.ts +16 -0
  56. package/dist/components/CountdownComponent.js +414 -0
  57. package/dist/components/DelayedXComponent.d.ts +12 -0
  58. package/dist/components/DelayedXComponent.js +240 -0
  59. package/dist/components/DrawerModalComponent.d.ts +20 -0
  60. package/dist/components/DrawerModalComponent.js +286 -0
  61. package/dist/components/GradientView.d.ts +38 -0
  62. package/dist/components/GradientView.js +126 -0
  63. package/dist/components/HapticFeedbackComponent.d.ts +16 -0
  64. package/dist/components/HapticFeedbackComponent.js +64 -0
  65. package/dist/components/HorizontalProductsComponent.d.ts +17 -0
  66. package/dist/components/HorizontalProductsComponent.js +284 -0
  67. package/dist/components/MultiChoiceGridComponent.d.ts +13 -0
  68. package/dist/components/MultiChoiceGridComponent.js +234 -0
  69. package/dist/components/NPSScaleComponent.d.ts +16 -0
  70. package/dist/components/NPSScaleComponent.js +260 -0
  71. package/dist/components/NavigationComponent.d.ts +26 -0
  72. package/dist/components/NavigationComponent.js +302 -0
  73. package/dist/components/OAuthButtonComponent.d.ts +20 -0
  74. package/dist/components/OAuthButtonComponent.js +237 -0
  75. package/dist/components/ProgressLoaderComponent.d.ts +13 -0
  76. package/dist/components/ProgressLoaderComponent.js +308 -0
  77. package/dist/components/ProgressStepperComponent.d.ts +18 -0
  78. package/dist/components/ProgressStepperComponent.js +228 -0
  79. package/dist/components/SegmentedPickerComponent.d.ts +10 -0
  80. package/dist/components/SegmentedPickerComponent.js +221 -0
  81. package/dist/components/ShareButtonsComponent.d.ts +21 -0
  82. package/dist/components/ShareButtonsComponent.js +265 -0
  83. package/dist/components/ShareCodeComponent.d.ts +16 -0
  84. package/dist/components/ShareCodeComponent.js +274 -0
  85. package/dist/components/SingleChoiceGridComponent.d.ts +13 -0
  86. package/dist/components/SingleChoiceGridComponent.js +210 -0
  87. package/dist/components/SliderComponent.d.ts +9 -0
  88. package/dist/components/SliderComponent.js +263 -0
  89. package/dist/components/StarRatingInputComponent.d.ts +20 -0
  90. package/dist/components/StarRatingInputComponent.js +198 -0
  91. package/dist/components/StickerCompositeComponent.d.ts +13 -0
  92. package/dist/components/StickerCompositeComponent.js +136 -0
  93. package/dist/components/TabsComponent.d.ts +19 -0
  94. package/dist/components/TabsComponent.js +431 -0
  95. package/dist/components/TextInputComponent.d.ts +18 -0
  96. package/dist/components/TextInputComponent.js +227 -0
  97. package/dist/components/TimelineComponent.d.ts +19 -0
  98. package/dist/components/TimelineComponent.js +104 -0
  99. package/dist/components/ToggleComponent.d.ts +14 -0
  100. package/dist/components/ToggleComponent.js +132 -0
  101. package/dist/components/VerticalProductsComponent.d.ts +17 -0
  102. package/dist/components/VerticalProductsComponent.js +311 -0
  103. package/dist/dynamicValues.d.ts +36 -0
  104. package/dist/dynamicValues.js +142 -0
  105. package/dist/filters/dateFilters.d.ts +50 -0
  106. package/dist/filters/dateFilters.js +390 -0
  107. package/dist/filters/index.d.ts +18 -0
  108. package/dist/filters/index.js +253 -0
  109. package/dist/hooks/useOfferings.d.ts +76 -0
  110. package/dist/hooks/useOfferings.js +99 -0
  111. package/dist/hooks/usePaywall.d.ts +27 -0
  112. package/dist/hooks/usePaywall.js +114 -0
  113. package/dist/hooks/usePlacement.d.ts +34 -0
  114. package/dist/hooks/usePlacement.js +89 -0
  115. package/dist/hooks/useSubscription.d.ts +40 -0
  116. package/dist/hooks/useSubscription.js +97 -0
  117. package/dist/index.d.ts +98 -0
  118. package/dist/index.js +198 -0
  119. package/dist/models/BillDogError.d.ts +40 -0
  120. package/dist/models/BillDogError.js +11 -0
  121. package/dist/models/CacheFetchPolicy.d.ts +8 -0
  122. package/dist/models/CacheFetchPolicy.js +4 -0
  123. package/dist/models/CustomProduct.d.ts +32 -0
  124. package/dist/models/CustomProduct.js +15 -0
  125. package/dist/models/CustomerInfo.d.ts +17 -0
  126. package/dist/models/CustomerInfo.js +11 -0
  127. package/dist/models/Delegate.d.ts +20 -0
  128. package/dist/models/Delegate.js +11 -0
  129. package/dist/models/EntitlementInfo.d.ts +19 -0
  130. package/dist/models/EntitlementInfo.js +2 -0
  131. package/dist/models/Placement.d.ts +54 -0
  132. package/dist/models/Placement.js +15 -0
  133. package/dist/models/PurchaseParams.d.ts +39 -0
  134. package/dist/models/PurchaseParams.js +60 -0
  135. package/dist/models/PurchaseResult.d.ts +30 -0
  136. package/dist/models/PurchaseResult.js +15 -0
  137. package/dist/models/RestoreResult.d.ts +30 -0
  138. package/dist/models/RestoreResult.js +22 -0
  139. package/dist/models/RestoredItem.d.ts +26 -0
  140. package/dist/models/RestoredItem.js +13 -0
  141. package/dist/modules/ABTest.d.ts +65 -0
  142. package/dist/modules/ABTest.js +113 -0
  143. package/dist/modules/Analytics.d.ts +91 -0
  144. package/dist/modules/Analytics.js +182 -0
  145. package/dist/modules/Survey.d.ts +65 -0
  146. package/dist/modules/Survey.js +82 -0
  147. package/dist/modules/VirtualCurrency.d.ts +63 -0
  148. package/dist/modules/VirtualCurrency.js +147 -0
  149. package/dist/murmur.d.ts +23 -0
  150. package/dist/murmur.js +104 -0
  151. package/dist/notifications/LiveActivitiesManager.d.ts +47 -0
  152. package/dist/notifications/LiveActivitiesManager.js +106 -0
  153. package/dist/notifications/NotificationScheduler.d.ts +55 -0
  154. package/dist/notifications/NotificationScheduler.js +199 -0
  155. package/dist/notifications/PurchaseNotificationHandler.d.ts +24 -0
  156. package/dist/notifications/PurchaseNotificationHandler.js +55 -0
  157. package/dist/notifications/useDeviceToken.d.ts +36 -0
  158. package/dist/notifications/useDeviceToken.js +97 -0
  159. package/dist/notifications/useLiveActivity.d.ts +39 -0
  160. package/dist/notifications/useLiveActivity.js +104 -0
  161. package/dist/review/ReviewAnalytics.d.ts +34 -0
  162. package/dist/review/ReviewAnalytics.js +73 -0
  163. package/dist/review/ReviewManager.d.ts +83 -0
  164. package/dist/review/ReviewManager.js +339 -0
  165. package/dist/review/ReviewTimingManager.d.ts +82 -0
  166. package/dist/review/ReviewTimingManager.js +224 -0
  167. package/dist/survey-core/types.d.ts +215 -0
  168. package/dist/survey-core/types.js +8 -0
  169. package/dist/types.d.ts +438 -0
  170. package/dist/types.js +158 -0
  171. package/dist/utils/ApiClient.d.ts +65 -0
  172. package/dist/utils/ApiClient.js +132 -0
  173. package/dist/utils/CSSConverter.d.ts +49 -0
  174. package/dist/utils/CSSConverter.js +470 -0
  175. package/dist/utils/animations.d.ts +41 -0
  176. package/dist/utils/animations.js +194 -0
  177. package/dist/utils/calendarIntegration.d.ts +36 -0
  178. package/dist/utils/calendarIntegration.js +89 -0
  179. package/dist/utils/configurationResolver.d.ts +23 -0
  180. package/dist/utils/configurationResolver.js +78 -0
  181. package/dist/utils/deviceDetection.d.ts +38 -0
  182. package/dist/utils/deviceDetection.js +59 -0
  183. package/dist/utils/hapticFeedback.d.ts +17 -0
  184. package/dist/utils/hapticFeedback.js +53 -0
  185. package/dist/utils/iconMapper.d.ts +26 -0
  186. package/dist/utils/iconMapper.js +113 -0
  187. package/dist/utils/notificationPermissions.d.ts +13 -0
  188. package/dist/utils/notificationPermissions.js +51 -0
  189. package/dist/utils/priceFormatting.d.ts +19 -0
  190. package/dist/utils/priceFormatting.js +99 -0
  191. package/dist/utils/shareSheet.d.ts +17 -0
  192. package/dist/utils/shareSheet.js +42 -0
  193. package/dist/utils/subscriptionUpgrade.d.ts +84 -0
  194. package/dist/utils/subscriptionUpgrade.js +100 -0
  195. package/dist/valueUtils.d.ts +48 -0
  196. package/dist/valueUtils.js +129 -0
  197. package/dist/xFlowTags.d.ts +18 -0
  198. package/dist/xFlowTags.js +385 -0
  199. package/ios/BillDogABTest.m +50 -0
  200. package/ios/BillDogABTest.swift +188 -0
  201. package/ios/BillDogAnalytics.m +105 -0
  202. package/ios/BillDogAnalytics.swift +324 -0
  203. package/ios/BillDogBridge.m +222 -0
  204. package/ios/BillDogBridge.swift +715 -0
  205. package/ios/BillDogLiveActivities.m +41 -0
  206. package/ios/BillDogLiveActivities.swift +104 -0
  207. package/ios/BillDogPaywallViewManager.m +39 -0
  208. package/ios/BillDogPaywallViewManager.swift +361 -0
  209. package/ios/BillDogSurvey.m +34 -0
  210. package/ios/BillDogSurvey.swift +257 -0
  211. package/ios/BillDogVirtualCurrencyBridge.m +63 -0
  212. package/ios/BillDogVirtualCurrencyBridge.swift +511 -0
  213. package/junit.xml +25 -0
  214. package/package.json +61 -0
  215. package/react-native.config.js +13 -0
  216. package/src/AdvancedPaywallCache.ts +433 -0
  217. package/src/BillDog.ts +983 -0
  218. package/src/BillDogConfiguration.ts +318 -0
  219. package/src/ComponentRenderer.tsx +1325 -0
  220. package/src/LayoutEngine.ts +459 -0
  221. package/src/LocalizationResolver.ts +311 -0
  222. package/src/NativePaywallView.tsx +132 -0
  223. package/src/PaywallCache.ts +358 -0
  224. package/src/PaywallStateManager.ts +154 -0
  225. package/src/PaywallView.tsx +328 -0
  226. package/src/ProductVariableProvider.ts +282 -0
  227. package/src/VariableResolver.ts +516 -0
  228. package/src/WebViewPaywall.tsx +454 -0
  229. package/src/animations/presets.ts +421 -0
  230. package/src/components/AccoladeCpsComponent.tsx +259 -0
  231. package/src/components/AccordionComponent.tsx +213 -0
  232. package/src/components/AnimatedWrapper.tsx +316 -0
  233. package/src/components/CarouselComponent.tsx +615 -0
  234. package/src/components/ChartCurveComponent.tsx +452 -0
  235. package/src/components/CheckboxComponent.tsx +185 -0
  236. package/src/components/ConfettiComponent.tsx +178 -0
  237. package/src/components/CountdownComponent.tsx +454 -0
  238. package/src/components/DelayedXComponent.tsx +266 -0
  239. package/src/components/DrawerModalComponent.tsx +324 -0
  240. package/src/components/GradientView.tsx +129 -0
  241. package/src/components/HapticFeedbackComponent.tsx +39 -0
  242. package/src/components/HorizontalProductsComponent.tsx +329 -0
  243. package/src/components/MultiChoiceGridComponent.tsx +265 -0
  244. package/src/components/NPSScaleComponent.tsx +294 -0
  245. package/src/components/NavigationComponent.tsx +329 -0
  246. package/src/components/OAuthButtonComponent.tsx +266 -0
  247. package/src/components/ProgressLoaderComponent.tsx +366 -0
  248. package/src/components/ProgressStepperComponent.tsx +250 -0
  249. package/src/components/SegmentedPickerComponent.tsx +245 -0
  250. package/src/components/ShareButtonsComponent.tsx +299 -0
  251. package/src/components/ShareCodeComponent.tsx +303 -0
  252. package/src/components/SingleChoiceGridComponent.tsx +229 -0
  253. package/src/components/SliderComponent.tsx +280 -0
  254. package/src/components/StarRatingInputComponent.tsx +223 -0
  255. package/src/components/StickerCompositeComponent.tsx +168 -0
  256. package/src/components/TabsComponent.tsx +496 -0
  257. package/src/components/TextInputComponent.tsx +258 -0
  258. package/src/components/TimelineComponent.tsx +129 -0
  259. package/src/components/ToggleComponent.tsx +142 -0
  260. package/src/components/VerticalProductsComponent.tsx +357 -0
  261. package/src/dynamicValues.ts +180 -0
  262. package/src/filters/dateFilters.ts +411 -0
  263. package/src/filters/index.ts +281 -0
  264. package/src/hooks/useOfferings.ts +192 -0
  265. package/src/hooks/usePaywall.ts +154 -0
  266. package/src/hooks/usePlacement.ts +143 -0
  267. package/src/hooks/useSubscription.ts +154 -0
  268. package/src/index.ts +245 -0
  269. package/src/models/BillDogError.ts +24 -0
  270. package/src/models/CacheFetchPolicy.ts +13 -0
  271. package/src/models/CustomProduct.ts +33 -0
  272. package/src/models/CustomerInfo.ts +26 -0
  273. package/src/models/Delegate.ts +22 -0
  274. package/src/models/EntitlementInfo.ts +27 -0
  275. package/src/models/Placement.ts +50 -0
  276. package/src/models/PurchaseParams.ts +81 -0
  277. package/src/models/PurchaseResult.ts +32 -0
  278. package/src/models/RestoreResult.ts +27 -0
  279. package/src/models/RestoredItem.ts +25 -0
  280. package/src/modules/ABTest.ts +131 -0
  281. package/src/modules/Analytics.ts +227 -0
  282. package/src/modules/Survey.ts +126 -0
  283. package/src/modules/VirtualCurrency.ts +223 -0
  284. package/src/murmur.ts +102 -0
  285. package/src/notifications/LiveActivitiesManager.ts +140 -0
  286. package/src/notifications/NotificationScheduler.ts +292 -0
  287. package/src/notifications/PurchaseNotificationHandler.ts +67 -0
  288. package/src/notifications/useDeviceToken.ts +116 -0
  289. package/src/notifications/useLiveActivity.ts +125 -0
  290. package/src/review/ReviewAnalytics.ts +89 -0
  291. package/src/review/ReviewManager.ts +355 -0
  292. package/src/review/ReviewTimingManager.ts +265 -0
  293. package/src/survey-core/types.ts +244 -0
  294. package/src/types/ambient.d.ts +9 -0
  295. package/src/types.ts +680 -0
  296. package/src/utils/ApiClient.ts +163 -0
  297. package/src/utils/CSSConverter.ts +552 -0
  298. package/src/utils/animations.ts +232 -0
  299. package/src/utils/calendarIntegration.ts +113 -0
  300. package/src/utils/configurationResolver.ts +106 -0
  301. package/src/utils/deviceDetection.ts +83 -0
  302. package/src/utils/hapticFeedback.ts +55 -0
  303. package/src/utils/iconMapper.ts +102 -0
  304. package/src/utils/notificationPermissions.ts +48 -0
  305. package/src/utils/priceFormatting.ts +119 -0
  306. package/src/utils/shareSheet.ts +55 -0
  307. package/src/utils/subscriptionUpgrade.ts +183 -0
  308. package/src/valueUtils.ts +108 -0
  309. package/src/xFlowTags.ts +463 -0
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalizationResolver = void 0;
4
+ const react_native_1 = require("react-native");
5
+ const BillDogConfiguration_1 = require("./BillDogConfiguration");
6
+ /**
7
+ * Properties that can be localized
8
+ */
9
+ const LOCALIZABLE_PROPERTIES = new Set([
10
+ 'text', 'title', 'subtitle', 'label', 'placeholder',
11
+ 'buttonText', 'ctaText', 'description', 'content',
12
+ 'headerText', 'footerText', 'disclaimer'
13
+ ]);
14
+ /**
15
+ * Right-to-left languages. CLDR-aligned 11-code set — kept identical to
16
+ * iOS `PaywallRenderer.swift rtlLocales` and Android
17
+ * `PaywallScreen.kt rtlLocales` so layout direction is consistent across
18
+ * every platform.
19
+ */
20
+ const RTL_LOCALES = new Set([
21
+ 'ar', 'he', 'fa', 'ur', 'ps', 'sd', 'yi', 'ku', 'ckb', 'dv', 'ug',
22
+ ]);
23
+ /**
24
+ * Client-side localization resolver for React Native SDK
25
+ * Resolves localized text based on device locale with fallback to baseLocale
26
+ */
27
+ class LocalizationResolver {
28
+ constructor(localizations, baseLocale = 'en', explicitLocale) {
29
+ this.localizations = localizations;
30
+ this.baseLocale = baseLocale;
31
+ // Priority: explicit locale > global config override > device locale
32
+ this.selectedLocale = explicitLocale !== null && explicitLocale !== void 0 ? explicitLocale : this.getEffectiveLocale();
33
+ }
34
+ /**
35
+ * Get the effective locale. Precedence mirrors Android
36
+ * `BillDogConfig.getEffectiveLocale` (BillDogConfig.kt:150-152):
37
+ * runtime locale override > device locale > "en".
38
+ *
39
+ * Public + static so callers (e.g. WebViewPaywall's locale bridge) can
40
+ * resolve the active locale without constructing a resolver.
41
+ */
42
+ static getEffectiveLocale() {
43
+ const configOverride = BillDogConfiguration_1.BillDogConfiguration.getLocaleOverride();
44
+ if (configOverride && configOverride.trim()) {
45
+ return configOverride;
46
+ }
47
+ return LocalizationResolver.detectDeviceLocale();
48
+ }
49
+ /** Instance accessor — defers to the canonical static resolver. */
50
+ getEffectiveLocale() {
51
+ return LocalizationResolver.getEffectiveLocale();
52
+ }
53
+ /**
54
+ * Returns true when `locale`'s language belongs to a right-to-left
55
+ * script. Matches against the language portion only (e.g. `ar-EG` → `ar`),
56
+ * mirroring Android `PaywallScreen.kt:431-458`.
57
+ */
58
+ static isRtlLocale(locale) {
59
+ var _a, _b;
60
+ if (!locale)
61
+ return false;
62
+ const language = (_b = (_a = locale.split(/[-_]/)[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
63
+ return RTL_LOCALES.has(language);
64
+ }
65
+ /** Detect the device locale from the platform native modules. */
66
+ static detectDeviceLocale() {
67
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
68
+ try {
69
+ if (react_native_1.Platform.OS === 'ios') {
70
+ return (((_c = (_b = (_a = react_native_1.NativeModules.SettingsManager) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.AppleLocale) === null || _c === void 0 ? void 0 : _c.split('_')[0]) ||
71
+ ((_g = (_f = (_e = (_d = react_native_1.NativeModules.SettingsManager) === null || _d === void 0 ? void 0 : _d.settings) === null || _e === void 0 ? void 0 : _e.AppleLanguages) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.split('-')[0]) ||
72
+ 'en');
73
+ }
74
+ else if (react_native_1.Platform.OS === 'android') {
75
+ return ((_j = (_h = react_native_1.NativeModules.I18nManager) === null || _h === void 0 ? void 0 : _h.localeIdentifier) === null || _j === void 0 ? void 0 : _j.split('_')[0]) || 'en';
76
+ }
77
+ }
78
+ catch {
79
+ // Fall through to default.
80
+ }
81
+ return 'en';
82
+ }
83
+ /**
84
+ * Set the active locale for resolution
85
+ */
86
+ setLocale(locale) {
87
+ this.selectedLocale = locale;
88
+ }
89
+ /**
90
+ * Get the currently selected locale
91
+ */
92
+ getSelectedLocale() {
93
+ return this.selectedLocale;
94
+ }
95
+ /**
96
+ * Get the base locale (source language)
97
+ */
98
+ getBaseLocale() {
99
+ return this.baseLocale;
100
+ }
101
+ /**
102
+ * Find the matching locale key using the canonical 4-step matcher.
103
+ * Mirrors Android `LocalizationResolver.findLocaleKey` (LocalizationResolver.kt:50-86)
104
+ * and iOS `LocalizationResolver.findLocaleKey` exactly:
105
+ * 1. exact match
106
+ * 2. case-insensitive match
107
+ * 3. separator-normalized match (en-US ↔ en_US)
108
+ * 4. language-only fallback (en-US → en, or en → first en-* regional)
109
+ */
110
+ findLocaleKey(locale) {
111
+ var _a;
112
+ if (!this.localizations || !locale)
113
+ return undefined;
114
+ const keys = Object.keys(this.localizations);
115
+ // Step 1: exact match
116
+ if (this.localizations[locale])
117
+ return locale;
118
+ // Step 2: case-insensitive match
119
+ const lower = locale.toLowerCase();
120
+ const ciMatch = keys.find(k => k.toLowerCase() === lower);
121
+ if (ciMatch)
122
+ return ciMatch;
123
+ // Step 3: separator-normalized match
124
+ const alt = locale.includes('-')
125
+ ? locale.replace(/-/g, '_')
126
+ : locale.replace(/_/g, '-');
127
+ if (alt !== locale) {
128
+ if (this.localizations[alt])
129
+ return alt;
130
+ const altLower = alt.toLowerCase();
131
+ const altMatch = keys.find(k => k.toLowerCase() === altLower);
132
+ if (altMatch)
133
+ return altMatch;
134
+ }
135
+ // Step 4: language-only fallback
136
+ const languageOnly = (_a = locale.split(/[-_]/)[0]) !== null && _a !== void 0 ? _a : '';
137
+ if (languageOnly) {
138
+ const langLower = languageOnly.toLowerCase();
139
+ // Prefer an exact-language key (e.g. "en") over a regional variant
140
+ const exactLang = keys.find(k => k.toLowerCase() === langLower);
141
+ if (exactLang)
142
+ return exactLang;
143
+ // Otherwise any regional variant matching the language
144
+ const regional = keys.find(k => { var _a; return ((_a = k.split(/[-_]/)[0]) !== null && _a !== void 0 ? _a : '').toLowerCase() === langLower; });
145
+ if (regional)
146
+ return regional;
147
+ }
148
+ return undefined;
149
+ }
150
+ /**
151
+ * Check if current locale is the base locale
152
+ */
153
+ isBaseLocale() {
154
+ return this.selectedLocale.toLowerCase() === this.baseLocale.toLowerCase();
155
+ }
156
+ /**
157
+ * Get available locales from the localization data
158
+ */
159
+ getAvailableLocales() {
160
+ const locales = new Set([this.baseLocale]);
161
+ if (this.localizations) {
162
+ Object.keys(this.localizations).forEach(key => locales.add(key));
163
+ }
164
+ return locales;
165
+ }
166
+ /**
167
+ * Resolve a localization key to its translated value
168
+ * Falls back to defaultValue if translation not found
169
+ */
170
+ resolve(key, defaultValue) {
171
+ // If selected locale is base locale, return default (original) value
172
+ if (this.isBaseLocale()) {
173
+ return defaultValue;
174
+ }
175
+ // Try to find translation for selected locale (case-insensitive)
176
+ const matchedKey = this.findLocaleKey(this.selectedLocale);
177
+ const translations = matchedKey ? this.localizations[matchedKey] : undefined;
178
+ const translated = translations === null || translations === void 0 ? void 0 : translations[key];
179
+ if (translated !== undefined) {
180
+ return translated;
181
+ }
182
+ // Log missing translation for debugging
183
+ console.debug(`[LocalizationResolver] Translation not found for key '${key}' in locale '${this.selectedLocale}', using default`);
184
+ return defaultValue;
185
+ }
186
+ /**
187
+ * Resolve a variable value with localization support
188
+ * Variable keys are prefixed with locale for lookup
189
+ */
190
+ resolveVariable(variableKey, defaultValue) {
191
+ var _a, _b;
192
+ if (this.isBaseLocale()) {
193
+ return defaultValue;
194
+ }
195
+ // Try locale-prefixed key first (e.g., "es.headline" for Spanish)
196
+ const localizedKey = `${this.selectedLocale}.${variableKey}`;
197
+ const matchedKey = this.findLocaleKey(this.selectedLocale);
198
+ const translations = matchedKey ? this.localizations[matchedKey] : undefined;
199
+ return ((_b = (_a = translations === null || translations === void 0 ? void 0 : translations[localizedKey]) !== null && _a !== void 0 ? _a : translations === null || translations === void 0 ? void 0 : translations[variableKey]) !== null && _b !== void 0 ? _b : defaultValue);
200
+ }
201
+ /**
202
+ * Resolve all localizable properties in a component.
203
+ *
204
+ * Lookup keys are componentId-prefixed (`<componentId>.<propertyName>`),
205
+ * matching the shape the dashboard `LocalizationPanel` writes and the
206
+ * Android `VariableResolver.resolveComponent` runtime path
207
+ * (VariableResolver.kt:124-156) + iOS `LocalizationResolver.swift:194-198`.
208
+ * Previously this looked up the source string itself as the key, which
209
+ * never matched the dashboard-authored translation maps.
210
+ */
211
+ resolveComponent(component) {
212
+ var _a, _b;
213
+ const resolvedProperties = {};
214
+ const componentId = (_a = component.id) !== null && _a !== void 0 ? _a : '';
215
+ for (const [key, value] of Object.entries(component.properties || {})) {
216
+ if (typeof value === 'string' && LOCALIZABLE_PROPERTIES.has(key)) {
217
+ const localizationKey = componentId ? `${componentId}.${key}` : key;
218
+ resolvedProperties[key] = this.resolve(localizationKey, value);
219
+ }
220
+ else {
221
+ resolvedProperties[key] = value;
222
+ }
223
+ }
224
+ // Recursively resolve children
225
+ const resolvedChildren = (_b = component.children) === null || _b === void 0 ? void 0 : _b.map(child => this.resolveComponent(child));
226
+ return {
227
+ ...component,
228
+ properties: resolvedProperties,
229
+ children: resolvedChildren,
230
+ };
231
+ }
232
+ /**
233
+ * Resolve all components in a configuration
234
+ */
235
+ resolveConfiguration(config) {
236
+ return {
237
+ ...config,
238
+ components: config.components.map(c => this.resolveComponent(c)),
239
+ };
240
+ }
241
+ // Factory Methods
242
+ /**
243
+ * Create resolver from PaywallConfiguration
244
+ * Respects global locale override from BillDogConfiguration
245
+ */
246
+ static fromConfiguration(config) {
247
+ var _a;
248
+ return new LocalizationResolver(config.localizations, (_a = config.baseLocale) !== null && _a !== void 0 ? _a : 'en');
249
+ }
250
+ /**
251
+ * Create resolver with device locale auto-detected
252
+ * Respects global locale override from BillDogConfiguration
253
+ */
254
+ static withDeviceLocale(config) {
255
+ var _a;
256
+ return new LocalizationResolver(config.localizations, (_a = config.baseLocale) !== null && _a !== void 0 ? _a : 'en');
257
+ }
258
+ /**
259
+ * Create resolver with specific locale (overrides global config)
260
+ */
261
+ static withLocale(config, locale) {
262
+ var _a;
263
+ return new LocalizationResolver(config.localizations, (_a = config.baseLocale) !== null && _a !== void 0 ? _a : 'en', locale);
264
+ }
265
+ }
266
+ exports.LocalizationResolver = LocalizationResolver;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * NativePaywallView — renders a BillDog paywall by embedding the NATIVE paywall view
3
+ * (SwiftUI/UIKit on iOS, Jetpack Compose on Android) via a legacy (Paper) native
4
+ * component (`BDPaywallView`). This is the thin-bridge "Option 2" inline path: the
5
+ * native BillDog SDK renders the paywall and handles purchases; this component only
6
+ * hosts it and forwards its events.
7
+ *
8
+ * The pure-JS `PaywallView`/`ComponentRenderer` and `WebViewPaywall` remain available
9
+ * as alternative rendering strategies (e.g. for environments without the native module).
10
+ */
11
+ import React from 'react';
12
+ import { type ViewStyle } from 'react-native';
13
+ export interface NativePaywallViewProps {
14
+ /** Placement / paywall identifier to load. */
15
+ identifier: string;
16
+ style?: ViewStyle;
17
+ /** Fired after a completed purchase (productId + native result fields). */
18
+ onPurchase?: (productId: string, data?: Record<string, unknown>) => void;
19
+ onDismiss?: () => void;
20
+ onRestore?: () => void;
21
+ onOpenUrl?: (url: string) => void;
22
+ onTrackEvent?: (event: string, data?: Record<string, unknown>) => void;
23
+ onLoaded?: () => void;
24
+ onError?: (message: string) => void;
25
+ /** Rendered when the native paywall component is unavailable on this platform. */
26
+ fallback?: React.ReactNode;
27
+ }
28
+ /**
29
+ * Inline native paywall. Requires the `BDPaywallView` native component (iOS
30
+ * `BillDogPaywallViewManager`, Android `BillDogPaywallViewManager`). When it is not
31
+ * registered, renders `fallback` (or nothing) instead of crashing.
32
+ */
33
+ export declare function NativePaywallView(props: NativePaywallViewProps): React.ReactElement | null;
34
+ /** Whether the native paywall component is available on the current platform. */
35
+ export declare const isNativePaywallAvailable: boolean;
36
+ export default NativePaywallView;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ var _a;
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isNativePaywallAvailable = void 0;
8
+ exports.NativePaywallView = NativePaywallView;
9
+ /**
10
+ * NativePaywallView — renders a BillDog paywall by embedding the NATIVE paywall view
11
+ * (SwiftUI/UIKit on iOS, Jetpack Compose on Android) via a legacy (Paper) native
12
+ * component (`BDPaywallView`). This is the thin-bridge "Option 2" inline path: the
13
+ * native BillDog SDK renders the paywall and handles purchases; this component only
14
+ * hosts it and forwards its events.
15
+ *
16
+ * The pure-JS `PaywallView`/`ComponentRenderer` and `WebViewPaywall` remain available
17
+ * as alternative rendering strategies (e.g. for environments without the native module).
18
+ */
19
+ const react_1 = __importDefault(require("react"));
20
+ const react_native_1 = require("react-native");
21
+ const COMPONENT_NAME = 'BDPaywallView';
22
+ /** True only when the native view manager is actually registered on this platform. */
23
+ const isNativeComponentAvailable = ((_a = react_native_1.UIManager.getViewManagerConfig) === null || _a === void 0 ? void 0 : _a.call(react_native_1.UIManager, COMPONENT_NAME)) != null;
24
+ // Only bind the native component when it exists — requireNativeComponent otherwise
25
+ // logs a hard error on some RN versions.
26
+ const BDPaywallViewNative = isNativeComponentAvailable
27
+ ? (0, react_native_1.requireNativeComponent)(COMPONENT_NAME)
28
+ : null;
29
+ /**
30
+ * Inline native paywall. Requires the `BDPaywallView` native component (iOS
31
+ * `BillDogPaywallViewManager`, Android `BillDogPaywallViewManager`). When it is not
32
+ * registered, renders `fallback` (or nothing) instead of crashing.
33
+ */
34
+ function NativePaywallView(props) {
35
+ const { identifier, style, onPurchase, onDismiss, onRestore, onOpenUrl, onTrackEvent, onLoaded, onError, fallback, } = props;
36
+ if (BDPaywallViewNative == null) {
37
+ if (fallback != null)
38
+ return <>{fallback}</>;
39
+ if (__DEV__) {
40
+ return (<react_native_1.View style={[styles.fill, styles.center, style]}>
41
+ <react_native_1.Text style={styles.warn}>
42
+ BillDog: native paywall component &quot;{COMPONENT_NAME}&quot; is not registered
43
+ on {react_native_1.Platform.OS}. Ensure the native SDK is linked, or use PaywallView /
44
+ WebViewPaywall.
45
+ </react_native_1.Text>
46
+ </react_native_1.View>);
47
+ }
48
+ return null;
49
+ }
50
+ return (<BDPaywallViewNative paywallIdentifier={identifier} style={[styles.fill, style]} onLoaded={() => onLoaded === null || onLoaded === void 0 ? void 0 : onLoaded()} onError={(e) => { var _a, _b; return onError === null || onError === void 0 ? void 0 : onError((_b = (_a = e.nativeEvent) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : 'Unknown paywall error'); }} onPurchase={(e) => { var _a, _b, _c; return onPurchase === null || onPurchase === void 0 ? void 0 : onPurchase((_b = (_a = e.nativeEvent) === null || _a === void 0 ? void 0 : _a.productId) !== null && _b !== void 0 ? _b : '', (_c = e.nativeEvent) === null || _c === void 0 ? void 0 : _c.data); }} onDismiss={() => onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss()} onRestore={() => onRestore === null || onRestore === void 0 ? void 0 : onRestore()} onOpenUrl={(e) => { var _a, _b; return onOpenUrl === null || onOpenUrl === void 0 ? void 0 : onOpenUrl((_b = (_a = e.nativeEvent) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : ''); }} onTrackEvent={(e) => { var _a, _b, _c; return onTrackEvent === null || onTrackEvent === void 0 ? void 0 : onTrackEvent((_b = (_a = e.nativeEvent) === null || _a === void 0 ? void 0 : _a.event) !== null && _b !== void 0 ? _b : '', (_c = e.nativeEvent) === null || _c === void 0 ? void 0 : _c.data); }}/>);
51
+ }
52
+ /** Whether the native paywall component is available on the current platform. */
53
+ exports.isNativePaywallAvailable = isNativeComponentAvailable;
54
+ const styles = react_native_1.StyleSheet.create({
55
+ fill: { flex: 1 },
56
+ center: { alignItems: 'center', justifyContent: 'center', padding: 16 },
57
+ warn: { color: '#B00020', textAlign: 'center', fontSize: 13 },
58
+ });
59
+ exports.default = NativePaywallView;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * PaywallCache - Smart caching layer for React Native
3
+ * Uses AsyncStorage for metadata and RNFS for asset caching
4
+ * Supports server-provided cache configuration
5
+ */
6
+ export interface CacheConfig {
7
+ enabled: boolean;
8
+ maxCacheAge: number;
9
+ backgroundUpdateEnabled: boolean;
10
+ preloadAssets: boolean;
11
+ }
12
+ export declare const DEFAULT_CACHE_CONFIG: CacheConfig;
13
+ export interface CachedPaywall {
14
+ paywall: {
15
+ id: string;
16
+ identifier: string;
17
+ name: string;
18
+ configuration: any;
19
+ version: number;
20
+ };
21
+ version: number;
22
+ cachedAt: number;
23
+ expiresAt: number;
24
+ etag?: string;
25
+ isFallback?: boolean;
26
+ }
27
+ export declare class PaywallCache {
28
+ private config;
29
+ private cacheDir;
30
+ private fallbackCache;
31
+ constructor(config?: Partial<CacheConfig>);
32
+ /**
33
+ * Update cache configuration from server response
34
+ */
35
+ configureFromServer(serverConfig: CacheConfig): void;
36
+ /**
37
+ * Get current cache configuration
38
+ */
39
+ getConfig(): CacheConfig;
40
+ get(identifier: string): Promise<CachedPaywall | null>;
41
+ set(identifier: string, paywall: CachedPaywall): Promise<void>;
42
+ /**
43
+ * Set a fallback paywall that will never be cleared
44
+ */
45
+ setFallback(identifier: string, paywall: CachedPaywall): Promise<void>;
46
+ delete(identifier: string, includeFallback?: boolean): Promise<void>;
47
+ /**
48
+ * Check if background update is needed and trigger if enabled
49
+ */
50
+ shouldTriggerBackgroundUpdate(identifier: string): boolean;
51
+ markBackgroundUpdateStarted(identifier: string): void;
52
+ markBackgroundUpdateCompleted(identifier: string): void;
53
+ cacheAsset(url: string): Promise<string | null>;
54
+ /**
55
+ * Preload all assets from a paywall configuration
56
+ */
57
+ preloadPaywallAssets(configuration: any): Promise<void>;
58
+ private extractAssetUrls;
59
+ getCachedAssetPath(url: string): Promise<string | null>;
60
+ /**
61
+ * Clear regular cache (preserves fallbacks)
62
+ */
63
+ clearAll(): Promise<void>;
64
+ /**
65
+ * Clear all cache including fallbacks
66
+ */
67
+ clearAllIncludingFallbacks(): Promise<void>;
68
+ getStats(): Promise<{
69
+ paywallCount: number;
70
+ assetCount: number;
71
+ fallbackCount: number;
72
+ config: CacheConfig;
73
+ }>;
74
+ }