@osano/osano-cmp-react-native 0.13.0 → 0.15.0

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 (145) hide show
  1. package/README.dev.md +237 -12
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/OsanoCMPSDK/OsanoCMPSDKModule.kt +147 -64
  4. package/android/src/main/java/com/OsanoCMPSDK/OsanoCMPSDKPackage.kt +0 -1
  5. package/ios/OsanoCmpSDK.mm +33 -3
  6. package/ios/OsanoCmpSdk.h +0 -7
  7. package/lib/commonjs/ConsentManager.js +32 -4
  8. package/lib/commonjs/ConsentManager.js.map +1 -1
  9. package/lib/commonjs/components/Button.js +105 -95
  10. package/lib/commonjs/components/Button.js.map +1 -1
  11. package/lib/commonjs/components/Locale.js +5 -3
  12. package/lib/commonjs/components/Locale.js.map +1 -1
  13. package/lib/commonjs/index.js +1 -1
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/native/OsanoCmp.js +35 -8
  16. package/lib/commonjs/native/OsanoCmp.js.map +1 -1
  17. package/lib/commonjs/native/OsanoCmpSdkSpec.js +9 -0
  18. package/lib/commonjs/native/OsanoCmpSdkSpec.js.map +1 -0
  19. package/lib/commonjs/services/consent.js +6 -2
  20. package/lib/commonjs/services/consent.js.map +1 -1
  21. package/lib/commonjs/utils/ExpoDetector.js +105 -0
  22. package/lib/commonjs/utils/ExpoDetector.js.map +1 -0
  23. package/lib/commonjs/utils/ExpoGoMemoryStorage.js +61 -0
  24. package/lib/commonjs/utils/ExpoGoMemoryStorage.js.map +1 -0
  25. package/lib/commonjs/views/Dialog/Buttons.js +26 -16
  26. package/lib/commonjs/views/Dialog/Buttons.js.map +1 -1
  27. package/lib/commonjs/views/Dialog/index.js +58 -95
  28. package/lib/commonjs/views/Dialog/index.js.map +1 -1
  29. package/lib/commonjs/views/Drawer/Drawer.ConsentCategories.js +12 -13
  30. package/lib/commonjs/views/Drawer/Drawer.ConsentCategories.js.map +1 -1
  31. package/lib/commonjs/views/Drawer/Drawer.Header.js +2 -2
  32. package/lib/commonjs/views/Drawer/Drawer.Header.js.map +1 -1
  33. package/lib/commonjs/views/Drawer/Drawer.Iab.Disclosures.js +10 -1
  34. package/lib/commonjs/views/Drawer/Drawer.Iab.Disclosures.js.map +1 -1
  35. package/lib/commonjs/views/Drawer/index.js +5 -4
  36. package/lib/commonjs/views/Drawer/index.js.map +1 -1
  37. package/lib/module/ConsentManager.js +32 -4
  38. package/lib/module/ConsentManager.js.map +1 -1
  39. package/lib/module/components/Button.js +99 -88
  40. package/lib/module/components/Button.js.map +1 -1
  41. package/lib/module/components/Locale.js +4 -3
  42. package/lib/module/components/Locale.js.map +1 -1
  43. package/lib/module/index.js +1 -1
  44. package/lib/module/index.js.map +1 -1
  45. package/lib/module/native/OsanoCmp.js +34 -8
  46. package/lib/module/native/OsanoCmp.js.map +1 -1
  47. package/lib/module/native/OsanoCmpSdkSpec.js +3 -0
  48. package/lib/module/native/OsanoCmpSdkSpec.js.map +1 -0
  49. package/lib/module/services/consent.js +7 -3
  50. package/lib/module/services/consent.js.map +1 -1
  51. package/lib/module/utils/ExpoDetector.js +98 -0
  52. package/lib/module/utils/ExpoDetector.js.map +1 -0
  53. package/lib/module/utils/ExpoGoMemoryStorage.js +54 -0
  54. package/lib/module/utils/ExpoGoMemoryStorage.js.map +1 -0
  55. package/lib/module/views/Dialog/Buttons.js +27 -17
  56. package/lib/module/views/Dialog/Buttons.js.map +1 -1
  57. package/lib/module/views/Dialog/index.js +59 -96
  58. package/lib/module/views/Dialog/index.js.map +1 -1
  59. package/lib/module/views/Drawer/Drawer.ConsentCategories.js +10 -12
  60. package/lib/module/views/Drawer/Drawer.ConsentCategories.js.map +1 -1
  61. package/lib/module/views/Drawer/Drawer.Header.js +2 -2
  62. package/lib/module/views/Drawer/Drawer.Header.js.map +1 -1
  63. package/lib/module/views/Drawer/Drawer.Iab.Disclosures.js +10 -1
  64. package/lib/module/views/Drawer/Drawer.Iab.Disclosures.js.map +1 -1
  65. package/lib/module/views/Drawer/index.js +6 -6
  66. package/lib/module/views/Drawer/index.js.map +1 -1
  67. package/lib/typescript/lib/commonjs/ConsentManager.d.ts.map +1 -1
  68. package/lib/typescript/lib/commonjs/components/Button.d.ts +4 -4
  69. package/lib/typescript/lib/commonjs/components/Button.d.ts.map +1 -1
  70. package/lib/typescript/lib/commonjs/components/Locale.d.ts.map +1 -1
  71. package/lib/typescript/lib/commonjs/hooks/useDeviceOrientation.d.ts +1 -1
  72. package/lib/typescript/lib/commonjs/native/OsanoCmp.d.ts.map +1 -1
  73. package/lib/typescript/lib/commonjs/native/OsanoCmpSdkSpec.d.ts +5 -0
  74. package/lib/typescript/lib/commonjs/native/OsanoCmpSdkSpec.d.ts.map +1 -0
  75. package/lib/typescript/lib/commonjs/services/consent.d.ts.map +1 -1
  76. package/lib/typescript/lib/commonjs/utils/ExpoDetector.d.ts +28 -0
  77. package/lib/typescript/lib/commonjs/utils/ExpoDetector.d.ts.map +1 -0
  78. package/lib/typescript/lib/commonjs/utils/ExpoGoMemoryStorage.d.ts +22 -0
  79. package/lib/typescript/lib/commonjs/utils/ExpoGoMemoryStorage.d.ts.map +1 -0
  80. package/lib/typescript/lib/commonjs/views/Dialog/Buttons.d.ts.map +1 -1
  81. package/lib/typescript/lib/commonjs/views/Dialog/index.d.ts.map +1 -1
  82. package/lib/typescript/lib/commonjs/views/Drawer/Drawer.ConsentCategories.d.ts.map +1 -1
  83. package/lib/typescript/lib/commonjs/views/Drawer/Drawer.Iab.Disclosures.d.ts.map +1 -1
  84. package/lib/typescript/lib/commonjs/views/Drawer/index.d.ts.map +1 -1
  85. package/lib/typescript/lib/module/ConsentManager.d.ts.map +1 -1
  86. package/lib/typescript/lib/module/components/Button.d.ts +7 -7
  87. package/lib/typescript/lib/module/components/Button.d.ts.map +1 -1
  88. package/lib/typescript/lib/module/components/Locale.d.ts +4 -1
  89. package/lib/typescript/lib/module/components/Locale.d.ts.map +1 -1
  90. package/lib/typescript/lib/module/hooks/useDeviceOrientation.d.ts +1 -1
  91. package/lib/typescript/lib/module/native/OsanoCmp.d.ts.map +1 -1
  92. package/lib/typescript/lib/module/native/OsanoCmpSdkSpec.d.ts +3 -0
  93. package/lib/typescript/lib/module/native/OsanoCmpSdkSpec.d.ts.map +1 -0
  94. package/lib/typescript/lib/module/services/consent.d.ts.map +1 -1
  95. package/lib/typescript/lib/module/utils/ExpoDetector.d.ts +27 -0
  96. package/lib/typescript/lib/module/utils/ExpoDetector.d.ts.map +1 -0
  97. package/lib/typescript/lib/module/utils/ExpoGoMemoryStorage.d.ts +21 -0
  98. package/lib/typescript/lib/module/utils/ExpoGoMemoryStorage.d.ts.map +1 -0
  99. package/lib/typescript/lib/module/views/Dialog/Buttons.d.ts.map +1 -1
  100. package/lib/typescript/lib/module/views/Dialog/index.d.ts.map +1 -1
  101. package/lib/typescript/lib/module/views/Drawer/Drawer.ConsentCategories.d.ts.map +1 -1
  102. package/lib/typescript/lib/module/views/Drawer/Drawer.Header.d.ts.map +1 -1
  103. package/lib/typescript/lib/module/views/Drawer/Drawer.Iab.Disclosures.d.ts.map +1 -1
  104. package/lib/typescript/lib/module/views/Drawer/index.d.ts.map +1 -1
  105. package/lib/typescript/src/ConsentManager.d.ts.map +1 -1
  106. package/lib/typescript/src/components/Button.d.ts +7 -7
  107. package/lib/typescript/src/components/Button.d.ts.map +1 -1
  108. package/lib/typescript/src/components/Locale.d.ts +2 -1
  109. package/lib/typescript/src/components/Locale.d.ts.map +1 -1
  110. package/lib/typescript/src/native/OsanoCmp.d.ts.map +1 -1
  111. package/lib/typescript/src/native/OsanoCmpSdkSpec.d.ts +17 -0
  112. package/lib/typescript/src/native/OsanoCmpSdkSpec.d.ts.map +1 -0
  113. package/lib/typescript/src/services/consent.d.ts.map +1 -1
  114. package/lib/typescript/src/utils/ExpoDetector.d.ts +29 -0
  115. package/lib/typescript/src/utils/ExpoDetector.d.ts.map +1 -0
  116. package/lib/typescript/src/utils/ExpoGoMemoryStorage.d.ts +21 -0
  117. package/lib/typescript/src/utils/ExpoGoMemoryStorage.d.ts.map +1 -0
  118. package/lib/typescript/src/views/Dialog/Buttons.d.ts +4 -2
  119. package/lib/typescript/src/views/Dialog/Buttons.d.ts.map +1 -1
  120. package/lib/typescript/src/views/Dialog/index.d.ts +1 -1
  121. package/lib/typescript/src/views/Dialog/index.d.ts.map +1 -1
  122. package/lib/typescript/src/views/Drawer/Drawer.ConsentCategories.d.ts.map +1 -1
  123. package/lib/typescript/src/views/Drawer/Drawer.Header.d.ts +1 -1
  124. package/lib/typescript/src/views/Drawer/Drawer.Header.d.ts.map +1 -1
  125. package/lib/typescript/src/views/Drawer/Drawer.Iab.Disclosures.d.ts.map +1 -1
  126. package/lib/typescript/src/views/Drawer/index.d.ts.map +1 -1
  127. package/osano-cmp-sdk.podspec +15 -15
  128. package/package.json +28 -3
  129. package/src/ConsentManager.ts +37 -4
  130. package/src/components/Button.tsx +122 -88
  131. package/src/components/Locale.tsx +28 -28
  132. package/src/constants.ts +2 -2
  133. package/src/index.tsx +1 -1
  134. package/src/native/OsanoCmp.ts +39 -23
  135. package/src/native/OsanoCmpSdkSpec.ts +25 -0
  136. package/src/services/consent.ts +9 -3
  137. package/src/utils/ExpoDetector.ts +114 -0
  138. package/src/utils/ExpoGoMemoryStorage.ts +61 -0
  139. package/src/views/Dialog/Buttons.tsx +33 -23
  140. package/src/views/Dialog/index.tsx +164 -208
  141. package/src/views/Drawer/Drawer.ConsentCategories.tsx +25 -25
  142. package/src/views/Drawer/Drawer.Header.tsx +7 -7
  143. package/src/views/Drawer/Drawer.Iab.Disclosures.tsx +6 -3
  144. package/src/views/Drawer/index.tsx +20 -19
  145. package/android/src/main/AndroidManifestNew.xml +0 -2
