react-native-insider 8.1.0 → 9.0.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 (48) hide show
  1. package/README.md +89 -660
  2. package/RNInsider.podspec +33 -12
  3. package/android/build.gradle +16 -2
  4. package/android/src/main/java/com/useinsider/react/RNInsiderAppFrameViewManager.java +253 -0
  5. package/android/src/main/java/com/useinsider/react/RNInsiderModule.java +238 -174
  6. package/android/src/main/java/com/useinsider/react/RNInsiderPackage.java +5 -1
  7. package/android/src/main/java/com/useinsider/react/RNUtils.java +111 -0
  8. package/babel.config.js +4 -1
  9. package/index.d.ts +196 -161
  10. package/index.js +60 -11
  11. package/ios/RNInsider/RNInsider.m +245 -341
  12. package/ios/RNInsider/RNInsiderAppFrameView.h +33 -0
  13. package/ios/RNInsider/RNInsiderAppFrameView.mm +315 -0
  14. package/ios/RNInsider/RNNotificationHandler.h +4 -1
  15. package/ios/RNInsider/RNNotificationHandler.m +16 -18
  16. package/ios/RNInsider/RNUtils.h +2 -0
  17. package/ios/RNInsider/RNUtils.m +79 -0
  18. package/package.json +43 -12
  19. package/src/EventHandler.js +17 -0
  20. package/src/InsiderAppFrame.d.ts +45 -0
  21. package/src/InsiderAppFrame.js +265 -0
  22. package/src/InsiderAppFrameLogic.d.ts +35 -0
  23. package/src/InsiderAppFrameLogic.js +192 -0
  24. package/src/InsiderAppFrameStatus.d.ts +22 -0
  25. package/src/InsiderAppFrameStatus.js +35 -0
  26. package/src/InsiderAppFramesError.d.ts +25 -0
  27. package/src/InsiderAppFramesError.js +77 -0
  28. package/src/InsiderEvent.js +1 -0
  29. package/src/InsiderEvents.d.ts +93 -0
  30. package/src/InsiderEvents.js +124 -0
  31. package/src/InsiderIdentifier.js +1 -1
  32. package/src/InsiderUser.d.ts +3 -2
  33. package/src/InsiderUser.js +27 -0
  34. package/src/Util.js +2 -1
  35. package/src/specs/InsiderAppFrameNativeComponent.ts +54 -0
  36. package/.orbit-output/config/MASTER.md +0 -129
  37. package/.orbit-output/config/architecture/API_DOCS.md +0 -342
  38. package/.orbit-output/config/architecture/ARCHITECTURE.md +0 -209
  39. package/.orbit-output/config/architecture/CODE-CATALOG.md +0 -172
  40. package/.orbit-output/config/architecture/project.yaml +0 -138
  41. package/.orbit-output/config/automation/AUTOMATION-SETUP.md +0 -50
  42. package/.orbit-output/config/enforcement/ENFORCEMENT-RULES.md +0 -41
  43. package/.orbit-output/config/enforcement/validate.sh +0 -49
  44. package/.orbit-output/skills/custom/academy-doc-generator.md +0 -598
  45. package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  46. package/android/src/test/java/com/useinsider/react/RNInsiderModuleTest.java +0 -169
  47. package/docs/app-cards/app-cards_new.md +0 -569
  48. package/ios/RNInsiderTests/RNInsiderTriggerPushProcessTests.m +0 -91
@@ -25,8 +25,12 @@ public class RNInsiderPackage implements ReactPackage {
25
25
  return Collections.emptyList();
26
26
  }
27
27
 
28
+ // Without this entry Fabric has no ViewManager for InsiderAppFrameView and it never renders.
29
+ // RNInsiderAppFrameViewManager needs an Insider SDK that ships App Frames to compile at all.
28
30
  @Override
29
31
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
30
- return Collections.emptyList();
32
+ List<ViewManager> viewManagers = new ArrayList<>();
33
+ viewManagers.add(new RNInsiderAppFrameViewManager());
34
+ return viewManagers;
31
35
  }
32
36
  }
@@ -17,10 +17,12 @@ import org.json.JSONArray;
17
17
  import org.json.JSONException;
18
18
  import org.json.JSONObject;
19
19
 
20
+ import java.lang.reflect.Array;
20
21
  import java.util.ArrayList;
21
22
  import java.util.Date;
22
23
  import java.util.HashMap;
23
24
  import java.util.Iterator;
25
+ import java.util.List;
24
26
  import java.util.Map;
25
27
 
