@logrocket/react-native 1.39.2 → 1.40.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.
package/android/build.gradle
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
def DEFAULT_COMPILE_SDK_VERSION = 33
|
|
14
14
|
def DEFAULT_MIN_SDK_VERSION = 25
|
|
15
15
|
def DEFAULT_TARGET_SDK_VERSION = 31
|
|
16
|
-
def SDK_VERSION = "1.
|
|
16
|
+
def SDK_VERSION = "1.40.0"
|
|
17
17
|
|
|
18
18
|
def PACKAGE_ROOT_DIR = rootProject.name == 'LogRocket SDK' ? "$rootDir/../packages/@logrocket/react-native" : "$rootDir/..";
|
|
19
19
|
|
|
@@ -18,11 +18,12 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
|
18
18
|
import com.facebook.react.bridge.ReactMethod;
|
|
19
19
|
import com.facebook.react.bridge.ReadableArray;
|
|
20
20
|
import com.facebook.react.bridge.ReadableMap;
|
|
21
|
+
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
22
|
+
import com.facebook.react.bridge.ReadableType;
|
|
21
23
|
import com.facebook.react.bridge.WritableMap;
|
|
22
24
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
23
25
|
import com.facebook.react.uimanager.util.ReactFindViewUtil;
|
|
24
26
|
import com.facebook.react.uimanager.util.ReactFindViewUtil.OnViewFoundListener;
|
|
25
|
-
import com.logrocket.core.CaptureMessageBuilder;
|
|
26
27
|
import com.logrocket.core.CustomEventBuilder;
|
|
27
28
|
import com.logrocket.core.IdentifyHelper;
|
|
28
29
|
import com.logrocket.core.LogRocketCore;
|
|
@@ -30,26 +31,28 @@ import com.logrocket.core.SDK;
|
|
|
30
31
|
import com.logrocket.core.SDK.OptionsConfiguration;
|
|
31
32
|
import com.logrocket.core.SDK.SanitizerType;
|
|
32
33
|
import com.logrocket.core.TelemetryReporter;
|
|
33
|
-
import com.logrocket.core.network.IRequestBuilder;
|
|
34
|
-
import com.logrocket.core.network.IResponseBuilder;
|
|
35
34
|
import com.logrocket.core.util.logging.Logger;
|
|
36
35
|
import com.logrocket.core.util.logging.TaggedLogger;
|
|
36
|
+
import com.logrocket.core.util.MessageReceiverHelper;
|
|
37
37
|
import java.util.ArrayList;
|
|
38
38
|
import java.util.HashMap;
|
|
39
39
|
import java.util.Iterator;
|
|
40
40
|
import java.util.List;
|
|
41
41
|
import java.util.Map;
|
|
42
42
|
import java.util.Objects;
|
|
43
|
+
import org.json.JSONArray;
|
|
44
|
+
import org.json.JSONException;
|
|
45
|
+
import org.json.JSONObject;
|
|
43
46
|
|
|
44
47
|
public class LogRocketNativeModule extends ReactContextBaseJavaModule {
|
|
45
48
|
|
|
46
49
|
private final ReactApplicationContext reactContext;
|
|
47
|
-
private final Map<String, IResponseBuilder> capturedRequests = new HashMap<>();
|
|
48
50
|
private final Logger logger = new TaggedLogger("react-native");
|
|
49
51
|
|
|
50
52
|
private static final String SDK_ERROR_ACTION = "LogRocketSDK.Error";
|
|
51
53
|
private static final String SDK_SESSION_ACCEPTED_ACTION = "LogRocketSDK.SessionAccepted";
|
|
52
54
|
private static String currentAppId = "";
|
|
55
|
+
private List<JSONArray> messageList = new ArrayList<>();
|
|
53
56
|
|
|
54
57
|
public LogRocketNativeModule(ReactApplicationContext reactContext) {
|
|
55
58
|
super(reactContext);
|
|
@@ -145,88 +148,6 @@ public class LogRocketNativeModule extends ReactContextBaseJavaModule {
|
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
@Keep
|
|
149
|
-
@ReactMethod
|
|
150
|
-
public void captureRequest(String reqId, ReadableMap request) {
|
|
151
|
-
try {
|
|
152
|
-
IRequestBuilder requestBuilder = SDK.newRequestBuilder().setUrl(request.getString("url"));
|
|
153
|
-
|
|
154
|
-
if (request.hasKey("body")) {
|
|
155
|
-
ReadableMap arson = request.getMap("body");
|
|
156
|
-
if (arson != null && arson.hasKey("arson")) {
|
|
157
|
-
requestBuilder.setArsonBody(arson.getString("arson"));
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (request.hasKey("method")) {
|
|
162
|
-
requestBuilder.setMethod(request.getString("method"));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (request.hasKey("headers") && !request.isNull("headers")) {
|
|
166
|
-
requestBuilder.setHeaders(formatReadableMap(request.getMap("headers")));
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
IResponseBuilder responseBuilder = requestBuilder.capture();
|
|
170
|
-
|
|
171
|
-
this.capturedRequests.put(reqId, responseBuilder);
|
|
172
|
-
} catch (Throwable th) {
|
|
173
|
-
this.logger.error("Error while capturing network request", th);
|
|
174
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
@Keep
|
|
179
|
-
@ReactMethod
|
|
180
|
-
public void captureResponse(String reqId, ReadableMap response) {
|
|
181
|
-
try {
|
|
182
|
-
IResponseBuilder responseBuilder = this.capturedRequests.get(reqId);
|
|
183
|
-
if (responseBuilder != null) {
|
|
184
|
-
|
|
185
|
-
if (response.hasKey("statusCode")) {
|
|
186
|
-
responseBuilder.setStatusCode(response.getInt("statusCode"));
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (response.hasKey("duration")) {
|
|
190
|
-
responseBuilder.setDuration(response.getDouble("duration"));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (response.hasKey("body")) {
|
|
194
|
-
ReadableMap arson = response.getMap("body");
|
|
195
|
-
if (arson != null && arson.hasKey("arson")) {
|
|
196
|
-
responseBuilder.setArsonBody(arson.getString("arson"));
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (response.hasKey("headers") && !response.isNull("headers")) {
|
|
201
|
-
responseBuilder.setHeaders(formatReadableMap(response.getMap("headers")));
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
responseBuilder.capture();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
} catch (Throwable th) {
|
|
208
|
-
this.logger.error("Error while capturing network response", th);
|
|
209
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
210
|
-
} finally {
|
|
211
|
-
this.capturedRequests.remove(reqId);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
@Keep
|
|
216
|
-
@ReactMethod
|
|
217
|
-
public void addLog(String level, ReadableArray args) {
|
|
218
|
-
try {
|
|
219
|
-
List<Object> argsList = args.toArrayList();
|
|
220
|
-
LogRocketCore core = LogRocketCore.maybeGetInstance();
|
|
221
|
-
|
|
222
|
-
if (core != null) {
|
|
223
|
-
core.captureReactNativeLog(level, argsList);
|
|
224
|
-
}
|
|
225
|
-
} catch (Throwable th) {
|
|
226
|
-
this.logger.error("Error while adding log", th);
|
|
227
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
151
|
|
|
231
152
|
@Keep
|
|
232
153
|
@ReactMethod
|
|
@@ -301,91 +222,6 @@ public class LogRocketNativeModule extends ReactContextBaseJavaModule {
|
|
|
301
222
|
}
|
|
302
223
|
}
|
|
303
224
|
|
|
304
|
-
@Keep
|
|
305
|
-
@ReactMethod
|
|
306
|
-
public void captureException(
|
|
307
|
-
String errorMessage, String errorType, String exceptionType, String stackTrace) {
|
|
308
|
-
try {
|
|
309
|
-
SDK.captureException(errorMessage, errorType, exceptionType, stackTrace);
|
|
310
|
-
} catch (Throwable th) {
|
|
311
|
-
this.logger.error("Error during captureException call", th);
|
|
312
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
@Keep
|
|
317
|
-
@ReactMethod
|
|
318
|
-
public void captureMessage(String message, ReadableMap options) {
|
|
319
|
-
try {
|
|
320
|
-
CaptureMessageBuilder builder = new CaptureMessageBuilder(message);
|
|
321
|
-
|
|
322
|
-
Iterator<Map.Entry<String, Object>> iterator = options.getEntryIterator();
|
|
323
|
-
while (iterator.hasNext()) {
|
|
324
|
-
Map.Entry<String, Object> entry = iterator.next();
|
|
325
|
-
String keyString = entry.getKey();
|
|
326
|
-
|
|
327
|
-
if (keyString.equals("tags") || keyString.equals("extra")) {
|
|
328
|
-
ReadableMap objectField = (ReadableMap) entry.getValue();
|
|
329
|
-
Iterator<Map.Entry<String, Object>> propIterator = objectField.getEntryIterator();
|
|
330
|
-
|
|
331
|
-
while (propIterator.hasNext()) {
|
|
332
|
-
Map.Entry<String, Object> prop = propIterator.next();
|
|
333
|
-
String propKey = prop.getKey();
|
|
334
|
-
String propValue = prop.getValue().toString();
|
|
335
|
-
if (keyString.equals("tags")) {
|
|
336
|
-
builder.putTag(propKey, propValue);
|
|
337
|
-
} else {
|
|
338
|
-
builder.putExtra(propKey, propValue);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
SDK.captureMessage(builder);
|
|
344
|
-
} catch (Throwable th) {
|
|
345
|
-
this.logger.error("Error during captureMessage call", th);
|
|
346
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
@Keep
|
|
351
|
-
@ReactMethod
|
|
352
|
-
public void captureReduxInitialState(ReadableMap data) {
|
|
353
|
-
try {
|
|
354
|
-
int storeId = data.getInt("storeId");
|
|
355
|
-
String state = data.getString("state");
|
|
356
|
-
|
|
357
|
-
LogRocketCore core = LogRocketCore.maybeGetInstance();
|
|
358
|
-
|
|
359
|
-
if (core != null) {
|
|
360
|
-
core.captureReduxInitialState(storeId, state);
|
|
361
|
-
}
|
|
362
|
-
} catch (Throwable th) {
|
|
363
|
-
this.logger.error("Error during captureReduxInitialState call", th);
|
|
364
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
@Keep
|
|
369
|
-
@ReactMethod
|
|
370
|
-
public void captureReduxAction(ReadableMap data) {
|
|
371
|
-
try {
|
|
372
|
-
int storeId = data.getInt("storeId");
|
|
373
|
-
int count = data.hasKey("count") ? data.getInt("count") : 0;
|
|
374
|
-
float duration = data.getInt("duration");
|
|
375
|
-
String stateDelta = data.getString("stateDelta");
|
|
376
|
-
String action = data.getString("action");
|
|
377
|
-
|
|
378
|
-
LogRocketCore core = LogRocketCore.maybeGetInstance();
|
|
379
|
-
|
|
380
|
-
if (core != null) {
|
|
381
|
-
core.captureReduxAction(storeId, count, duration, stateDelta, action);
|
|
382
|
-
}
|
|
383
|
-
} catch (Throwable th) {
|
|
384
|
-
this.logger.error("Error during captureReduxAction call", th);
|
|
385
|
-
TelemetryReporter.sendErrorTelemetry(th);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
225
|
@Keep
|
|
390
226
|
@ReactMethod
|
|
391
227
|
public void tagPage(String relativePage) {
|
|
@@ -439,6 +275,25 @@ public class LogRocketNativeModule extends ReactContextBaseJavaModule {
|
|
|
439
275
|
}
|
|
440
276
|
}
|
|
441
277
|
|
|
278
|
+
@Keep
|
|
279
|
+
@ReactMethod
|
|
280
|
+
public void postMessage(ReadableArray message){
|
|
281
|
+
try {
|
|
282
|
+
JSONArray array = toJSONArray(message);
|
|
283
|
+
messageList.add(array);
|
|
284
|
+
} catch (Throwable th) {
|
|
285
|
+
this.logger.error("Error while capturing message", th);
|
|
286
|
+
TelemetryReporter.sendErrorTelemetry(th);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@Keep
|
|
291
|
+
@ReactMethod
|
|
292
|
+
public void donePostingMessage() {
|
|
293
|
+
MessageReceiverHelper.rebuildMessage(messageList);
|
|
294
|
+
messageList = new ArrayList<>();
|
|
295
|
+
}
|
|
296
|
+
|
|
442
297
|
static class LogRocketReceiver extends BroadcastReceiver {
|
|
443
298
|
private final ReactApplicationContext reactContext;
|
|
444
299
|
private final Logger logger = new TaggedLogger("logrocket-receiver");
|
|
@@ -579,4 +434,105 @@ public class LogRocketNativeModule extends ReactContextBaseJavaModule {
|
|
|
579
434
|
}
|
|
580
435
|
};
|
|
581
436
|
}
|
|
437
|
+
|
|
438
|
+
// helpers found here: https://gist.github.com/mfmendiola/bb8397162df9f76681325ab9f705748b
|
|
439
|
+
/*
|
|
440
|
+
MIT License
|
|
441
|
+
Copyright (c) 2020 Marc Mendiola
|
|
442
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
443
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
444
|
+
in the Software without restriction, including without limitation the rights
|
|
445
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
446
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
447
|
+
furnished to do so, subject to the following conditions:
|
|
448
|
+
The above copyright notice and this permission notice shall be included in all
|
|
449
|
+
copies or substantial portions of the Software.
|
|
450
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
451
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
452
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
453
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
454
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
455
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
456
|
+
SOFTWARE.
|
|
457
|
+
*/
|
|
458
|
+
|
|
459
|
+
private static JSONObject toJSONObject(ReadableMap readableMap) throws JSONException {
|
|
460
|
+
JSONObject jsonObject = new JSONObject();
|
|
461
|
+
|
|
462
|
+
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
|
|
463
|
+
|
|
464
|
+
while (iterator.hasNextKey()) {
|
|
465
|
+
String key = iterator.nextKey();
|
|
466
|
+
ReadableType type = readableMap.getType(key);
|
|
467
|
+
|
|
468
|
+
switch (type) {
|
|
469
|
+
case Null:
|
|
470
|
+
// The standard Java null reference causes JSONArray.get to fail so we
|
|
471
|
+
// use JSONObject.NULL instead.
|
|
472
|
+
// reference: https://developer.android.com/reference/org/json/JSONArray
|
|
473
|
+
jsonObject.put(key, JSONObject.NULL);
|
|
474
|
+
break;
|
|
475
|
+
case Boolean:
|
|
476
|
+
jsonObject.put(key, readableMap.getBoolean(key));
|
|
477
|
+
break;
|
|
478
|
+
case Number:
|
|
479
|
+
jsonObject.put(key, readableMap.getDouble(key));
|
|
480
|
+
break;
|
|
481
|
+
case String:
|
|
482
|
+
String string = readableMap.getString(key);
|
|
483
|
+
if(string != null) {
|
|
484
|
+
jsonObject.put(key, string);
|
|
485
|
+
}
|
|
486
|
+
break;
|
|
487
|
+
case Map:
|
|
488
|
+
ReadableMap map = readableMap.getMap(key);
|
|
489
|
+
if(map != null) {
|
|
490
|
+
jsonObject.put(key, toJSONObject(map));
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
case Array:
|
|
494
|
+
ReadableArray array = readableMap.getArray(key);
|
|
495
|
+
if(array != null) {
|
|
496
|
+
jsonObject.put(key, toJSONArray(array));
|
|
497
|
+
}
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return jsonObject;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
private static JSONArray toJSONArray(ReadableArray readableArray) throws JSONException {
|
|
506
|
+
JSONArray jsonArray = new JSONArray();
|
|
507
|
+
|
|
508
|
+
for (int i = 0; i < readableArray.size(); i++) {
|
|
509
|
+
ReadableType type = readableArray.getType(i);
|
|
510
|
+
|
|
511
|
+
switch (type) {
|
|
512
|
+
case Null:
|
|
513
|
+
// The standard Java null reference causes JSONArray.get to fail so we
|
|
514
|
+
// use JSONObject.NULL instead.
|
|
515
|
+
// reference: https://developer.android.com/reference/org/json/JSONArray
|
|
516
|
+
jsonArray.put(i, JSONObject.NULL);
|
|
517
|
+
break;
|
|
518
|
+
case Boolean:
|
|
519
|
+
jsonArray.put(i, readableArray.getBoolean(i));
|
|
520
|
+
break;
|
|
521
|
+
case Number:
|
|
522
|
+
jsonArray.put(i, readableArray.getDouble(i));
|
|
523
|
+
break;
|
|
524
|
+
case String:
|
|
525
|
+
jsonArray.put(i, readableArray.getString(i));
|
|
526
|
+
break;
|
|
527
|
+
case Map:
|
|
528
|
+
jsonArray.put(i, toJSONObject(readableArray.getMap(i)));
|
|
529
|
+
break;
|
|
530
|
+
case Array:
|
|
531
|
+
jsonArray.put(i, toJSONArray(readableArray.getArray(i)));
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return jsonArray;
|
|
537
|
+
}
|
|
582
538
|
}
|