@@ -0,0 +1,21 @@
1
+ /**
2
+ * In-memory storage fallback for Expo Go environment
3
+ * Provides storage functionality when native modules are not available
4
+ */
5
+ export declare class ExpoGoMemoryStorage {
6
+ private static storage;
7
+ private static defaultStorage;
8
+ static setStorage(key: string, value: string): Promise<string>;
9
+ static getStorage(key: string): Promise<string | null>;
10
+ static clearStorage(key: string): Promise<void>;
11
+ static setStorageToDefault(key: string, value: string): Promise<string>;
12
+ static setIntStorageToDefault(key: string, value: number): Promise<number>;
13
+ static setBoolStorageToDefault(key: string, value: boolean): Promise<boolean>;
14
+ static clearStorageFromDefault(key: string): Promise<void>;
15
+ static getDeviceId(): Promise<string>;
16
+ /**
17
+ * Clear all storage for testing purposes
18
+ */
19
+ static clearAll(): void;
20
+ }
21
+ //# sourceMappingURL=ExpoGoMemoryStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoGoMemoryStorage.d.ts","sourceRoot":"","sources":["../../../../src/utils/ExpoGoMemoryStorage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,MAAM,CAAC,OAAO,CAA6B;IACnD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAgD;IAE7E,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9D,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKtD,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvE,MAAM,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1E,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7E,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D,MAAM,CAAC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAUrC;;OAEG;IACH,MAAM,CAAC,QAAQ,IAAI,IAAI;CAIvB"}
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
- import { type ViewProps } from 'react-native';
3
- export declare const Buttons: React.FC<ViewProps>;
2
+ import { type ViewProps, type ViewStyle } from 'react-native';
3
+ export declare const Buttons: React.FC<ViewProps & {
4
+ buttonStyle?: ViewStyle;
5
+ }>;
4
6
  export default Buttons;