26
28
  public class RNUtils {
@@ -37,6 +39,115 @@ public class RNUtils {
37
39
  return writableMap;
38
40
  }
39
41
 
42
+ /**
43
+ * Recursively converts a {@code Map<String, Object>} coming from the native SDK into a
44
+ * {@link WritableMap} for the React Native bridge.
45
+ *
46
+ * <p>Unlike {@link #convertMapToWritableMap(HashMap)} — which only accepts
47
+ * {@code HashMap<String, String>} — this handles the heterogeneous value types the SDK
48
+ * emits for recorded-event parameters: nested maps, {@link List}s and arrays (including
49
+ * the {@code String[]} / {@code Number[]} produced by
50
+ * {@code addParameterWithStringArray} / {@code addParameterWithNumericArray}), booleans,
51
+ * integral and floating point numbers, strings, dates and nulls.
52
+ *
53
+ * <p>Following the house style, a failure is reported through
54
+ * {@code Insider.Instance.putException} and the partial result is returned rather than
55
+ * throwing back into the SDK's callback thread.
56
+ */
57
+ public static WritableMap convertObjectMapToWritableMap(Map<String, Object> map) {
58
+ WritableMap writableMap = new WritableNativeMap();
59
+ try {
60
+ if (map == null) {
61
+ return writableMap;
62
+ }
63
+
64
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
65
+ String key = entry.getKey();
66
+ if (key == null) continue;
67
+
68
+ putObjectIntoWritableMap(writableMap, key, entry.getValue());
69
+ }
70
+ } catch (Exception e) {
71
+ Insider.Instance.putException(e);
72
+ }
73
+ return writableMap;
74
+ }
75
+
76
+ /**
77
+ * Recursively converts a {@link List} or Java array from the native SDK into a
78
+ * {@link WritableArray}. Element type dispatch matches
79
+ * {@link #convertObjectMapToWritableMap(Map)}.
80
+ */
81
+ public static WritableArray convertObjectListToWritableArray(Object list) {
82
+ WritableArray writableArray = new WritableNativeArray();
83
+ try {
84
+ if (list == null) {
85
+ return writableArray;
86
+ }
87
+
88
+ if (list instanceof List) {
89
+ for (Object value : (List<?>) list) {
90
+ pushObjectIntoWritableArray(writableArray, value);
91
+ }
92
+ } else if (list.getClass().isArray()) {
93
+ int length = Array.getLength(list);
94
+ for (int i = 0; i < length; i++) {
95
+ pushObjectIntoWritableArray(writableArray, Array.get(list, i));
96
+ }
97
+ }
98
+ } catch (Exception e) {
99
+ Insider.Instance.putException(e);
100
+ }
101
+ return writableArray;
102
+ }
103
+
104
+ @SuppressWarnings("unchecked")
105
+ private static void putObjectIntoWritableMap(WritableMap map, String key, Object value) {
106
+ if (value == null) {
107
+ map.putNull(key);
108
+ } else if (value instanceof Map) {
109
+ map.putMap(key, convertObjectMapToWritableMap((Map<String, Object>) value));
110
+ } else if (value instanceof List || value.getClass().isArray()) {
111
+ map.putArray(key, convertObjectListToWritableArray(value));
112
+ } else if (value instanceof Boolean) {
113
+ map.putBoolean(key, (Boolean) value);
114
+ } else if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
115
+ map.putInt(key, ((Number) value).intValue());
116
+ } else if (value instanceof Number) {
117
+ // Long included: the bridge has no 64-bit integer type, so widen to double.
118
+ map.putDouble(key, ((Number) value).doubleValue());
119
+ } else if (value instanceof String) {
120
+ map.putString(key, (String) value);
121
+ } else if (value instanceof Date) {
122
+ map.putDouble(key, ((Date) value).getTime());
123
+ } else {
124
+ map.putString(key, value.toString());
125
+ }
126
+ }
127
+
128
+ @SuppressWarnings("unchecked")
129
+ private static void pushObjectIntoWritableArray(WritableArray array, Object value) {
130
+ if (value == null) {
131
+ array.pushNull();
132
+ } else if (value instanceof Map) {
133
+ array.pushMap(convertObjectMapToWritableMap((Map<String, Object>) value));
134
+ } else if (value instanceof List || value.getClass().isArray()) {
135
+ array.pushArray(convertObjectListToWritableArray(value));
136
+ } else if (value instanceof Boolean) {
137
+ array.pushBoolean((Boolean) value);
138
+ } else if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
139
+ array.pushInt(((Number) value).intValue());
140
+ } else if (value instanceof Number) {
141
+ array.pushDouble(((Number) value).doubleValue());
142
+ } else if (value instanceof String) {
143
+ array.pushString((String) value);
144
+ } else if (value instanceof Date) {
145
+ array.pushDouble(((Date) value).getTime());
146
+ } else {
147
+ array.pushString(value.toString());
148
+ }
149
+ }
150
+
40
151
  public static WritableArray convertJSONArrayToArray(JSONArray jsonArray) {
41
152
  WritableArray array = new WritableNativeArray();
42
153
  try {
package/babel.config.js CHANGED
@@ -1,3 +1,6 @@
1
+ // Single Babel config for Jest and Stryker. It replaces a .babelrc that
2
+ // carried the same preset with enableBabelRuntime: false; keeping one file
3
+ // means every tool resolves the same transform.
1
4
  module.exports = {
2
- presets: ['@react-native/babel-preset'],
5
+ presets: [['@react-native/babel-preset', { enableBabelRuntime: false }]],
3
6
  };
package/index.d.ts CHANGED
@@ -3,6 +3,23 @@ import type RNInsiderEvent from './src/InsiderEvent';
3
3
  import type RNInsiderUser from './src/InsiderUser';
4
4
  import type RNInsiderIdentifier from './src/InsiderIdentifier';
5
5
  import type RNInsiderAppCards from './src/InsiderAppCards';
6
+ import type RNInsiderEvents from './src/InsiderEvents';
7
+
8
+ // App Frames is a React component, so it is a named export rather than a member of RNInsider.
9
+ export { default as InsiderAppFrame } from './src/InsiderAppFrame';
10
+ export type { InsiderAppFrameProps, InsiderAppFrameHandle } from './src/InsiderAppFrame';
11
+ export {
12
+ InsiderAppFramesError,
13
+ InsiderAppFramesErrorCode,
14
+ NO_DISMISS_CODE,
15
+ } from './src/InsiderAppFramesError';
16
+ export type { InsiderAppFramesErrorCodeType } from './src/InsiderAppFramesError';
17
+ export { InsiderAppFrameStatus } from './src/InsiderAppFrameStatus';
18
+ export { isErrorStatus, isLoadingStatus } from './src/InsiderAppFrameLogic';
19
+ export type { InsiderAppFrameStatusType } from './src/InsiderAppFrameStatus';
20
+
21
+ import type { InsiderAppFramesError as InsiderAppFramesErrorClass } from './src/InsiderAppFramesError';
22
+ import type { InsiderAppFramesErrorCode as InsiderAppFramesErrorCodeEnum } from './src/InsiderAppFramesError';
6
23
 
7
24
  export type CustomParameters = {
8
25
  [key: string]: string | number | boolean | Date | number[] | string[];
@@ -36,6 +53,17 @@ export declare const InsiderAppCardsErrorCode: {
36
53
  /** Union type of all possible error code values. */
37
54
  export type InsiderAppCardsErrorCodeType = typeof InsiderAppCardsErrorCode[keyof typeof InsiderAppCardsErrorCode];
38
55
 
56
+ /**
57
+ * Recorded-event types. They are defined alongside the `events` module in
58
+ * `./src/InsiderEvents`, and re-exported here so that consumers can keep importing them
59
+ * straight from the package root (`import { InsiderEventSubscription } from 'react-native-insider'`).
60
+ */
61
+ export type {
62
+ InsiderRecordedEventParameters,
63
+ InsiderEventRecordedCallback,
64
+ InsiderEventSubscription,
65
+ } from './src/InsiderEvents';
66
+
39
67
  /**
40
68
  * Represents a typed error from an App Cards operation.
41
69
  *
@@ -84,167 +112,174 @@ export declare class InsiderAppCardsError extends Error {
84
112
  static from(error: { code: string; message: string } | string | unknown): InsiderAppCardsError;
85
113
  }
86
114
 
87
- declare module 'react-native-insider' {
88
- export interface InsiderCloseButtonPosition {
89
- LEFT: string;
90
- RIGHT: string;
91
- NONE: string;
92
- }
93
-
94
- export default class RNInsider {
95
- static closeButtonPosition: InsiderCloseButtonPosition;
96
- static AppCardsError: typeof InsiderAppCardsError;
97
- static AppCardsErrorCode: typeof InsiderAppCardsErrorCode;
98
- static init(partnerName: string, appGroup: string, insiderCallback: Function): void;
99
- static initWithCustomEndpoint(partnerName: string, appGroup: string, endpoint: string, insiderCallback: Function): void;
100
- static reinitWithPartnerName(partnerName: string): void;
101
- static tagEvent(name: string): RNInsiderEvent;
102
- static getCurrentUser(): RNInsiderUser;
103
- static get appCards(): RNInsiderAppCards;
104
- static setGDPRConsent(gdprConsent: boolean): void;
105
- static setMobileAppAccess(mobileAppAccess: boolean): void;
115
+ // Top level, not `declare module 'react-native-insider'`: this file is already a module, so such
116
+ // a block would be read as an augmentation of itself and never applied.
117
+ export interface InsiderCloseButtonPosition {
118
+ LEFT: string;
119
+ RIGHT: string;
120
+ NONE: string;
121
+ }
106
122
 
107
- static createNewProduct(
108
- productID: string,
109
- name: string,
110
- taxonomy: Array<string>,
111
- imageURL: string,
112
- price: number,
113
- currency: string
114
- ): RNInsiderProduct;
115
- static itemPurchased(uniqueSaleID: string, product: RNInsiderProduct, customParameters?: CustomParameters): void;
116
- static itemAddedToCart(product: RNInsiderProduct, customParameters?: CustomParameters): void;
117
- static itemRemovedFromCart(productID: string): void;
118
- static itemRemovedFromCart(productID: string, customParameters: CustomParameters): void;
119
- static itemRemovedFromCart(productID: string, saleID: string): void;
120
- static itemRemovedFromCart(productID: string, saleID: string, customParameters: CustomParameters): void;
121
- static cartCleared(customParameters?: CustomParameters): void;
122
- static itemAddedToWishlist(product: RNInsiderProduct, customParameters?: CustomParameters): void;
123
- static itemRemovedFromWishlist(productID: string, customParameters?: CustomParameters): void;
124
- static wishlistCleared(customParameters?: CustomParameters): void;
125
- static getMessageCenterData(
126
- limit: number,
127
- startDate: Date,
128
- endDate: Date,
129
- callback: (messageCenterData: any) => void
130
- ): void;
131
- static getMessageCenterDataWithIdentifiers(
132
- limit: number,
133
- startDate: Date,
134
- endDate: Date,
135
- identifiers: RNInsiderIdentifier,
136
- callback: (messageCenterData: any) => void
137
- ): void;
138
- static getSmartRecommendation(
139
- recommendationID: number,
140
- locale: string,
141
- currency: string,
142
- callback: (recommendation: any) => void
143
- ): void;
144
- static getSmartRecommendationWithProduct(
145
- product: RNInsiderProduct,
146
- recommendationID: number,
147
- locale: string,
148
- callback: (recommendation: any) => void
149
- ): void;
150
- static getSmartRecommendationWithProductIDs(
151
- productIDs: string[],
152
- recommendationID: number,
153
- locale: string,
154
- currency: string,
155
- callback: (recommendation: any) => void
156
- ): void;
157
- static clickSmartRecommendationProduct(recommendationID: number, product: RNInsiderProduct): void;
158
- static getContentStringWithName(
159
- variableName: string,
160
- defaultValue: string,
161
- contentOptimizerDataType: number,
162
- callback: (content: string) => void
163
- ): void;
164
- static getContentBoolWithName(
165
- variableName: string,
166
- defaultValue: boolean,
167
- contentOptimizerDataType: number,
168
- callback: (content: boolean) => void
169
- ): void;
170
- static getContentIntWithName(
171
- variableName: string,
172
- defaultValue: number,
173
- contentOptimizerDataType: number,
174
- callback: (content: number) => void
175
- ): void;
176
- static getContentStringWithoutCache(
177
- variableName: string,
178
- defaultValue: string,
179
- contentOptimizerDataType: number,
180
- callback: (content: string) => void
181
- ): void;
182
- static getContentBoolWithoutCache(
183
- variableName: string,
184
- defaultValue: boolean,
185
- contentOptimizerDataType: number,
186
- callback: (content: boolean) => void
187
- ): void;
188
- static getContentIntWithoutCache(
189
- variableName: string,
190
- defaultValue: number,
191
- contentOptimizerDataType: number,
192
- callback: (content: number) => void
193
- ): void;
194
- static visitHomePage(customParameters?: CustomParameters): void;
195
- static visitListingPage(taxonomy: Array<string>, customParameters?: CustomParameters): void;
196
- static visitProductDetailPage(product: RNInsiderProduct, customParameters?: CustomParameters): void;
197
- static visitCartPage(products: Array<RNInsiderProduct>): void;
198
- static visitCartPage(products: Array<RNInsiderProduct>, customParameters: CustomParameters): void;
199
- static visitCartPage(products: Array<RNInsiderProduct>, saleID: string): void;
200
- static visitCartPage(products: Array<RNInsiderProduct>, saleID: string, customParameters: CustomParameters): void;
201
- static visitWishlistPage(products: Array<RNInsiderProduct>, customParameters?: CustomParameters): void;
202
- static startTrackingGeofence(): void;
203
- static setAllowsBackgroundLocationUpdates(allowsBackgroundLocationUpdates: boolean): void;
204
- static handleNotification(notification: any): void;
205
- static triggerPushProcessWithNotificationData(notification: any): void;
206
- static enableIDFACollection(enableIDFACollection: boolean): void;
207
- static removeInapp(): void;
208
- static registerWithQuietPermission(enabled: boolean): void;
209
- static setHybridPushToken(token: string): void;
210
- static showNativeAppReview(): void;
211
- static enableLocationCollection(consentStatus: boolean): void;
212
- static enableIpCollection(consentStatus: boolean): void;
213
- static enableCarrierCollection(consentStatus: boolean): void;
214
- static signUpConfirmation(customParameters?: CustomParameters): void;
215
- static setInternalBrowserCloseButtonPosition(position: string): void;
216
- static reenableTemplatesForIOS(): void;
217
- static disableTemplatesForIOS(): void;
218
- static setForegroundPushCallback(callback: (notification: any) => void): void;
219
- static setActiveForegroundPushView(): void;
220
- static handleUniversalLink(url: string): void;
221
- static getInsiderID(): Promise<string>;
222
- static insiderIDListener(callback: (insiderID: string) => void): void;
223
- static disableInAppMessages(): void;
224
- static enableInAppMessages(): void;
225
- /**
226
- * Handles deep link URLs from Insider QR codes and email links.
227
- *
228
- * This method processes incoming URLs to enable deep linking functionality
229
- * for features available in the Insider panel. It parses the URL and routes
230
- * the user to the appropriate screen or action within the app, allowing
231
- * seamless integration with Insider's panel-based features.
232
- *
233
- * @platform iOS only - This method is only available on iOS platform
234
- * @param url - The URL string to be processed from Insider QR codes or email links
235
- * @example
236
- * RNInsider.handleURL('insider{your_partner_name}://test_device/...');
237
- */
238
- static handleURL(url: string): void;
239
- }
123
+ export default class RNInsider {
124
+ static closeButtonPosition: InsiderCloseButtonPosition;
125
+ static AppCardsError: typeof InsiderAppCardsError;
126
+ static AppCardsErrorCode: typeof InsiderAppCardsErrorCode;
127
+ static AppFramesError: typeof InsiderAppFramesErrorClass;
128
+ static AppFramesErrorCode: typeof InsiderAppFramesErrorCodeEnum;
129
+ /**
130
+ * Initializes the Insider SDK; pass `appIdentifier` when one partner serves several apps.
131
+ * @param appIdentifier Optional app identifier given to you by Insider (`^[a-z0-9][a-z0-9_]{0,49}$`).
132
+ * Omit it, or pass an empty string, to initialize without one.
133
+ */
134
+ static init(partnerName: string, appGroup: string, insiderCallback: Function, appIdentifier?: string): void;
135
+ /**
136
+ * Initializes the Insider SDK against a custom endpoint; pass `appIdentifier` when one partner serves several apps.
137
+ * @param appIdentifier Optional app identifier given to you by Insider (`^[a-z0-9][a-z0-9_]{0,49}$`).
138
+ * Omit it, or pass an empty string, to initialize without one.
139
+ */
140
+ static initWithCustomEndpoint(partnerName: string, appGroup: string, endpoint: string, insiderCallback: Function, appIdentifier?: string): void;
141
+ static reinitWithPartnerName(partnerName: string): void;
142
+ static tagEvent(name: string): RNInsiderEvent;
143
+ static getCurrentUser(): RNInsiderUser;
144
+ static get appCards(): RNInsiderAppCards;
145
+ static get events(): RNInsiderEvents;
146
+ static setGDPRConsent(gdprConsent: boolean): void;
147
+ static setMobileAppAccess(mobileAppAccess: boolean): void;
240
148
 
241
- export const NOTIFICATION_OPEN: string;
242
- export const INAPP_BUTTON_CLICK: string;
243
- export const TEMP_STORE_PURCHASE: string;
244
- export const TEMP_STORE_ADDED_TO_CART: string;
245
- export const TEMP_STORE_CUSTOM_ACTION: string;
246
- export const FOREGROUND_PUSH: string;
247
- export const INAPP_SEEN: string;
248
- export const INSIDER_ID_LISTENER: string;
249
- export const SESSION_STARTED: string;
149
+ static createNewProduct(
150
+ productID: string,
151
+ name: string,
152
+ taxonomy: Array<string>,
153
+ imageURL: string,
154
+ price: number,
155
+ currency: string
156
+ ): RNInsiderProduct;
157
+ static itemPurchased(uniqueSaleID: string, product: RNInsiderProduct, customParameters?: CustomParameters): void;
158
+ static itemAddedToCart(product: RNInsiderProduct, customParameters?: CustomParameters): void;
159
+ static itemRemovedFromCart(productID: string): void;
160
+ static itemRemovedFromCart(productID: string, customParameters: CustomParameters): void;
161
+ static itemRemovedFromCart(productID: string, saleID: string): void;
162
+ static itemRemovedFromCart(productID: string, saleID: string, customParameters: CustomParameters): void;
163
+ static cartCleared(customParameters?: CustomParameters): void;
164
+ static itemAddedToWishlist(product: RNInsiderProduct, customParameters?: CustomParameters): void;
165
+ static itemRemovedFromWishlist(productID: string, customParameters?: CustomParameters): void;
166
+ static wishlistCleared(customParameters?: CustomParameters): void;
167
+ static getMessageCenterData(
168
+ limit: number,
169
+ startDate: Date,
170
+ endDate: Date,
171
+ callback: (messageCenterData: any) => void
172
+ ): void;
173
+ static getMessageCenterDataWithIdentifiers(
174
+ limit: number,
175
+ startDate: Date,
176
+ endDate: Date,
177
+ identifiers: RNInsiderIdentifier,
178
+ callback: (messageCenterData: any) => void
179
+ ): void;
180
+ static getSmartRecommendation(
181
+ recommendationID: number,
182
+ locale: string,
183
+ currency: string,
184
+ callback: (recommendation: any) => void
185
+ ): void;
186
+ static getSmartRecommendationWithProduct(
187
+ product: RNInsiderProduct,
188
+ recommendationID: number,
189
+ locale: string,
190
+ callback: (recommendation: any) => void
191
+ ): void;
192
+ static getSmartRecommendationWithProductIDs(
193
+ productIDs: string[],
194
+ recommendationID: number,
195
+ locale: string,
196
+ currency: string,
197
+ callback: (recommendation: any) => void
198
+ ): void;
199
+ static clickSmartRecommendationProduct(recommendationID: number, product: RNInsiderProduct): void;
200
+ static getContentStringWithName(
201
+ variableName: string,
202
+ defaultValue: string,
203
+ contentOptimizerDataType: number,
204
+ callback: (content: string) => void
205
+ ): void;
206
+ static getContentBoolWithName(
207
+ variableName: string,
208
+ defaultValue: boolean,
209
+ contentOptimizerDataType: number,
210
+ callback: (content: boolean) => void
211
+ ): void;
212
+ static getContentIntWithName(
213
+ variableName: string,
214
+ defaultValue: number,
215
+ contentOptimizerDataType: number,
216
+ callback: (content: number) => void
217
+ ): void;
218
+ static getContentStringWithoutCache(
219
+ variableName: string,
220
+ defaultValue: string,
221
+ contentOptimizerDataType: number,
222
+ callback: (content: string) => void
223
+ ): void;
224
+ static getContentBoolWithoutCache(
225
+ variableName: string,
226
+ defaultValue: boolean,
227
+ contentOptimizerDataType: number,
228
+ callback: (content: boolean) => void
229
+ ): void;
230
+ static getContentIntWithoutCache(
231
+ variableName: string,
232
+ defaultValue: number,
233
+ contentOptimizerDataType: number,
234
+ callback: (content: number) => void
235
+ ): void;
236
+ static markContentOptimizerAsSeen(variableName: string): void;
237
+ static visitHomePage(customParameters?: CustomParameters): void;
238
+ static visitListingPage(taxonomy: Array<string>, customParameters?: CustomParameters): void;
239
+ static visitProductDetailPage(product: RNInsiderProduct, customParameters?: CustomParameters): void;
240
+ static visitCartPage(products: Array<RNInsiderProduct>): void;
241
+ static visitCartPage(products: Array<RNInsiderProduct>, customParameters: CustomParameters): void;
242
+ static visitCartPage(products: Array<RNInsiderProduct>, saleID: string): void;
243
+ static visitCartPage(products: Array<RNInsiderProduct>, saleID: string, customParameters: CustomParameters): void;
244
+ static visitWishlistPage(products: Array<RNInsiderProduct>, customParameters?: CustomParameters): void;
245
+ static startTrackingGeofence(): void;
246
+ static setAllowsBackgroundLocationUpdates(allowsBackgroundLocationUpdates: boolean): void;
247
+ static handleNotification(notification: any): void;
248
+ static triggerPushProcessWithNotificationData(notification: any): void;
249
+ static enableIDFACollection(enableIDFACollection: boolean): void;
250
+ static removeInapp(): void;
251
+ static registerWithQuietPermission(enabled: boolean): void;
252
+ static setHybridPushToken(token: string): void;
253
+ static showNativeAppReview(): void;
254
+ static enableLocationCollection(consentStatus: boolean): void;
255
+ static enableIpCollection(consentStatus: boolean): void;
256
+ static enableCarrierCollection(consentStatus: boolean): void;
257
+ static signUpConfirmation(customParameters?: CustomParameters): void;
258
+ static setInternalBrowserCloseButtonPosition(position: string): void;
259
+ static reenableTemplatesForIOS(): void;
260
+ static disableTemplatesForIOS(): void;
261
+ static setForegroundPushCallback(callback: (notification: any) => void): void;
262
+ static setActiveForegroundPushView(): void;
263
+ static handleUniversalLink(url: string): void;
264
+ static getInsiderID(): Promise<string>;
265
+ static insiderIDListener(callback: (insiderID: string) => void): void;
266
+ static disableInAppMessages(): void;
267
+ static enableInAppMessages(): void;
268
+ /**
269
+ * Handles deep link URLs from Insider QR codes and email links.
270
+ *
271
+ * This method processes incoming URLs to enable deep linking functionality
272
+ * for features available in the Insider panel. It parses the URL and routes
273
+ * the user to the appropriate screen or action within the app, allowing
274
+ * seamless integration with Insider's panel-based features.
275
+ *
276
+ * @platform iOS only - This method is only available on iOS platform
277
+ * @param url - The URL string to be processed from Insider QR codes or email links
278
+ * @example
279
+ * RNInsider.handleURL('insider{your_partner_name}://test_device/...');
280
+ */
281
+ static handleURL(url: string): void;
250
282
  }
283
+
284
+ // The event-channel constants (NOTIFICATION_OPEN, …) are module-local in index.js and not
285
+ // exported; discriminate callbacks with `InsiderCallbackType`.
package/index.js CHANGED
@@ -1,19 +1,23 @@
1
- import { Platform, NativeModules, NativeEventEmitter } from 'react-native';
1
+ import { Platform, NativeModules } from 'react-native';
2
2
 
3
3
  import { shouldNotProceed, generateJSONErrorString, checkParameters, showParameterWarningLog, parseObjectWithTypes, isPlainObject } from './src/Util';
4
4
  import RNInsiderEvent from './src/InsiderEvent';
5
5
  import RNInsiderUser from './src/InsiderUser';
6
6
  import RNInsiderProduct from './src/InsiderProduct';
7
7
  import RNInsiderAppCards from './src/InsiderAppCards';
8
+ import RNInsiderEvents from './src/InsiderEvents';
9
+ import eventHandler from './src/EventHandler';
8
10
  import { InsiderAppCardsError, InsiderAppCardsErrorCode } from './src/InsiderAppCardsError';
11
+ import InsiderAppFrame from './src/InsiderAppFrame';
12
+ import { InsiderAppFramesError, InsiderAppFramesErrorCode, NO_DISMISS_CODE } from './src/InsiderAppFramesError';
13
+ import { InsiderAppFrameStatus } from './src/InsiderAppFrameStatus';
14
+ import { isErrorStatus, isLoadingStatus } from './src/InsiderAppFrameLogic';
9
15
  import CloseButtonPosition from './src/CloseButtonPosition';
10
16
 
11
17
  var packageJSON = require('./package.json');
12
18
 
13
19
  const Insider = NativeModules.RNInsider;
14
20
  const InsiderUser = new RNInsiderUser();
15
- const NotificationHandler = NativeModules.RNNotificationHandler;
16
- const eventHandler = new NativeEventEmitter(NotificationHandler);
17
21
 
18
22
  const NOTIFICATION_OPEN = 'NOTIFICATION_OPEN';
19
23
  const INAPP_BUTTON_CLICK = 'INAPP_BUTTON_CLICK';
@@ -43,14 +47,35 @@ function registerInsiderCallback(insiderCallback) {
43
47
  }
44
48
  }
45
49
 
46
- export { InsiderAppCardsError, InsiderAppCardsErrorCode };
50
+ function resolveAppIdentifier(functionName, appIdentifier) {
51
+ if (appIdentifier !== undefined && appIdentifier !== null && typeof appIdentifier !== 'string') {
52
+ console.warn(`[ReactNative] ${functionName}: 'appIdentifier' must be a string (got ${typeof appIdentifier}); initializing without an app identifier.`);
53
+ }
54
+ return typeof appIdentifier === 'string' && appIdentifier.length > 0 ? appIdentifier : null;
55
+ }
56
+
57
+ // The codegen view config is resolved lazily, so importing InsiderAppFrame costs nothing
58
+ // until it is first rendered.
59
+ export {
60
+ InsiderAppCardsError,
61
+ InsiderAppCardsErrorCode,
62
+ InsiderAppFrame,
63
+ InsiderAppFramesError,
64
+ InsiderAppFramesErrorCode,
65
+ InsiderAppFrameStatus,
66
+ isErrorStatus,
67
+ isLoadingStatus,
68
+ NO_DISMISS_CODE,
69
+ };
47
70
 
48
71
  export default class RNInsider {
49
72
  static closeButtonPosition = CloseButtonPosition;
50
73
  static AppCardsError = InsiderAppCardsError;
51
74
  static AppCardsErrorCode = InsiderAppCardsErrorCode;
75
+ static AppFramesError = InsiderAppFramesError;
76
+ static AppFramesErrorCode = InsiderAppFramesErrorCode;
52
77
 
53
- static init(partnerName, appGroup, insiderCallback) {
78
+ static init(partnerName, appGroup, insiderCallback, appIdentifier) {
54
79
  if (shouldNotProceed()) return;
55
80
  if (checkParameters([{ type: 'string', value: partnerName }, { type: 'string', value: appGroup }, { type: 'function', value: insiderCallback }])) {
56
81
  showParameterWarningLog("init", [
@@ -63,17 +88,18 @@ export default class RNInsider {
63
88
  try {
64
89
  registerInsiderCallback(insiderCallback);
65
90
  let sdkVersion = 'RN-' + packageJSON.version;
91
+ appIdentifier = resolveAppIdentifier("init", appIdentifier);
66
92
  if (Platform.OS === platformType.ios) {
67
- Insider.initWithLaunchOptions(null, partnerName, appGroup, sdkVersion);
93
+ Insider.initWithLaunchOptions(null, partnerName, appGroup, sdkVersion, appIdentifier);
68
94
  } else {
69
- Insider.init(partnerName, sdkVersion);
95
+ Insider.init(partnerName, sdkVersion, appIdentifier);
70
96
  }
71
97
  } catch (error) {
72
98
  Insider.putErrorLog(generateJSONErrorString(error));
73
99
  }
74
100
  }
75
101
 
76
- static initWithCustomEndpoint(partnerName, appGroup, endpoint, insiderCallback) {
102
+ static initWithCustomEndpoint(partnerName, appGroup, endpoint, insiderCallback, appIdentifier) {
77
103
  if (shouldNotProceed()) return;
78
104
  if (checkParameters([
79
105
  { type: 'string', value: partnerName },
@@ -91,10 +117,11 @@ export default class RNInsider {
91
117
  } try {
92
118
  registerInsiderCallback(insiderCallback);
93
119
  let sdkVersion = 'RN-' + packageJSON.version;
120
+ appIdentifier = resolveAppIdentifier("initWithCustomEndpoint", appIdentifier);
94
121
  if (Platform.OS === platformType.ios) {
95
- Insider.initWithCustomEndpoint(null, partnerName, appGroup, endpoint, sdkVersion);
122
+ Insider.initWithCustomEndpoint(null, partnerName, appGroup, endpoint, sdkVersion, appIdentifier);
96
123
  } else {
97
- Insider.init(partnerName, sdkVersion);
124
+ Insider.init(partnerName, sdkVersion, appIdentifier);
98
125
  Insider.setCustomEndpoint(endpoint);
99
126
  }
100
127
  } catch (error) {
@@ -134,6 +161,11 @@ export default class RNInsider {
134
161
  return RNInsiderAppCards;
135
162
  }
136
163
 
164
+ static get events() {
165
+ if (shouldNotProceed()) return;
166
+ return RNInsiderEvents;
167
+ }
168
+
137
169
  static setGDPRConsent(gdprConsent) {
138
170
  if (shouldNotProceed()) return;
139
171
  if (checkParameters([{ type: 'boolean', value: gdprConsent }])) {
@@ -586,6 +618,23 @@ export default class RNInsider {
586
618
  }
587
619
  }
588
620
 
621
+ static markContentOptimizerAsSeen(variableName) {
622
+ if (shouldNotProceed()) return;
623
+ if (checkParameters([
624
+ { type: 'string', value: variableName }
625
+ ])) {
626
+ showParameterWarningLog("markContentOptimizerAsSeen", [
627
+ { type: 'string', value: variableName }
628
+ ]);
629
+ return;
630
+ }
631
+ try {
632
+ Insider.markContentOptimizerAsSeen(variableName);
633
+ } catch (error) {
634
+ Insider.putErrorLog(generateJSONErrorString(error));
635
+ }
636
+ }
637
+
589
638
 
590
639
  // Visit Pages
591
640
  static visitHomePage(customParameters) {
@@ -897,7 +946,7 @@ export default class RNInsider {
897
946
  return;
898
947
  }
899
948
  try {
900
- if (Platform.OS !== 'android' || url == null || shouldNotProceed()) return;
949
+ if (Platform.OS !== 'android') return;
901
950
 
902
951
  Insider.handleUniversalLink(url);
903
952
  } catch (error) {