react-native-insider 7.0.5-nh → 7.0.6-nh

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.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Generate PR description using project template
3
+ argument-hint: "[base-branch]"
4
+ ---
5
+
6
+ Generate a PR description using the template in .github/pull_request_template.md file.
7
+
8
+ If the user provided a base branch argument, use that: $1
9
+ Otherwise, automatically detect the base branch by:
10
+ 1. First checking if there's an upstream branch set
11
+ 2. If not, use the default main branch (develop, main, or master)
12
+
13
+ Compare the current branch against this base branch.
14
+
15
+ Requirements:
16
+ - Write the description as markdown text
17
+ - This is a React Native SDK project with iOS (Objective-C) and Android (Java) native modules
18
+ - Highlight code elements (classes, methods, imports, etc.) using backticks
19
+ - Never mention classes with full paths, just wrap class names with backticks (e.g., `InsiderIdentifier` not `src/InsiderIdentifier.js`)
20
+ - For native code references, use simple class names: `RNInsider` (not `ios/RNInsider/RNInsider.m`) or `RNInsiderModule` (not `android/src/main/java/com/useinsider/react/RNInsiderModule.java`)
21
+ - If the current branch name contains the format "MOB-[0-9]+" (e.g., feature/MOB-1234), extract the ticket number and create a JIRA URL: https://winsider.atlassian.net/browse/MOB-XXXX
22
+ - Include manual testing recommendations in the test cases section of the template
23
+ - Keep it high-level and avoid getting into too much technical detail
24
+ - Focus on what changed and why, not the implementation details
25
+ - When describing changes, specify if they affect iOS, Android, or both platforms
26
+
27
+ Output Format:
28
+ - **IMPORTANT**: Wrap the entire PR description in a markdown code block using triple backticks (```markdown ... ```)
29
+ - This allows the user to easily copy the raw markdown without formatting issues
30
+ - The output should be a single markdown code block containing all the PR description content
31
+
32
+ Steps:
33
+ 1. Read the PR template from .github/pull_request_template.md
34
+ 2. Get the git diff comparing current branch against the base branch
35
+ 3. Get the commit history for context
36
+ 4. Extract the JIRA ticket number from the branch name if present
37
+ 5. Analyze the changes across iOS, Android, and JavaScript/TypeScript code
38
+ 6. Identify which platform(s) are affected (iOS, Android, or both)
39
+ 7. Generate a clear, concise PR description following the template format
40
+ 8. Wrap the entire output in a ```markdown code block for easy copying
@@ -0,0 +1,34 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git:*)",
5
+ "Bash(npm run:*)",
6
+ "Edit(ios/**)",
7
+ "Edit(index.d.ts)",
8
+ "Edit(index.js)",
9
+ "Edit(src/**)",
10
+ "Edit(android/**)",
11
+ "Read(.github/**)",
12
+ "Read(.claude/**)",
13
+ "WebSearch",
14
+ "WebFetch(domain:academy.insiderone.com)"
15
+ ],
16
+ "deny": [
17
+ "Bash(sudo:*)",
18
+ "Bash(curl:*)",
19
+ "Bash(wget:*)",
20
+ "Bash(fetch:*)",
21
+ "Bash(git push:*)",
22
+ "Bash(git push --force:*)",
23
+ "Read(./.env*)",
24
+ "Read(./secrets/**)",
25
+ "Read(./config/credentials.json)"
26
+ ],
27
+ "ask": [
28
+ "Bash(pod install:*)",
29
+ "Bash(pod update:*)",
30
+ "Bash(rm:*)",
31
+ "Bash(git commit:*)"
32
+ ]
33
+ }
34
+ }
package/RNInsider.podspec CHANGED
@@ -9,12 +9,12 @@ Pod::Spec.new do |s|
9
9
  s.authors = package_json['author']
10
10
  s.license = 'MIT'
11
11
  s.platform = :ios, '12.0'
12
- s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/14.2.2/InsiderMobileIOSFramework.zip'}
12
+ s.source = {:http => 'https://mobilesdk.useinsider.com/iOS/14.2.3/InsiderMobileIOSFramework.zip'}
13
13
  s.source_files = 'ios/RNInsider/*.{h,m}'
14
14
  s.requires_arc = true
15
15
  s.static_framework = true
16
16
  s.dependency 'React'
17
- s.dependency 'InsiderMobile', '14.2.2'
17
+ s.dependency 'InsiderMobile', '14.2.3'
18
18
  s.dependency 'InsiderGeofence', '1.2.4'
19
19
  s.dependency 'InsiderHybrid', '1.7.6'
20
20
  end
@@ -31,7 +31,7 @@ import com.useinsider.insider.InsiderIDListener;
31
31
  import org.json.JSONArray;
32
32
  import org.json.JSONObject;
33
33
 
34
- import java.util.ArrayList;
34
+ import java.util.Date;
35
35
  import java.util.HashMap;
36
36
  import java.util.Map;
37
37
 
@@ -124,9 +124,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
124
124
  }
125
125
 
126
126
  @ReactMethod
127
- public void tagEvent(String eventName, ReadableMap parameters) {
127
+ public void tagEvent(String eventName, ReadableArray parameters) {
128
128
  try {
129
- InsiderHybrid.tagEvent(eventName, RNUtils.convertReadableMapToMap(parameters));
129
+ RNUtils.parseEvent(eventName, parameters).build();
130
130
  } catch (Exception e) {
131
131
  Insider.Instance.putException(e);
132
132
  }
@@ -144,7 +144,10 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
144
144
  @ReactMethod
145
145
  public void setBirthday(String birthday) {
146
146
  try {
147
- InsiderHybrid.setBirthday(birthday);
147
+ // React Native's bridge does not support long type directly, so we use String to pass epoch time.
148
+ long birthdayEpoch = Long.parseLong(birthday);
149
+ Date birthdayDate = new Date(birthdayEpoch);
150
+ Insider.Instance.getCurrentUser().setBirthday(birthdayDate);
148
151
  } catch (Exception e) {
149
152
  Insider.Instance.putException(e);
150
153
  }
@@ -298,7 +301,7 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
298
301
  }
299
302
  }
300
303
 
301
- private InsiderIdentifiers setIdentifiers (ReadableMap identifiers) {
304
+ private InsiderIdentifiers setIdentifiers(ReadableMap identifiers) {
302
305
  try {
303
306
  HashMap<String, Object> mappedIdentifiers = RNUtils.convertReadableMapToMap(identifiers);
304
307
  InsiderIdentifiers insiderIdentifiers = new InsiderIdentifiers();
@@ -411,7 +414,10 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
411
414
  @ReactMethod
412
415
  public void setCustomAttributeWithDate(String key, String value) {
413
416
  try {
414
- InsiderHybrid.setCustomAttributeWithDate(key, value);
417
+ // React Native's bridge does not support long type directly, so we use String to pass epoch time.
418
+ long valueEpoch = Long.parseLong(value);
419
+ Date valueDate = new Date(valueEpoch);
420
+ Insider.Instance.getCurrentUser().setCustomAttributeWithDate(key, valueDate);
415
421
  } catch (Exception e) {
416
422
  Insider.Instance.putException(e);
417
423
  }
@@ -459,10 +465,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
459
465
  }
460
466
 
461
467
  @ReactMethod
462
- public void itemPurchased(String saleID, ReadableMap productMustMap, ReadableMap productOptMap) {
468
+ public void itemPurchased(String saleID, ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
463
469
  try {
464
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
465
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
470
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
466
471
  Insider.Instance.itemPurchased(saleID, product);
467
472
  } catch (Exception e) {
468
473
  Insider.Instance.putException(e);
@@ -470,10 +475,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
470
475
  }
471
476
 
472
477
  @ReactMethod
473
- public void itemAddedToCart(ReadableMap productMustMap, ReadableMap productOptMap) {
478
+ public void itemAddedToCart(ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
474
479
  try {
475
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
476
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
480
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
477
481
  Insider.Instance.itemAddedToCart(product);
478
482
  } catch (Exception e) {
479
483
  Insider.Instance.putException(e);
@@ -499,10 +503,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
499
503
  }
500
504
 
501
505
  @ReactMethod
502
- public void itemAddedToWishlist(ReadableMap productMustMap, ReadableMap productOptMap) {
506
+ public void itemAddedToWishlist(ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
503
507
  try {
504
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
505
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
508
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
506
509
  Insider.Instance.itemAddedToWishlist(product);
507
510
  } catch (Exception e) {
508
511
  Insider.Instance.putException(e);
@@ -570,11 +573,10 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
570
573
  }
571
574
 
572
575
  @ReactMethod
573
- public void getSmartRecommendationWithProduct(ReadableMap productMustMap, ReadableMap productOptMap,
576
+ public void getSmartRecommendationWithProduct(ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters,
574
577
  int recommendationID, String locale, final Callback callback) {
575
578
  try {
576
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
577
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
579
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
578
580
  Insider.Instance.getSmartRecommendationWithProduct(product, recommendationID, locale,
579
581
  new RecommendationEngine.SmartRecommendation() {
580
582
  @Override
@@ -613,11 +615,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
613
615
  }
614
616
 
615
617
  @ReactMethod
616
- public void clickSmartRecommendationProduct(int recommendationID, ReadableMap productMustMap,
617
- ReadableMap productOptMap) {
618
+ public void clickSmartRecommendationProduct(int recommendationID, ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
618
619
  try {
619
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
620
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
620
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
621
621
  Insider.Instance.clickSmartRecommendationProduct(recommendationID, product);
622
622
  } catch (Exception e) {
623
623
  Insider.Instance.putException(e);
@@ -705,10 +705,9 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
705
705
  }
706
706
 
707
707
  @ReactMethod
708
- public void visitProductDetailPage(ReadableMap productMustMap, ReadableMap productOptMap) {
708
+ public void visitProductDetailPage(ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
709
709
  try {
710
- HashMap optMap = RNUtils.fixIntegerAttributesInMap(RNUtils.convertReadableMapToMap(productOptMap));
711
- InsiderProduct product = InsiderHybrid.createProduct(RNUtils.convertReadableMapToMap(productMustMap), optMap);
710
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
712
711
  Insider.Instance.visitProductDetailPage(product);
713
712
  } catch (Exception e) {
714
713
  Insider.Instance.putException(e);
@@ -720,10 +719,11 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
720
719
  try {
721
720
  InsiderProduct[] ips = new InsiderProduct[products.size()];
722
721
  for (int i = 0; i < products.size(); i++) {
723
- HashMap productsMap = RNUtils.convertReadableMapToMap(products.getMap(i));
724
- HashMap optMap = RNUtils.fixIntegerAttributesInMap((HashMap<String, Object>) productsMap.get("productOptMap"));
725
- InsiderProduct product = InsiderHybrid
726
- .createProduct((HashMap<String, Object>) productsMap.get("productMustMap"), optMap);
722
+ ReadableMap productMap = products.getMap(i);
723
+ ReadableMap requiredFields = productMap.getMap("requiredFields");
724
+ ReadableMap optionalFields = productMap.getMap("optionalFields");
725
+ ReadableArray customParameters = productMap.getArray("customParameters");
726
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
727
727
  ips[i] = product;
728
728
  }
729
729
  Insider.Instance.visitCartPage(ips);
@@ -737,10 +737,11 @@ public class RNInsiderModule extends ReactContextBaseJavaModule {
737
737
  try {
738
738
  InsiderProduct[] ips = new InsiderProduct[products.size()];
739
739
  for (int i = 0; i < products.size(); i++) {
740
- HashMap productsMap = RNUtils.convertReadableMapToMap(products.getMap(i));
741
- HashMap optMap = RNUtils.fixIntegerAttributesInMap((HashMap<String, Object>) productsMap.get("productOptMap"));
742
- InsiderProduct product = InsiderHybrid
743
- .createProduct((HashMap<String, Object>) productsMap.get("productMustMap"), optMap);
740
+ ReadableMap productMap = products.getMap(i);
741
+ ReadableMap requiredFields = productMap.getMap("requiredFields");
742
+ ReadableMap optionalFields = productMap.getMap("optionalFields");
743
+ ReadableArray customParameters = productMap.getArray("customParameters");
744
+ InsiderProduct product = RNUtils.parseProduct(requiredFields, optionalFields, customParameters);
744
745
  ips[i] = product;
745
746
  }
746
747
  Insider.Instance.visitWishlistPage(ips);
@@ -9,18 +9,17 @@ import com.facebook.react.bridge.WritableMap;
9
9
  import com.facebook.react.bridge.WritableNativeArray;
10
10
  import com.facebook.react.bridge.WritableNativeMap;
11
11
  import com.useinsider.insider.Insider;
12
+ import com.useinsider.insider.InsiderEvent;
13
+ import com.useinsider.insider.InsiderProduct;
12
14
 
13
15
  import org.json.JSONArray;
14
16
  import org.json.JSONException;
15
17
  import org.json.JSONObject;
16
18
 
17
- import java.text.DateFormat;
18
- import java.text.SimpleDateFormat;
19
19
  import java.util.ArrayList;
20
20
  import java.util.Date;
21
21
  import java.util.HashMap;
22
22
  import java.util.Iterator;
23
- import java.util.List;
24
23
  import java.util.Map;
25
24
 
26
25
  public class RNUtils {
@@ -30,7 +29,7 @@ public class RNUtils {
30
29
  try {
31
30
  for (String key : map.keySet()) {
32
31
  writableMap.putString(key, map.get(key));
33
- }
32
+ }
34
33
  } catch (Exception e) {
35
34
  Insider.Instance.putException(e);
36
35
  }
@@ -86,7 +85,7 @@ public class RNUtils {
86
85
  } else {
87
86
  map.putString(key, value.toString());
88
87
  }
89
- }
88
+ }
90
89
  } catch (Exception e) {
91
90
  Insider.Instance.putException(e);
92
91
  }
@@ -117,13 +116,12 @@ public class RNUtils {
117
116
  ReadableArray array = readableMap.getArray(key);
118
117
  if (isConvertibleToNumericArray(array)) {
119
118
  map.put(key, convertReadableArrayToNumericArray(array));
120
- }
121
- else {
119
+ } else {
122
120
  map.put(key, convertReadableArrayToStringArray(array));
123
121
  }
124
122
  break;
125
123
  }
126
- }
124
+ }
127
125
  } catch (Exception e) {
128
126
  Insider.Instance.putException(e);
129
127
  }
@@ -190,4 +188,195 @@ public class RNUtils {
190
188
  }
191
189
  return true;
192
190
  }
191
+
192
+ static InsiderEvent parseEvent(String eventName, ReadableArray parameters) {
193
+ InsiderEvent event = Insider.Instance.tagEvent(eventName);
194
+
195
+ for (int i = 0; i < parameters.size(); i++) {
196
+ ReadableMap parameter = parameters.getMap(i);
197
+ if (parameter == null) continue;
198
+
199
+ String type = parameter.getString("type");
200
+ String key = parameter.getString("key");
201
+ if (type == null || key == null) continue;
202
+
203
+ switch (type) {
204
+ case "string":
205
+ String stringValue = parameter.getString("value");
206
+ event.addParameterWithString(key, stringValue);
207
+ break;
208
+ case "integer":
209
+ int intValue = parameter.getInt("value");
210
+ event.addParameterWithInt(key, intValue);
211
+ break;
212
+ case "double":
213
+ double doubleValue = parameter.getDouble("value");
214
+ event.addParameterWithDouble(key, doubleValue);
215
+ break;
216
+ case "boolean":
217
+ boolean booleanValue = parameter.getBoolean("value");
218
+ event.addParameterWithBoolean(key, booleanValue);
219
+ break;
220
+ case "date":
221
+ // React Native's bridge does not support long type directly, so we use String to pass epoch time.
222
+ long epochValue = Long.parseLong(parameter.getString("value"));
223
+ Date dateValue = new Date(epochValue);
224
+ event.addParameterWithDate(key, dateValue);
225
+ break;
226
+ case "strings":
227
+ ReadableArray stringsArray = parameter.getArray("value");
228
+ String[] stringsValue = RNUtils.convertReadableArrayToStringArray(stringsArray);
229
+ event.addParameterWithStringArray(key, stringsValue);
230
+ break;
231
+ case "numbers":
232
+ ReadableArray numbersArray = parameter.getArray("value");
233
+ Number[] numbersValue = RNUtils.convertReadableArrayToNumericArray(numbersArray);
234
+ event.addParameterWithNumericArray(key, numbersValue);
235
+ break;
236
+ default:
237
+ throw new IllegalArgumentException("Unknown parameter type received.");
238
+ }
239
+ }
240
+
241
+ return event;
242
+ }
243
+
244
+ static InsiderProduct parseProduct(ReadableMap requiredFields, ReadableMap optionalFields, ReadableArray customParameters) {
245
+ // apply required fields
246
+ String productId = requiredFields.getString("product_id");
247
+ String name = requiredFields.getString("name");
248
+ ReadableArray taxonomyReadableArray = requiredFields.getArray("taxonomy");
249
+ String[] taxonomy = RNUtils.convertReadableArrayToStringArray(taxonomyReadableArray);
250
+ String imageURL = requiredFields.getString("image_url");
251
+ double price = requiredFields.getDouble("price");
252
+ String currency = requiredFields.getString("currency");
253
+ InsiderProduct product = Insider.Instance.createNewProduct(productId, name, taxonomy, imageURL, price, currency);
254
+
255
+ // apply optional fields
256
+ Iterator<Map.Entry<String, Object>> optionalIterator = optionalFields.getEntryIterator();
257
+ while (optionalIterator.hasNext()) {
258
+ Map.Entry<String, Object> parameter = optionalIterator.next();
259
+ String key = parameter.getKey();
260
+ Object value = parameter.getValue();
261
+
262
+ switch (key) {
263
+ case "color":
264
+ product.setColor((String) value);
265
+ break;
266
+ case "voucher_name":
267
+ product.setVoucherName((String) value);
268
+ break;
269
+ case "promotion_name":
270
+ product.setPromotionName((String) value);
271
+ break;
272
+ case "size":
273
+ product.setSize((String) value);
274
+ break;
275
+ case "sale_price":
276
+ product.setSalePrice((double) value);
277
+ break;
278
+ case "shipping_cost":
279
+ product.setShippingCost((double) value);
280
+ break;
281
+ case "voucher_discount":
282
+ product.setVoucherDiscount((double) value);
283
+ break;
284
+ case "promotion_discount":
285
+ product.setPromotionDiscount((double) value);
286
+ break;
287
+ case "stock":
288
+ Double stockNumber = (Double) value;
289
+ product.setStock(stockNumber.intValue());
290
+ break;
291
+ case "quantity":
292
+ Double quantityNumber = (Double) value;
293
+ product.setQuantity(quantityNumber.intValue());
294
+ break;
295
+ case "group_code":
296
+ product.setGroupCode((String) value);
297
+ break;
298
+ case "brand":
299
+ product.setBrand((String) value);
300
+ break;
301
+ case "sku":
302
+ product.setSku((String) value);
303
+ break;
304
+ case "gender":
305
+ product.setGender((String) value);
306
+ break;
307
+ case "multipack":
308
+ product.setMultipack((String) value);
309
+ break;
310
+ case "product_type":
311
+ product.setProductType((String) value);
312
+ break;
313
+ case "gtin":
314
+ product.setGtin((String) value);
315
+ break;
316
+ case "description":
317
+ product.setDescription((String) value);
318
+ break;
319
+ case "tags":
320
+ ReadableArray tagsReadableArray = (ReadableArray) value;
321
+ String[] tagsArray = RNUtils.convertReadableArrayToStringArray(tagsReadableArray);
322
+ product.setTags(tagsArray);
323
+ break;
324
+ case "in_stock":
325
+ product.setInStock((boolean) value);
326
+ break;
327
+ case "product_url":
328
+ product.setProductURL((String) value);
329
+ break;
330
+ }
331
+ }
332
+
333
+ // apply custom parameters
334
+ for (int i = 0; i < customParameters.size(); i++) {
335
+ ReadableMap parameter = customParameters.getMap(i);
336
+ if (parameter == null) continue;
337
+
338
+ String type = parameter.getString("type");
339
+ String key = parameter.getString("key");
340
+ if (type == null || key == null) continue;
341
+
342
+ switch (type) {
343
+ case "string":
344
+ String stringValue = parameter.getString("value");
345
+ product.setCustomAttributeWithString(key, stringValue);
346
+ break;
347
+ case "integer":
348
+ int intValue = parameter.getInt("value");
349
+ product.setCustomAttributeWithInt(key, intValue);
350
+ break;
351
+ case "double":
352
+ double doubleValue = parameter.getDouble("value");
353
+ product.setCustomAttributeWithDouble(key, doubleValue);
354
+ break;
355
+ case "boolean":
356
+ boolean booleanValue = parameter.getBoolean("value");
357
+ product.setCustomAttributeWithBoolean(key, booleanValue);
358
+ break;
359
+ case "date":
360
+ // React Native's bridge does not support long type directly, so we use String to pass epoch time.
361
+ long epochValue = Long.parseLong(parameter.getString("value"));
362
+ Date dateValue = new Date(epochValue);
363
+ product.setCustomAttributeWithDate(key, dateValue);
364
+ break;
365
+ case "strings":
366
+ ReadableArray stringsArray = parameter.getArray("value");
367
+ String[] stringsValue = RNUtils.convertReadableArrayToStringArray(stringsArray);
368
+ product.setCustomAttributeWithStringArray(key, stringsValue);
369
+ break;
370
+ case "numbers":
371
+ ReadableArray numbersArray = parameter.getArray("value");
372
+ Number[] numbersValue = RNUtils.convertReadableArrayToNumericArray(numbersArray);
373
+ product.setCustomAttributeWithNumericArray(key, numbersValue);
374
+ break;
375
+ default:
376
+ throw new IllegalArgumentException("Unknown parameter type received.");
377
+ }
378
+ }
379
+
380
+ return product;
381
+ }
193
382
  }
package/index.d.ts CHANGED
@@ -115,6 +115,20 @@ declare module 'react-native-insider' {
115
115
  static insiderIDListener(callback: (insiderID: string) => void): void;
116
116
  static disableInAppMessages(): void;
117
117
  static enableInAppMessages(): void;
118
+ /**
119
+ * Handles deep link URLs from Insider QR codes and email links.
120
+ *
121
+ * This method processes incoming URLs to enable deep linking functionality
122
+ * for features available in the Insider panel. It parses the URL and routes
123
+ * the user to the appropriate screen or action within the app, allowing
124
+ * seamless integration with Insider's panel-based features.
125
+ *
126
+ * @platform iOS only - This method is only available on iOS platform
127
+ * @param url - The URL string to be processed from Insider QR codes or email links
128
+ * @example
129
+ * RNInsider.handleURL('insider{your_partner_name}://test_device/...');
130
+ */
131
+ static handleURL(url: string): void;
118
132
  }
119
133
 
120
134
  export const NOTIFICATION_OPEN: string;
package/index.js CHANGED
@@ -184,7 +184,7 @@ export default class RNInsider {
184
184
  return;
185
185
  }
186
186
  try {
187
- Insider.itemPurchased(uniqueSaleID, product.productMustMap, product.productOptMap);
187
+ Insider.itemPurchased(uniqueSaleID, product.requiredFields, product.optionalFields, product.customParameters);
188
188
  } catch (error) {
189
189
  Insider.putErrorLog(generateJSONErrorString(error));
190
190
  }
@@ -197,7 +197,7 @@ export default class RNInsider {
197
197
  return;
198
198
  }
199
199
  try {
200
- Insider.itemAddedToCart(product.productMustMap, product.productOptMap);
200
+ Insider.itemAddedToCart(product.requiredFields, product.optionalFields, product.customParameters);
201
201
  } catch (error) {
202
202
  Insider.putErrorLog(generateJSONErrorString(error));
203
203
  }
@@ -225,16 +225,16 @@ export default class RNInsider {
225
225
  }
226
226
  }
227
227
 
228
- static itemAddedToWishlist(product: RNInsiderProduct) {
228
+ static itemAddedToWishlist(product) {
229
229
  if (shouldNotProceed() || product == null) return;
230
230
  try {
231
- Insider.itemAddedToWishlist(product.productMustMap, product.productOptMap);
231
+ Insider.itemAddedToWishlist(product.requiredFields, product.optionalFields, product.customParameters);
232
232
  } catch (error) {
233
233
  Insider.putErrorLog(generateJSONErrorString(error));
234
234
  }
235
235
  }
236
236
 
237
- static itemRemovedFromWishlist(productID: string) {
237
+ static itemRemovedFromWishlist(productID) {
238
238
  if (shouldNotProceed() || productID == null) return;
239
239
  try {
240
240
  Insider.itemRemovedFromWishlist(productID);
@@ -329,7 +329,7 @@ export default class RNInsider {
329
329
  return;
330
330
  }
331
331
  try {
332
- Insider.getSmartRecommendationWithProduct(product.productMustMap, product.productOptMap, recommendationID, locale, (recommendation) => {
332
+ Insider.getSmartRecommendationWithProduct(product.requiredFields, product.optionalFields, product.customParameters, recommendationID, locale, (recommendation) => {
333
333
  callback(recommendation);
334
334
  });
335
335
  } catch (error) {
@@ -379,7 +379,7 @@ export default class RNInsider {
379
379
  return;
380
380
  }
381
381
  try {
382
- Insider.clickSmartRecommendationProduct(recommendationID, product.productMustMap, product.productOptMap);
382
+ Insider.clickSmartRecommendationProduct(recommendationID, product.requiredFields, product.optionalFields, product.customParameters);
383
383
  } catch (error) {
384
384
  Insider.putErrorLog(generateJSONErrorString(error));
385
385
  }
@@ -555,7 +555,7 @@ export default class RNInsider {
555
555
  return;
556
556
  }
557
557
  try {
558
- Insider.visitProductDetailPage(product.productMustMap, product.productOptMap);
558
+ Insider.visitProductDetailPage(product.requiredFields, product.optionalFields, product.customParameters);
559
559
  } catch (error) {
560
560
  Insider.putErrorLog(generateJSONErrorString(error));
561
561
  }
@@ -567,35 +567,35 @@ export default class RNInsider {
567
567
  showParameterWarningLog("visitCartPage", [{ type: 'object', value: products }]);
568
568
  return;
569
569
  }
570
- let mappedProducts = new Array(products.length);
571
570
  try {
572
- products.forEach((product, i) => {
573
- let productMap = {};
574
- productMap['productMustMap'] = product.productMustMap;
575
- productMap['productOptMap'] = product.productOptMap;
576
- mappedProducts[i] = productMap;
577
- });
571
+ const mappedProducts = products.map(product => ({
572
+ requiredFields: product.requiredFields,
573
+ optionalFields: product.optionalFields,
574
+ customParameters: product.customParameters
575
+ }));
578
576
  Insider.visitCartPage(mappedProducts);
579
577
  } catch (error) {
580
578
  Insider.putErrorLog(generateJSONErrorString(error));
581
579
  }
582
580
  }
583
581
 
584
- static visitWishlistPage(products: Array<RNInsiderProduct>) {
585
- if (shouldNotProceed() || products == null) return;
586
- let mappedProducts = new Array(products.length);
587
- try {
588
- products.forEach((product, i) => {
589
- let productMap = {};
590
- productMap['productMustMap'] = product.productMustMap;
591
- productMap['productOptMap'] = product.productOptMap;
592
- mappedProducts[i] = productMap;
593
- });
594
- Insider.visitWishlistPage(mappedProducts);
595
- } catch (error) {
596
- Insider.putErrorLog(generateJSONErrorString(error));
597
- }
582
+ static visitWishlistPage(products) {
583
+ if (shouldNotProceed() || products == null) return;
584
+ if (checkParameters([{ type: 'object', value: products }])) {
585
+ showParameterWarningLog("visitWishlistPage", [{ type: 'object', value: products }]);
586
+ return;
598
587
  }
588
+ try {
589
+ const mappedProducts = products.map(product => ({
590
+ requiredFields: product.requiredFields,
591
+ optionalFields: product.optionalFields,
592
+ customParameters: product.customParameters
593
+ }));
594
+ Insider.visitWishlistPage(mappedProducts);
595
+ } catch (error) {
596
+ Insider.putErrorLog(generateJSONErrorString(error));
597
+ }
598
+ }
599
599
 
600
600
  static startTrackingGeofence() {
601
601
  if (shouldNotProceed()) return;
@@ -848,4 +848,16 @@ export default class RNInsider {
848
848
  Insider.putErrorLog(generateJSONErrorString(error));
849
849
  }
850
850
  }
851
+
852
+ static handleURL(url) {
853
+ if (shouldNotProceed()) return;
854
+
855
+ try {
856
+ if (Platform.OS === 'android') return;
857
+
858
+ Insider.handleURL(url);
859
+ } catch (error) {
860
+ Insider.putErrorLog(generateJSONErrorString(error));
861
+ }
862
+ }
851
863
  }