5
7
  //# sourceMappingURL=Buttons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Buttons.d.ts","sourceRoot":"","sources":["../../../../../src/views/Dialog/Buttons.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAKhE,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAgDvC,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Buttons.d.ts","sourceRoot":"","sources":["../../../../../src/views/Dialog/Buttons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,EAAoB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAYhF,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,GAAG;IAAE,WAAW,CAAC,EAAE,SAAS,CAAA;CAAE,CAoDrE,CAAC;AAeF,eAAe,OAAO,CAAC"}
@@ -1,5 +1,5 @@
1
- import { Modal } from 'react-native';
2
1
  import type { ReactElement } from 'react';
2
+ import { Modal } from 'react-native';
3
3
  export declare const Dialog: () => ReactElement<Modal>;
4
4
  export default Dialog;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/views/Dialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,EAWL,MAAM,cAAc,CAAC;AAStB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAiB1C,eAAO,MAAM,MAAM,QAAO,YAAY,CAAC,KAAK,CAsS3C,CAAC;AAyGF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/views/Dialog/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQ1C,OAAO,EACN,KAAK,EAWL,MAAM,cAAc,CAAC;AAiBtB,eAAO,MAAM,MAAM,QAAO,YAAY,CAAC,KAAK,CA4O3C,CAAC;AAwHF,eAAe,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.ConsentCategories.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.ConsentCategories.tsx"],"names":[],"mappings":"AAaA,OAAO,KAMN,MAAM,OAAO,CAAC;AAshBf,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EA8G3C,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"Drawer.ConsentCategories.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.ConsentCategories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAmiBf,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EA8G3C,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -1,5 +1,5 @@
