cm-sdk-react-native-v3 3.6.0 → 3.6.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.
@@ -1,5 +1,4 @@
1
- import type { TurboModule } from 'react-native';
2
- import { TurboModuleRegistry } from 'react-native';
1
+ import { NativeModules } from 'react-native';
3
2
 
4
3
  // Event payload types for better TypeScript support
5
4
  export type ConsentReceivedEvent = {
@@ -30,16 +29,53 @@ export type UrlConfig = {
30
29
  noHash?: boolean;
31
30
  };
32
31
 
32
+ export enum WebViewPosition {
33
+ FullScreen = 'fullScreen',
34
+ HalfScreenTop = 'halfScreenTop',
35
+ HalfScreenBottom = 'halfScreenBottom',
36
+ Custom = 'custom',
37
+ }
38
+
39
+ export type WebViewRect = {
40
+ x: number;
41
+ y: number;
42
+ width: number;
43
+ height: number;
44
+ };
45
+
46
+ export enum BackgroundStyleType {
47
+ Dimmed = 'dimmed',
48
+ Color = 'color',
49
+ Blur = 'blur',
50
+ None = 'none',
51
+ }
52
+
53
+ export enum BlurEffectStyle {
54
+ Light = 'light',
55
+ Dark = 'dark',
56
+ ExtraLight = 'extraLight',
57
+ }
58
+
59
+ export enum ATTStatus {
60
+ NotDetermined = 0,
61
+ Restricted = 1,
62
+ Denied = 2,
63
+ Authorized = 3,
64
+ }
65
+
66
+ export type WebViewBackgroundStyle =
67
+ | { type: BackgroundStyleType.Dimmed; color?: string | number; opacity?: number }
68
+ | { type: BackgroundStyleType.Color; color: string | number }
69
+ | { type: BackgroundStyleType.Blur; blurEffectStyle?: BlurEffectStyle }
70
+ | { type: BackgroundStyleType.None };
71
+
33
72
  export type WebViewConfig = {
34
- position?: string;
73
+ position?: WebViewPosition;
74
+ customRect?: WebViewRect;
35
75
  cornerRadius?: number;
36
76
  respectsSafeArea?: boolean;
37
77
  allowsOrientationChanges?: boolean;
38
- backgroundStyle?: {
39
- type?: string;
40
- color?: string;
41
- opacity?: number;
42
- };
78
+ backgroundStyle?: WebViewBackgroundStyle;
43
79
  };
44
80
 
45
81
  export type UserStatus = {
@@ -53,14 +89,14 @@ export type UserStatus = {
53
89
 
54
90
  export type GoogleConsentModeStatus = Object;
55
91
 
56
- export interface Spec extends TurboModule {
92
+ export interface CmSdkReactNativeV3Module {
57
93
  // Configuration methods
58
94
  setUrlConfig(config: UrlConfig): Promise<void>;
59
-
95
+
60
96
  setWebViewConfig(config: WebViewConfig): Promise<void>;
61
97
 
62
98
  // iOS-only ATT status method
63
- setATTStatus(status: number): Promise<void>;
99
+ setATTStatus(status: ATTStatus | number): Promise<void>;
64
100
 
65
101
  // Main interaction methods
66
102
  checkAndOpen(jumpToSettings: boolean): Promise<boolean>;
@@ -84,9 +120,11 @@ export interface Spec extends TurboModule {
84
120
  rejectAll(): Promise<boolean>;
85
121
  acceptAll(): Promise<boolean>;
86
122
 
87
- // Event emitter methods (required for TurboModule)
123
+ // Event emitter methods used by NativeEventEmitter
88
124
  addListener(eventName: string): void;
89
125
  removeListeners(count: number): void;
90
126
  }
91
127
 
92
- export default TurboModuleRegistry.getEnforcing<Spec>('CmSdkReactNativeV3');
128
+ const { CmSdkReactNativeV3 } = NativeModules;
129
+
130
+ export default CmSdkReactNativeV3 as CmSdkReactNativeV3Module;
package/src/index.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { NativeModules, Platform, NativeEventEmitter } from 'react-native';
1
+ import { NativeModules, Platform, NativeEventEmitter, processColor } from 'react-native';
2
2
  import NativeCmSdkReactNativeV3, {
3
3
  type ConsentReceivedEvent,
4
4
  type ErrorEvent,
@@ -6,27 +6,37 @@ import NativeCmSdkReactNativeV3, {
6
6
  type ATTStatusChangeEvent,
7
7
  type UrlConfig,
8
8
  type WebViewConfig,
9
+ type WebViewRect,
10
+ type WebViewBackgroundStyle,
11
+ WebViewPosition,
12
+ BackgroundStyleType,
13
+ BlurEffectStyle,
14
+ ATTStatus,
9
15
  type UserStatus,
10
16
  type GoogleConsentModeStatus,
17
+ type CmSdkReactNativeV3Module,
11
18
  } from './NativeCmSdkReactNativeV3';
12
19
 
20
+ // Re-export enums/constants for consumers
21
+ export { WebViewPosition, BackgroundStyleType, BlurEffectStyle, ATTStatus };
22
+
13
23
  const LINKING_ERROR =
14
24
  `The package 'react-native-cm-sdk-react-native-v3' doesn't seem to be linked. Make sure: \n\n` +
15
25
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
16
26
  '- You rebuilt the app after installing the package\n' +
17
27
  '- You are not using Expo Go\n';
18
28
 
19
- // Use TurboModule if available (New Architecture), fallback to legacy NativeModules
20
- const CmSdkReactNativeV3 = NativeCmSdkReactNativeV3 ?? (NativeModules.CmSdkReactNativeV3
21
- ? NativeModules.CmSdkReactNativeV3
22
- : new Proxy(
23
- {},
24
- {
25
- get() {
26
- throw new Error(LINKING_ERROR);
27
- },
28
- }
29
- ));
29
+ const CmSdkReactNativeV3: CmSdkReactNativeV3Module =
30
+ NativeCmSdkReactNativeV3 ??
31
+ (NativeModules.CmSdkReactNativeV3 as CmSdkReactNativeV3Module | undefined) ??
32
+ (new Proxy(
33
+ {},
34
+ {
35
+ get() {
36
+ throw new Error(LINKING_ERROR);
37
+ },
38
+ }
39
+ ) as CmSdkReactNativeV3Module);
30
40
 
31
41
  const eventEmitter = new NativeEventEmitter(CmSdkReactNativeV3);
32
42
 
@@ -68,10 +78,22 @@ export const setUrlConfig = (config: UrlConfig): Promise<void> => {
68
78
  };
69
79
 
70
80
  export const setWebViewConfig = (config: WebViewConfig): Promise<void> => {
71
- return CmSdkReactNativeV3.setWebViewConfig(config);
81
+ const normalized = normalizeWebViewConfig(config);
82
+ return CmSdkReactNativeV3.setWebViewConfig(normalized);
72
83
  };
73
84
 
74
- export const setATTStatus = (status: number): Promise<void> => {
85
+ export const setATTStatus = (status: ATTStatus | number): Promise<void> => {
86
+ const allowed = new Set<ATTStatus>([
87
+ ATTStatus.NotDetermined,
88
+ ATTStatus.Restricted,
89
+ ATTStatus.Denied,
90
+ ATTStatus.Authorized,
91
+ ]);
92
+ if (!allowed.has(status as ATTStatus)) {
93
+ throw new Error(
94
+ `[cm-sdk-react-native-v3] Invalid ATT status ${status}. Use ATTStatus enum (0–3 from Apple's ATTrackingManagerAuthorizationStatus).`
95
+ );
96
+ }
75
97
  return CmSdkReactNativeV3.setATTStatus(status);
76
98
  };
77
99
 
@@ -89,6 +111,96 @@ export const getUserStatus = (): Promise<UserStatus> => {
89
111
  return CmSdkReactNativeV3.getUserStatus();
90
112
  };
91
113
 
114
+ // Helpers
115
+ const normalizeWebViewConfig = (config: WebViewConfig): WebViewConfig => {
116
+ const position = (config.position as WebViewPosition | undefined) ?? WebViewPosition.FullScreen;
117
+ const allowedPositions = [
118
+ WebViewPosition.FullScreen,
119
+ WebViewPosition.HalfScreenTop,
120
+ WebViewPosition.HalfScreenBottom,
121
+ WebViewPosition.Custom,
122
+ ];
123
+ if (!allowedPositions.includes(position)) {
124
+ throw new Error(`Invalid WebView position: ${position}`);
125
+ }
126
+
127
+ if (position === WebViewPosition.Custom) {
128
+ if (!config.customRect) {
129
+ throw new Error('customRect is required when position is "custom"');
130
+ }
131
+ if (Platform.OS === 'android') {
132
+ console.warn(
133
+ '[cm-sdk-react-native-v3] Android native SDK currently ignores customRect/position "custom"; it will fall back to full screen.'
134
+ );
135
+ }
136
+ }
137
+
138
+ const backgroundStyle = (() => {
139
+ if (!config.backgroundStyle) {
140
+ return {
141
+ type: BackgroundStyleType.Dimmed,
142
+ color: normalizeColor('black'),
143
+ opacity: 0.5,
144
+ } as WebViewBackgroundStyle;
145
+ }
146
+ const { type } = config.backgroundStyle;
147
+ switch (type) {
148
+ case BackgroundStyleType.Dimmed:
149
+ return {
150
+ type,
151
+ color: normalizeColor(config.backgroundStyle.color ?? 'black'),
152
+ opacity: config.backgroundStyle.opacity ?? 0.5,
153
+ } as WebViewBackgroundStyle;
154
+ case BackgroundStyleType.Color:
155
+ if (!config.backgroundStyle.color) throw new Error('color is required for backgroundStyle "color"');
156
+ return { type, color: normalizeColor(config.backgroundStyle.color) } as WebViewBackgroundStyle;
157
+ case BackgroundStyleType.Blur: {
158
+ const blurStyle =
159
+ config.backgroundStyle.blurEffectStyle ?? (Platform.OS === 'ios'
160
+ ? BlurEffectStyle.Dark
161
+ : BlurEffectStyle.Dark);
162
+ if (
163
+ blurStyle !== BlurEffectStyle.Dark &&
164
+ blurStyle !== BlurEffectStyle.Light &&
165
+ blurStyle !== BlurEffectStyle.ExtraLight
166
+ ) {
167
+ throw new Error(`Invalid blurEffectStyle: ${blurStyle}`);
168
+ }
169
+ if (Platform.OS === 'android') {
170
+ console.warn('[cm-sdk-react-native-v3] Android native SDK currently ignores blur backgrounds; using dimmed.');
171
+ }
172
+ return { type, blurEffectStyle: blurStyle } as WebViewBackgroundStyle;
173
+ }
174
+ case BackgroundStyleType.None:
175
+ return { type } as WebViewBackgroundStyle;
176
+ default:
177
+ throw new Error(`Invalid backgroundStyle type: ${(config.backgroundStyle as any).type}`);
178
+ }
179
+ })();
180
+
181
+ if (Platform.OS === 'android' && config.backgroundStyle) {
182
+ console.warn(
183
+ '[cm-sdk-react-native-v3] Android native SDK currently ignores backgroundStyle overrides; it always uses a dimmed background.'
184
+ );
185
+ }
186
+
187
+ return {
188
+ position,
189
+ customRect: config.customRect,
190
+ cornerRadius: config.cornerRadius ?? 5,
191
+ respectsSafeArea: config.respectsSafeArea ?? true,
192
+ allowsOrientationChanges: config.allowsOrientationChanges ?? true,
193
+ backgroundStyle,
194
+ };
195
+ };
196
+
197
+ const normalizeColor = (color: string | number | undefined) => {
198
+ if (color === undefined) return undefined;
199
+ const processed = processColor(color);
200
+ if (processed == null) throw new Error(`Invalid color value: ${color}`);
201
+ return processed;
202
+ };
203
+
92
204
  export const getStatusForPurpose = (purposeId: string): Promise<string> => {
93
205
  return CmSdkReactNativeV3.getStatusForPurpose(purposeId);
94
206
  };
@@ -145,9 +257,31 @@ export type {
145
257
  LinkClickEvent,
146
258
  ATTStatusChangeEvent,
147
259
  UrlConfig,
260
+ WebViewRect,
261
+ WebViewBackgroundStyle,
148
262
  WebViewConfig,
149
263
  UserStatus,
150
264
  GoogleConsentModeStatus,
151
265
  };
152
266
 
267
+ /**
268
+ * Helper factory to build strongly-typed background styles.
269
+ */
270
+ export const BackgroundStyle = {
271
+ dimmed: (color?: string | number, opacity?: number): WebViewBackgroundStyle => ({
272
+ type: BackgroundStyleType.Dimmed,
273
+ color,
274
+ opacity,
275
+ }),
276
+ color: (color: string | number): WebViewBackgroundStyle => ({
277
+ type: BackgroundStyleType.Color,
278
+ color,
279
+ }),
280
+ blur: (blurEffectStyle: BlurEffectStyle = BlurEffectStyle.Dark): WebViewBackgroundStyle => ({
281
+ type: BackgroundStyleType.Blur,
282
+ blurEffectStyle,
283
+ }),
284
+ none: (): WebViewBackgroundStyle => ({ type: BackgroundStyleType.None }),
285
+ } as const;
286
+
153
287
  export default CmSdkReactNativeV3;