1
- import { type LayoutChangeEvent } from 'react-native';
2
1
  import React from 'react';
2
+ import { type LayoutChangeEvent } from 'react-native';
3
3
  export type DrawerHeaderType = {
4
4
  title: string;
5
5
  canGoBack: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.Header.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.Header.tsx"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,iBAAiB,EAOtB,MAAM,cAAc,CAAC;AACtB,OAAO,KAA2C,MAAM,OAAO,CAAC;AAOhE,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAgFnD,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"Drawer.Header.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAKN,KAAK,iBAAiB,EAGtB,MAAM,cAAc,CAAC;AAQtB,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAgFnD,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.Iab.Disclosures.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.Iab.Disclosures.tsx"],"names":[],"mappings":"AAYA,OAAO,KAMN,MAAM,OAAO,CAAC;AA4Kf,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EA4LxC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"Drawer.Iab.Disclosures.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/Drawer.Iab.Disclosures.tsx"],"names":[],"mappings":"AAYA,OAAO,KAMN,MAAM,OAAO,CAAC;AA8Kf,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EA6LxC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/index.tsx"],"names":[],"mappings":"AAcA,OAAO,KAMN,MAAM,OAAO,CAAC;AAgBf,KAAK,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAKnD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAoOxC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/views/Drawer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AA8Bf,KAAK,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAKnD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAqOxC,CAAC"}
@@ -21,21 +21,21 @@ Pod::Spec.new do |s|
21
21
  if respond_to?(:install_modules_dependencies, true)
22
22
  install_modules_dependencies(s)
23
23
  else
24
- s.dependency "React-Core"
24
+ s.dependency "React-Core"
25
25
 
26
- # Don't install the dependencies when we run `pod install` in the old architecture.
27
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
28
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
29
- s.pod_target_xcconfig = {
30
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
31
- "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
32
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
33
- }
34
- s.dependency "React-Codegen"
35
- s.dependency "RCT-Folly"
36
- s.dependency "RCTRequired"
37
- s.dependency "RCTTypeSafety"
38
- s.dependency "ReactCommon/turbomodule/core"
39
- end
26
+ # Don't install the dependencies when we run `pod install` in the old architecture.
27
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
28
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
29
+ s.pod_target_xcconfig = {
30
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_TARGET_SRCROOT)/../../ios/build/generated/ios\"",
31
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
32
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20"
33
+ }
34
+ s.dependency "React-Codegen"
35
+ s.dependency "RCT-Folly"
36
+ s.dependency "RCTRequired"
37
+ s.dependency "RCTTypeSafety"
38
+ s.dependency "ReactCommon/turbomodule/core"
39
+ end
40
40
  end
41
41
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osano/osano-cmp-react-native",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Package and example for the react-native Osano CMP SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -32,6 +32,8 @@
32
32
  "scripts": {
33
33
  "example": "yarn workspace osano-cmp-sdk-example",
34
34
  "test": "jest src/services/__tests__/consent.test.ts src/__tests__/index.test.tsx src/services/__tests__/google-consent-mode.test.ts src/__tests__/OsanoLogger.test.ts",
35
+ "test:legacy": "REACT_NATIVE_NEW_ARCH_ENABLED=false jest src/services/__tests__/consent.test.ts src/__tests__/index.test.tsx src/services/__tests__/google-consent-mode.test.ts src/__tests__/OsanoLogger.test.ts",
36
+ "test:newarch": "REACT_NATIVE_NEW_ARCH_ENABLED=true jest src/services/__tests__/consent.test.ts src/__tests__/index.test.tsx src/services/__tests__/google-consent-mode.test.ts src/__tests__/OsanoLogger.test.ts",
35
37
  "test:google-consent-mode": "jest src/services/__tests__/google-consent-mode.test.ts",
36
38
  "typecheck": "tsc --noEmit",
37
39
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
@@ -71,6 +73,7 @@
71
73
  "@docusaurus/module-type-aliases": "3.5.2",
72
74
  "@docusaurus/preset-classic": "3.5.2",
73
75
  "@mdx-js/react": "^3.0.1",
76
+ "@react-native-community/cli": "^18.0.0",
74
77
  "@testing-library/react-native": "^12.8.1",
75
78
  "@types/jest": "^29.5.5",
76
79
  "@types/react": "^18.2.44",
@@ -98,7 +101,9 @@
98
101
  },
99
102
  "overrides": {
100
103
  "axios": "^1.6.4",
101
- "trim": "^1.0.1"
104
+ "trim": "^1.0.1",
105
+ "inflight": "^1.0.6",
106
+ "glob": "^9.3.5"
102
107
  },
103
108
  "workspaces": [
104
109
  "example",
@@ -107,9 +112,21 @@
107
112
  "packageManager": "yarn@3.6.4",
108
113
  "jest": {
109
114
  "preset": "react-native",
115
+ "setupFilesAfterEnv": [
116
+ "<rootDir>/src/__tests__/setup.ts"
117
+ ],
110
118
  "modulePathIgnorePatterns": [
111
119
  "<rootDir>/example/node_modules",
112
120
  "<rootDir>/lib/"
121
+ ],
122
+ "transformIgnorePatterns": [
123
+ "node_modules/(?!(react-native|@react-native|react-native-svg|@testing-library/react-native)/)"
124
+ ],
125
+ "collectCoverageFrom": [
126
+ "src/**/*.{ts,tsx}",
127
+ "!src/**/__tests__/**",
128
+ "!src/**/*.test.{ts,tsx}",
129
+ "!src/**/types.ts"
113
130
  ]
114
131
  },
115
132
  "commitlint": {
@@ -139,10 +156,18 @@
139
156
  ]
140
157
  ]
141
158
  },
159
+ "codegenConfig": {
160
+ "name": "RNOsanoCmpSdkSpec",
161
+ "type": "modules",
162
+ "jsSrcsDir": "src",
163
+ "android": {
164
+ "javaPackageName": "com.osano.cmp.sdk"
165
+ }
166
+ },
142
167
  "dependencies": {
143
168
  "js-sha512": "^0.9.0",
144
169
  "react-native-picker-modal-view": "^1.3.2",
145
- "react-native-svg": "^15.1.0",
170
+ "react-native-svg": "^14.1.0",
146
171
  "text-encoding": "^0.7.0"
147
172
  }
148
173
  }
@@ -672,6 +672,41 @@ export class ConsentManager {
672
672
  if (extUsrData) {
673
673
  this._extUsrData = extUsrData;
674
674
  }
675
+ // Optimized helper function to get device locale compatible with legacy and new architectures
676
+ const getDeviceLocale = (platform: string): string => {
677
+ const fallbackLocale = 'en-US';
678
+
679
+ try {
680
+ if (platform === 'android') {
681
+ // I18nManager (legacy architecture)
682
+ const i18nLocale = NativeModules.I18nManager?.localeIdentifier;
683
+ if (i18nLocale) return i18nLocale;
684
+
685
+ // PlatformConstants (legacy architecture)
686
+ const platformLocale = NativeModules.PlatformConstants?.getConstants?.()?.Localization?.locale;
687
+ if (platformLocale) return platformLocale;
688
+
689
+ } else if (platform === 'ios') {
690
+ // SettingsManager (legacy architecture)
691
+ const appleLanguage = NativeModules.SettingsManager?.settings?.AppleLanguages?.[0];
692
+ if (appleLanguage) return appleLanguage;
693
+
694
+ const appleLocale = NativeModules.SettingsManager?.settings?.AppleLocale;
695
+ if (appleLocale) return appleLocale;
696
+ }
697
+
698
+ // Intl API (works in both architectures)
699
+ if (global.Intl && Intl.DateTimeFormat) {
700
+ const intlLocale = Intl.DateTimeFormat().resolvedOptions().locale;
701
+ if (intlLocale) return intlLocale;
702
+ }
703
+ } catch (error) {
704
+ OsanoLogger.debug(`[ConsentManager] Locale detection failed: ${error}`);
705
+ }
706
+
707
+ return fallbackLocale;
708
+ };
709
+
675
710
  switch (Platform.OS) {
676
711
  case 'android': {
677
712
  try {
@@ -682,7 +717,7 @@ export class ConsentManager {
682
717
  err instanceof Error ? err : undefined,
683
718
  );
684
719
  }
685
- this._locale = NativeModules.I18nManager.localeIdentifier;
720
+ this._locale = getDeviceLocale('android');
686
721
  break;
687
722
  }
688
723
  case 'ios': {
@@ -694,9 +729,7 @@ export class ConsentManager {
694
729
  err instanceof Error ? err : undefined,
695
730
  );
696
731
  }
697
- this._locale =
698
- NativeModules.SettingsManager.settings.AppleLanguages[0] || //iOS 13
699
- NativeModules.SettingsManager.settings.AppleLocale;
732
+ this._locale = getDeviceLocale('ios');
700
733
  break;
701
734
  }
702
735
  default: {
@@ -11,14 +11,12 @@ import {
11
11
  import { Path, Polygon, Svg } from 'react-native-svg';
12
12
  import { acceptAll, close, denyAll, goBack, showDrawer } from '../actions';
13
13
  import { saveConsent } from '../commands';
14
-
15
14
  import { OsanoPrivateContext } from '../context';
16
15
  import {
17
16
  setAllPurposeConsent,
18
17
  setAllSpecialFeatureConsent,
19
18
  setAllVendorConsent,
20
19
  } from '../iab/tcf/actions';
21
- import Locale from './Locale';
22
20
 
23
21
  type ButtonProps = React.PropsWithoutRef<
24
22
  Omit<PressableProps, 'style' | 'title'> & {
@@ -28,33 +26,50 @@ type ButtonProps = React.PropsWithoutRef<
28
26
  }
29
27
  >;
30
28
 
31
- export const Button: React.FC<ButtonProps> = (props) => {
29
+ // Base button component with React 19 compatibility
30
+ export const BaseButton: React.FC<ButtonProps> = (props) => {
32
31
  const { defaultPhrase, disabled, title, onPress, style: buttonStyle } = props;
33
- const { config } = useContext(OsanoPrivateContext);
32
+ const { config, translate } = useContext(OsanoPrivateContext);
34
33
  const { palette } = config || {};
35
34
  const { buttonBackgroundColor, buttonForegroundColor } = palette || {};
35
+
36
36
  const button: StyleProp<ViewStyle> = useMemo(
37
37
  () => ({
38
38
  alignItems: 'center',
39
+ justifyContent: 'center',
39
40
  backgroundColor: buttonBackgroundColor,
40
41
  borderColor: buttonForegroundColor,
41
42
  borderWidth: 1,
42
43
  borderRadius: 4,
43
- paddingVertical: 8,
44
+ paddingVertical: 12,
44
45
  paddingHorizontal: 16,
45
- flexBasis: 'auto',
46
+ minHeight: 44,
47
+ flexShrink: 0,
46
48
  }),
47
49
  [buttonBackgroundColor, buttonForegroundColor],
48
50
  );
51
+
49
52
  const buttonText: StyleProp<TextStyle> = useMemo(
50
53
  () => ({
51
54
  color: buttonForegroundColor,
52
55
  fontSize: 16,
53
56
  fontWeight: 'bold',
57
+ textAlign: 'center',
54
58
  }),
55
59
  [buttonForegroundColor],
56
60
  );
57
61
 
62
+ // Get translated text with fallback
63
+ const getButtonText = useCallback(() => {
64
+ if (title) {
65
+ const translated = translate(title, {}, defaultPhrase);
66
+ return typeof translated === 'string'
67
+ ? translated
68
+ : defaultPhrase || title;
69
+ }
70
+ return defaultPhrase || 'Button';
71
+ }, [title, defaultPhrase, translate]);
72
+
58
73
  return (
59
74
  <Pressable
60
75
  style={[button, buttonStyle]}
@@ -62,52 +77,12 @@ export const Button: React.FC<ButtonProps> = (props) => {
62
77
  disabled={disabled}
63
78
  testID={props.testID}
64
79
  >
65
- <Text style={buttonText}>
66
- <Locale path={title || ''} defaultPhrase={defaultPhrase} />
67
- </Text>
80
+ <Text style={buttonText}>{getButtonText()}</Text>
68
81
  </Pressable>
69
82
  );
70
83
  };
71
84
 
72
- export const DenyButton = (props: ButtonProps) => {
73
- const { cmp, dispatch } = useContext(OsanoPrivateContext);
74
- const { onPress, title, testID } = props;
75
-
76
- const handleReject = useCallback(() => {
77
- dispatch(setAllVendorConsent(false));
78
- dispatch(setAllPurposeConsent(true));
79
- dispatch(setAllSpecialFeatureConsent(false));
80
- dispatch(denyAll());
81
- cmp && dispatch(saveConsent(cmp));
82
- dispatch(close(cmp));
83
- }, []);
84
-
85
- return Button({
86
- ...props,
87
- title: title || 'buttons.denyNonEssential',
88
- onPress: onPress || handleReject,
89
- testID: testID || 'DenyNonEssential',
90
- });
91
- };
92
-
93
- export const AcceptButton = (props: ButtonProps) => {
94
- const { cmp, dispatch } = useContext(OsanoPrivateContext);
95
- const { onPress, title } = props;
96
-
97
- const handleAcceptConsent = useCallback(() => {
98
- dispatch(acceptAll());
99
- cmp && dispatch(saveConsent(cmp));
100
- dispatch(close(cmp));
101
- }, []);
102
-
103
- return Button({
104
- ...props,
105
- title: title || 'buttons.accept',
106
- onPress: onPress || handleAcceptConsent,
107
- testID: 'Accept',
108
- });
109
- };
110
-
85
+ // Icon buttons that don't need translation
111
86
  export const CloseButton = React.forwardRef(
112
87
  (
113
88
  props: PressableProps & {
@@ -119,7 +94,7 @@ export const CloseButton = React.forwardRef(
119
94
  const { cmp, dispatch } = useContext(OsanoPrivateContext);
120
95
  const handleClose = useCallback(() => {
121
96
  dispatch(close(cmp));
122
- }, []);
97
+ }, [cmp, dispatch]);
123
98
  return (
124
99
  <Pressable {...remain} ref={ref} onPress={onPress || handleClose}>
125
100
  <Svg width="24" height="24" viewBox="0 0 24 24" fill="none">
@@ -146,7 +121,7 @@ export const BackButton = (
146
121
  const { dispatch } = useContext(OsanoPrivateContext);
147
122
  const handleBack = useCallback(() => {
148
123
  dispatch(goBack());
149
- }, []);
124
+ }, [dispatch]);
150
125
  return (
151
126
  <Pressable {...remain} onPress={onPress || handleBack}>
152
127
  <Svg height="16px" viewBox="0 0 512 512" width="16px" fill={color}>
@@ -156,53 +131,76 @@ export const BackButton = (
156
131
  );
157
132
  };
158
133
 
159
- export const ManagePreferencesButton = (props: ButtonProps) => {
134
+ // Specialized button components using proper JSX
135
+ export const ManagePreferencesButton: React.FC<ButtonProps> = (props) => {
160
136
  const { onPress, ...remain } = props;
161
137
  const { config, dispatch, cmp } = useContext(OsanoPrivateContext);
138
+
162
139
  const handleShowDrawer = useCallback(() => {
163
140
  dispatch(close(cmp));
164
141
  dispatch(showDrawer());
165
- }, []);
166
-
167
- return Button({
168
- ...remain,
169
- onPress: onPress || handleShowDrawer,
170
- title: `buttons.dialog.openDrawer.${config?.jurisdiction}`,
171
- defaultPhrase: 'buttons.managePreferences',
172
- testID: `Manage Preferences`,
173
- });
142
+ }, [cmp, dispatch]);
143
+
144
+ return (
145
+ <BaseButton
146
+ {...remain}
147
+ onPress={onPress || handleShowDrawer}
148
+ title={`buttons.dialog.openDrawer.${config?.jurisdiction}`}
149
+ defaultPhrase="Manage Preferences"
150
+ testID="Manage Preferences"
151
+ />
152
+ );
174
153
  };
175
154
 
176
- export const RejectAllButton = (props: ButtonProps) => {
177
- const { config } = useContext(OsanoPrivateContext);
178
- return DenyButton({
179
- ...props,
180
- title: `buttons.dialog.denyAll.${config?.jurisdiction}`,
181
- defaultPhrase: 'buttons.denyAll',
182
- testID: `Reject All`,
183
- });
155
+ export const AcceptButton: React.FC<ButtonProps> = (props) => {
156
+ const { cmp, dispatch } = useContext(OsanoPrivateContext);
157
+ const { onPress, ...remain } = props;
158
+
159
+ const handleAcceptConsent = useCallback(() => {
160
+ dispatch(acceptAll());
161
+ cmp && dispatch(saveConsent(cmp));
162
+ dispatch(close(cmp));
163
+ }, [cmp, dispatch]);
164
+
165
+ return (
166
+ <BaseButton
167
+ {...remain}
168
+ onPress={onPress || handleAcceptConsent}
169
+ title="buttons.accept"
170
+ defaultPhrase="Accept"
171
+ testID="Accept"
172
+ />
173
+ );
184
174
  };
185
175
 
186
- export const SaveButton = (props: ButtonProps) => {
176
+ export const DenyButton: React.FC<ButtonProps> = (props) => {
187
177
  const { cmp, dispatch } = useContext(OsanoPrivateContext);
188
- const { onPress, title } = props;
178
+ const { onPress, ...remain } = props;
189
179
 
190
- const handleSave = useCallback(() => {
180
+ const handleReject = useCallback(() => {
181
+ dispatch(setAllVendorConsent(false));
182
+ dispatch(setAllPurposeConsent(true));
183
+ dispatch(setAllSpecialFeatureConsent(false));
184
+ dispatch(denyAll());
191
185
  cmp && dispatch(saveConsent(cmp));
192
186
  dispatch(close(cmp));
193
- }, []);
194
-
195
- return Button({
196
- ...props,
197
- title: title || `buttons.save`,
198
- onPress: onPress || handleSave,
199
- testID: `Save`,
200
- });
187
+ }, [cmp, dispatch]);
188
+
189
+ return (
190
+ <BaseButton
191
+ {...remain}
192
+ onPress={onPress || handleReject}
193
+ title="buttons.deny"
194
+ defaultPhrase="Deny"
195
+ testID="Deny"
196
+ />
197
+ );
201
198
  };
202
199
 
203
- export const AcceptAllButton = (props: ButtonProps) => {
200
+ export const AcceptAllButton: React.FC<ButtonProps> = (props) => {
204
201
  const { cmp, dispatch } = useContext(OsanoPrivateContext);
205
202
  const { onPress, ...remain } = props;
203
+
206
204
  const handleAcceptAllConsent = useCallback(() => {
207
205
  dispatch(setAllVendorConsent(true));
208
206
  dispatch(setAllPurposeConsent(false));
@@ -210,12 +208,48 @@ export const AcceptAllButton = (props: ButtonProps) => {
210
208
  dispatch(acceptAll());
211
209
  cmp && dispatch(saveConsent(cmp));
212
210
  dispatch(close(cmp));
213
- }, []);
214
-
215
- return Button({
216
- ...remain,
217
- onPress: onPress || handleAcceptAllConsent,
218
- title: `buttons.acceptAll`,
219
- testID: `Accept All`,
220
- });
211
+ }, [cmp, dispatch]);
212
+
213
+ return (
214
+ <BaseButton
215
+ {...remain}
216
+ onPress={onPress || handleAcceptAllConsent}
217
+ title="buttons.acceptAll"
218
+ defaultPhrase="Accept All"
219
+ testID="Accept All"
220
+ />
221
+ );
221
222
  };
223
+
224
+ export const RejectAllButton: React.FC<ButtonProps> = (props) => {
225
+ const { config } = useContext(OsanoPrivateContext);
226
+
227
+ return (
228
+ <DenyButton
229
+ {...props}
230
+ title={`buttons.dialog.denyAll.${config?.jurisdiction}`}
231
+ defaultPhrase="Reject All"
232
+ testID="Reject All"
233
+ />
234
+ );
235
+ };
236
+
237
+ export const SaveButton: React.FC<ButtonProps> = (props) => {
238
+ const { cmp, dispatch } = useContext(OsanoPrivateContext);
239
+ const { onPress, ...remain } = props;
240
+
241
+ const handleSave = useCallback(() => {
242
+ cmp && dispatch(saveConsent(cmp));
243
+ dispatch(close(cmp));
244
+ }, [cmp, dispatch]);
245
+
246
+ return (
247
+ <BaseButton
248
+ {...remain}
249
+ onPress={onPress || handleSave}
250
+ title="buttons.save"
251
+ defaultPhrase="Save"
252
+ testID="Save"
253
+ />
254
+ );
255
+ };
@@ -1,5 +1,5 @@
1
+ import React, { useContext } from 'react';
1
2
  import { OsanoPrivateContext } from '../context';
2
- import { useContext } from 'react';
3
3
 
4
4
  type LocaleOption = Record<string, string>;
5
5
 
@@ -21,32 +21,32 @@ export const Locale = (props: LocaleProps = { path: '' }) => {
21
21
  } = props;
22
22
  const { translate } = useContext(OsanoPrivateContext);
23
23
  const translations = ([] as string[]).concat(pathOrArray);
24
- return (
25
- (pathOrArray &&
26
- formatter(
27
- translations.reduce(
28
- (acc, path) =>
29
- `${acc}${acc ? delimiter : ''}${
30
- translate(
31
- path,
32
- Object.entries(options).reduce(
33
- (acc, [key, value]) => {
34
- acc[key] =
35
- typeof value === 'string'
36
- ? (translate(value, options) as string)
37
- : value;
38
- return acc;
39
- },
40
- {} as Record<string, string | LocaleOption>
41
- ),
42
- defaultPhrase
43
- ) as string
44
- }`,
45
- ''
46
- )
47
- )) ||
48
- null
49
- );
24
+ const translatedText =
25
+ pathOrArray &&
26
+ formatter(
27
+ translations.reduce(
28
+ (acc, path) =>
29
+ `${acc}${acc ? delimiter : ''}${
30
+ translate(
31
+ path,
32
+ Object.entries(options).reduce(
33
+ (acc, [key, value]) => {
34
+ acc[key] =
35
+ typeof value === 'string'
36
+ ? (translate(value, options) as string)
37
+ : value;
38
+ return acc;
39
+ },
40
+ {} as Record<string, string | LocaleOption>,
41
+ ),
42
+ defaultPhrase,
43
+ ) as string
44
+ }`,
45
+ '',
46
+ ),
47
+ );
48
+
49
+ return translatedText ? <>{translatedText}</> : null;
50
50
  };
51
51
 
52
- export default Locale;
52
+ export default Locale;
package/src/constants.ts CHANGED
@@ -17,7 +17,7 @@ export enum ConsentCategory {
17
17
  STORAGE = 'STORAGE',
18
18
  }
19
19
 
20
- const OSANO_DEV = process.env.OSANO_DEV
20
+ const OSANO_DEV = process.env.OSANO_DEV;
21
21
 
22
22
  export const env = {
23
23
  OSANO_ORIGIN: OSANO_DEV === 'true' ? 'https://cmp-ci.osano.com' : 'https://cmp.osano.com',
@@ -33,4 +33,4 @@ export const env = {
33
33
  LOOKUPS_URI: OSANO_DEV === 'true'
34
34
  ? 'https://lookups-ci.api.osano.com'
35
35
  : 'https://lookups.api.osano.com',
36
- };
36
+ };
package/src/index.tsx CHANGED
@@ -70,7 +70,7 @@ export const Osano: React.FunctionComponent<
70
70
  reducer,
71
71
  { configId, customerId },
72
72
  init,
73
- [consentManager.current.middleware],
73
+ [consentManager.current.middleware.bind(consentManager.current)],
74
74
  );
75
75
  const { addMiddleware, dispatch, getState, removeMiddleware } = store;
76
76