@sentry/react-native 8.4.0 → 8.5.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 (98) hide show
  1. package/android/build.gradle +2 -2
  2. package/android/libs/replay-stubs.jar +0 -0
  3. package/android/replay-stubs/build.gradle +1 -1
  4. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +56 -4
  5. package/android/src/main/java/io/sentry/react/RNSentryStart.java +3 -0
  6. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  7. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +10 -0
  8. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +10 -0
  9. package/dist/js/NativeRNSentry.d.ts +2 -0
  10. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  11. package/dist/js/NativeRNSentry.js.map +1 -1
  12. package/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  13. package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
  14. package/dist/js/feedback/FeedbackWidgetManager.js +15 -1
  15. package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
  16. package/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  17. package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -1
  18. package/dist/js/feedback/FeedbackWidgetProvider.js +12 -4
  19. package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -1
  20. package/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  21. package/dist/js/feedback/ShakeToReportBug.d.ts.map +1 -0
  22. package/dist/js/feedback/ShakeToReportBug.js +83 -0
  23. package/dist/js/feedback/ShakeToReportBug.js.map +1 -0
  24. package/dist/js/feedback/integration.d.ts +11 -0
  25. package/dist/js/feedback/integration.d.ts.map +1 -1
  26. package/dist/js/feedback/integration.js +7 -1
  27. package/dist/js/feedback/integration.js.map +1 -1
  28. package/dist/js/index.d.ts +1 -1
  29. package/dist/js/index.d.ts.map +1 -1
  30. package/dist/js/index.js +1 -1
  31. package/dist/js/index.js.map +1 -1
  32. package/dist/js/integrations/debugsymbolicator.js +3 -1
  33. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  34. package/dist/js/integrations/default.d.ts.map +1 -1
  35. package/dist/js/integrations/default.js +2 -1
  36. package/dist/js/integrations/default.js.map +1 -1
  37. package/dist/js/integrations/exports.d.ts +1 -0
  38. package/dist/js/integrations/exports.d.ts.map +1 -1
  39. package/dist/js/integrations/exports.js +1 -0
  40. package/dist/js/integrations/exports.js.map +1 -1
  41. package/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  42. package/dist/js/integrations/expoupdateslistener.d.ts.map +1 -0
  43. package/dist/js/integrations/expoupdateslistener.js +130 -0
  44. package/dist/js/integrations/expoupdateslistener.js.map +1 -0
  45. package/dist/js/misc.js +2 -2
  46. package/dist/js/misc.js.map +1 -1
  47. package/dist/js/options.d.ts +12 -0
  48. package/dist/js/options.d.ts.map +1 -1
  49. package/dist/js/options.js.map +1 -1
  50. package/dist/js/tools/utils.d.ts.map +1 -1
  51. package/dist/js/tools/utils.js +2 -3
  52. package/dist/js/tools/utils.js.map +1 -1
  53. package/dist/js/tracing/integrations/appStart.d.ts +8 -0
  54. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
  55. package/dist/js/tracing/integrations/appStart.js +56 -7
  56. package/dist/js/tracing/integrations/appStart.js.map +1 -1
  57. package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -1
  58. package/dist/js/tracing/integrations/nativeFrames.js +32 -22
  59. package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
  60. package/dist/js/tracing/integrations/timeToDisplayIntegration.d.ts.map +1 -1
  61. package/dist/js/tracing/integrations/timeToDisplayIntegration.js +1 -0
  62. package/dist/js/tracing/integrations/timeToDisplayIntegration.js.map +1 -1
  63. package/dist/js/tracing/reactnativenavigation.js +1 -1
  64. package/dist/js/tracing/reactnativenavigation.js.map +1 -1
  65. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  66. package/dist/js/tracing/reactnavigation.js +3 -1
  67. package/dist/js/tracing/reactnavigation.js.map +1 -1
  68. package/dist/js/utils/ignorerequirecyclelogs.js +1 -1
  69. package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
  70. package/dist/js/utils/safe.d.ts +1 -1
  71. package/dist/js/utils/safe.d.ts.map +1 -1
  72. package/dist/js/utils/safe.js.map +1 -1
  73. package/dist/js/version.d.ts +1 -1
  74. package/dist/js/version.js +1 -1
  75. package/dist/js/version.js.map +1 -1
  76. package/ios/RNSentry.mm +47 -1
  77. package/ios/RNSentryEvents.h +1 -0
  78. package/ios/RNSentryEvents.m +1 -0
  79. package/ios/RNSentryVersion.m +1 -1
  80. package/package.json +13 -13
  81. package/plugin/build/withSentry.js +1 -1
  82. package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
  83. package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
  84. package/scripts/sentry-xcode.sh +14 -0
  85. package/sentry.gradle +13 -0
  86. package/src/js/NativeRNSentry.ts +2 -0
  87. package/ts3.8/dist/js/NativeRNSentry.d.ts +2 -0
  88. package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  89. package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  90. package/ts3.8/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  91. package/ts3.8/dist/js/feedback/integration.d.ts +11 -0
  92. package/ts3.8/dist/js/index.d.ts +1 -1
  93. package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
  94. package/ts3.8/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  95. package/ts3.8/dist/js/options.d.ts +12 -0
  96. package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +8 -0
  97. package/ts3.8/dist/js/utils/safe.d.ts +1 -1
  98. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  import type { ReactNativeOptions } from '../options';
2
- type DangerTypesWithoutCallSignature = Object | null | undefined;
2
+ type DangerTypesWithoutCallSignature = object | null | undefined;
3
3
  /**
4
4
  * Returns callback factory wrapped with try/catch
5
5
  * or the original passed value is it's not a function.
@@ -1 +1 @@
1
- {"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,KAAK,+BAA+B,GAElC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAE5B;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,+BAA+B,EACnG,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAC/B,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAgBzB;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,GACjD,kBAAkB,CAAC,eAAe,CAAC,CAarC"}
1
+ {"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,KAAK,+BAA+B,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,+BAA+B,EACnG,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAC/B,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAgBzB;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,GACjD,kBAAkB,CAAC,eAAe,CAAC,CAarC"}
@@ -1 +1 @@
1
- {"version":3,"file":"safe.js","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAOrC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,MAA+B,EAC/B,UAEI,EAAE;IAEN,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;QAChC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;YACjB,IAAI;gBACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;aACxB;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CACT,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,IAAI,0BAA0B,EAC5F,KAAK,CACN,CAAC;gBACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,MAAM,CAAC;KACf;AACH,CAAC;AAID;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAAkD;IAElD,IAAI,aAAa,EAAE;QACjB,OAAO,CAAC,GAAG,IAA+B,EAA6B,EAAE;YACvE,IAAI;gBACF,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;aAC/B;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;gBAChE,OAAO,CAAC,CAAC;aACV;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,aAAa,CAAC;KACtB;AACH,CAAC","sourcesContent":["import { debug } from '@sentry/core';\nimport type { ReactNativeOptions } from '../options';\n\ntype DangerTypesWithoutCallSignature =\n // eslint-disable-next-line @typescript-eslint/ban-types\n Object | null | undefined;\n\n/**\n * Returns callback factory wrapped with try/catch\n * or the original passed value is it's not a function.\n *\n * If the factory fails original data are returned as it.\n * They might be partially modified by the failed function.\n */\nexport function safeFactory<A extends [R, ...unknown[]], R, T extends DangerTypesWithoutCallSignature>(\n danger: ((...args: A) => R) | T,\n options: {\n loggerMessage?: string;\n } = {},\n): ((...args: A) => R) | T {\n if (typeof danger === 'function') {\n return (...args) => {\n try {\n return danger(...args);\n } catch (error) {\n debug.error(\n options.loggerMessage ? options.loggerMessage : `The ${danger.name} callback threw an error`,\n error,\n );\n return args[0];\n }\n };\n } else {\n return danger;\n }\n}\n\ntype TracesSampler = Required<ReactNativeOptions>['tracesSampler'];\n\n/**\n * Returns sage tracesSampler that returns 0 if the original failed.\n */\nexport function safeTracesSampler(\n tracesSampler: ReactNativeOptions['tracesSampler'],\n): ReactNativeOptions['tracesSampler'] {\n if (tracesSampler) {\n return (...args: Parameters<TracesSampler>): ReturnType<TracesSampler> => {\n try {\n return tracesSampler(...args);\n } catch (error) {\n debug.error('The tracesSampler callback threw an error', error);\n return 0;\n }\n };\n } else {\n return tracesSampler;\n }\n}\n"]}
1
+ {"version":3,"file":"safe.js","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAKrC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,MAA+B,EAC/B,UAEI,EAAE;IAEN,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;QAChC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;YACjB,IAAI;gBACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;aACxB;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CACT,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,IAAI,0BAA0B,EAC5F,KAAK,CACN,CAAC;gBACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,MAAM,CAAC;KACf;AACH,CAAC;AAID;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAAkD;IAElD,IAAI,aAAa,EAAE;QACjB,OAAO,CAAC,GAAG,IAA+B,EAA6B,EAAE;YACvE,IAAI;gBACF,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;aAC/B;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;gBAChE,OAAO,CAAC,CAAC;aACV;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,aAAa,CAAC;KACtB;AACH,CAAC","sourcesContent":["import { debug } from '@sentry/core';\nimport type { ReactNativeOptions } from '../options';\n\ntype DangerTypesWithoutCallSignature = object | null | undefined;\n\n/**\n * Returns callback factory wrapped with try/catch\n * or the original passed value is it's not a function.\n *\n * If the factory fails original data are returned as it.\n * They might be partially modified by the failed function.\n */\nexport function safeFactory<A extends [R, ...unknown[]], R, T extends DangerTypesWithoutCallSignature>(\n danger: ((...args: A) => R) | T,\n options: {\n loggerMessage?: string;\n } = {},\n): ((...args: A) => R) | T {\n if (typeof danger === 'function') {\n return (...args) => {\n try {\n return danger(...args);\n } catch (error) {\n debug.error(\n options.loggerMessage ? options.loggerMessage : `The ${danger.name} callback threw an error`,\n error,\n );\n return args[0];\n }\n };\n } else {\n return danger;\n }\n}\n\ntype TracesSampler = Required<ReactNativeOptions>['tracesSampler'];\n\n/**\n * Returns sage tracesSampler that returns 0 if the original failed.\n */\nexport function safeTracesSampler(\n tracesSampler: ReactNativeOptions['tracesSampler'],\n): ReactNativeOptions['tracesSampler'] {\n if (tracesSampler) {\n return (...args: Parameters<TracesSampler>): ReturnType<TracesSampler> => {\n try {\n return tracesSampler(...args);\n } catch (error) {\n debug.error('The tracesSampler callback threw an error', error);\n return 0;\n }\n };\n } else {\n return tracesSampler;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  export declare const SDK_PACKAGE_NAME = "npm:@sentry/react-native";
2
2
  export declare const SDK_NAME = "sentry.javascript.react-native";
3
- export declare const SDK_VERSION = "8.4.0";
3
+ export declare const SDK_VERSION = "8.5.0";
4
4
  //# sourceMappingURL=version.d.ts.map
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = exports.SDK_NAME = exports.SDK_PACKAGE_NAME = void 0;
4
4
  exports.SDK_PACKAGE_NAME = 'npm:@sentry/react-native';
5
5
  exports.SDK_NAME = 'sentry.javascript.react-native';
6
- exports.SDK_VERSION = '8.4.0';
6
+ exports.SDK_VERSION = '8.5.0';
7
7
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,0BAA0B,CAAC;AAC9C,QAAA,QAAQ,GAAG,gCAAgC,CAAC;AAC5C,QAAA,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '8.4.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,0BAA0B,CAAC;AAC9C,QAAA,QAAQ,GAAG,gCAAgC,CAAC;AAC5C,QAAA,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '8.5.0';\n"]}
package/ios/RNSentry.mm CHANGED
@@ -60,6 +60,7 @@ static bool hasFetchedAppStart;
60
60
 
61
61
  @implementation RNSentry {
62
62
  bool hasListeners;
63
+ bool _shakeDetectionEnabled;
63
64
  RNSentryTimeToDisplay *_timeToDisplay;
64
65
  NSArray<NSString *> *_ignoreErrorPatternsStr;
65
66
  NSArray<NSRegularExpression *> *_ignoreErrorPatternsRegex;
@@ -295,9 +296,54 @@ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking : (
295
296
  [[RNSentryNativeLogsForwarder shared] stopForwarding];
296
297
  }
297
298
 
299
+ - (void)handleShakeDetected
300
+ {
301
+ if (_shakeDetectionEnabled) {
302
+ [self sendEventWithName:RNSentryOnShakeEvent body:@{}];
303
+ }
304
+ }
305
+
306
+ // SentryShakeDetector is a Swift class; its notification name and methods are accessed
307
+ // via the raw string / NSClassFromString to avoid requiring @import Sentry in this .mm file.
308
+ static NSNotificationName const RNSentryShakeNotification = @"SentryShakeDetected";
309
+
310
+ RCT_EXPORT_METHOD(enableShakeDetection)
311
+ {
312
+ [[NSNotificationCenter defaultCenter] removeObserver:self
313
+ name:RNSentryShakeNotification
314
+ object:nil];
315
+ [[NSNotificationCenter defaultCenter] addObserver:self
316
+ selector:@selector(handleShakeDetected)
317
+ name:RNSentryShakeNotification
318
+ object:nil];
319
+ Class shakeDetector = NSClassFromString(@"SentryShakeDetector");
320
+ if (shakeDetector) {
321
+ #pragma clang diagnostic push
322
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
323
+ [shakeDetector performSelector:@selector(enable)];
324
+ #pragma clang diagnostic pop
325
+ }
326
+ _shakeDetectionEnabled = YES;
327
+ }
328
+
329
+ RCT_EXPORT_METHOD(disableShakeDetection)
330
+ {
331
+ _shakeDetectionEnabled = NO;
332
+ Class shakeDetector = NSClassFromString(@"SentryShakeDetector");
333
+ if (shakeDetector) {
334
+ #pragma clang diagnostic push
335
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
336
+ [shakeDetector performSelector:@selector(disable)];
337
+ #pragma clang diagnostic pop
338
+ }
339
+ [[NSNotificationCenter defaultCenter] removeObserver:self
340
+ name:RNSentryShakeNotification
341
+ object:nil];
342
+ }
343
+
298
344
  - (NSArray<NSString *> *)supportedEvents
299
345
  {
300
- return @[ RNSentryNewFrameEvent, RNSentryNativeLogEvent ];
346
+ return @[ RNSentryNewFrameEvent, RNSentryNativeLogEvent, RNSentryOnShakeEvent ];
301
347
  }
302
348
 
303
349
  RCT_EXPORT_METHOD(
@@ -1,4 +1,5 @@
1
1
  #import <Foundation/Foundation.h>
2
2
 
3
3
  extern NSString *const RNSentryNewFrameEvent;
4
+ extern NSString *const RNSentryOnShakeEvent;
4
5
  extern NSString *const RNSentryNativeLogEvent;
@@ -1,4 +1,5 @@
1
1
  #import "RNSentryEvents.h"
2
2
 
3
3
  NSString *const RNSentryNewFrameEvent = @"rn_sentry_new_frame";
4
+ NSString *const RNSentryOnShakeEvent = @"rn_sentry_on_shake";
4
5
  NSString *const RNSentryNativeLogEvent = @"SentryNativeLog";
@@ -3,4 +3,4 @@
3
3
  NSString *const NATIVE_SDK_NAME = @"sentry.cocoa.react-native";
4
4
  NSString *const REACT_NATIVE_SDK_NAME = @"sentry.javascript.react-native";
5
5
  NSString *const REACT_NATIVE_SDK_PACKAGE_NAME = @"npm:@sentry/react-native";
6
- NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.4.0";
6
+ NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.5.0";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@sentry/react-native",
3
3
  "homepage": "https://github.com/getsentry/sentry-react-native",
4
4
  "repository": "https://github.com/getsentry/sentry-react-native",
5
- "version": "8.4.0",
5
+ "version": "8.5.0",
6
6
  "description": "Official Sentry SDK for react-native",
7
7
  "typings": "dist/js/index.d.ts",
8
8
  "types": "dist/js/index.d.ts",
@@ -38,10 +38,10 @@
38
38
  "test:watch": "npx jest --watch",
39
39
  "yalc:add:sentry-javascript": "yalc add @sentry/browser @sentry/core @sentry/react @sentry/types",
40
40
  "fix": "npx run-s fix:eslint fix:prettier",
41
- "fix:eslint": "eslint --config .eslintrc.js --fix .",
41
+ "fix:eslint": "ESLINT_USE_FLAT_CONFIG=false eslint --config .eslintrc.js --fix .",
42
42
  "fix:prettier": "prettier --config ../../.prettierrc.json --ignore-path ../../.prettierignore --write \"{src,test,scripts,plugin/src}/**/**.ts\"",
43
43
  "lint": "npx run-s lint:eslint lint:prettier",
44
- "lint:eslint": "eslint --config .eslintrc.js .",
44
+ "lint:eslint": "ESLINT_USE_FLAT_CONFIG=false eslint --config .eslintrc.js .",
45
45
  "lint:prettier": "prettier --config ../../.prettierrc.json --ignore-path ../../.prettierignore --check \"{src,test,scripts,plugin/src}/**/**.ts\""
46
46
  },
47
47
  "bin": {
@@ -72,20 +72,20 @@
72
72
  },
73
73
  "dependencies": {
74
74
  "@sentry/babel-plugin-component-annotate": "5.1.1",
75
- "@sentry/browser": "10.43.0",
75
+ "@sentry/browser": "10.44.0",
76
76
  "@sentry/cli": "3.3.3",
77
- "@sentry/core": "10.43.0",
78
- "@sentry/react": "10.43.0",
79
- "@sentry/types": "10.43.0"
77
+ "@sentry/core": "10.44.0",
78
+ "@sentry/react": "10.44.0",
79
+ "@sentry/types": "10.44.0"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@babel/core": "^7.26.7",
83
83
  "@expo/metro-config": "~0.20.0",
84
84
  "@mswjs/interceptors": "^0.25.15",
85
85
  "@react-native/babel-preset": "0.80.0",
86
- "@sentry-internal/eslint-config-sdk": "10.43.0",
87
- "@sentry-internal/eslint-plugin-sdk": "10.43.0",
88
- "@sentry-internal/typescript": "10.43.0",
86
+ "@sentry-internal/eslint-config-sdk": "10.44.0",
87
+ "@sentry-internal/eslint-plugin-sdk": "10.44.0",
88
+ "@sentry-internal/typescript": "10.44.0",
89
89
  "@sentry/wizard": "6.12.0",
90
90
  "@testing-library/react-native": "^13.2.2",
91
91
  "@types/jest": "^29.5.13",
@@ -95,13 +95,13 @@
95
95
  "@types/uglify-js": "^3.17.2",
96
96
  "@types/uuid": "^9.0.4",
97
97
  "@types/xmlhttprequest": "^1.8.2",
98
- "@typescript-eslint/eslint-plugin": "^5.48.0",
99
- "@typescript-eslint/parser": "^5.48.0",
98
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
99
+ "@typescript-eslint/parser": "^8.0.0",
100
100
  "babel-jest": "^29.6.3",
101
101
  "babel-plugin-module-resolver": "^5.0.0",
102
102
  "babel-preset-fbjs": "^3.4.0",
103
103
  "downlevel-dts": "^0.11.0",
104
- "eslint": "^8.57.0",
104
+ "eslint": "^9.0.0",
105
105
  "eslint-plugin-react": "^7.37.0",
106
106
  "eslint-plugin-react-native": "^3.8.1",
107
107
  "expo": "^53.0.0",
@@ -31,7 +31,7 @@ const withSentryPlugin = (config, props) => {
31
31
  (0, logger_1.warnOnce)(`There was a problem with configuring your native Android project: ${e}`);
32
32
  }
33
33
  // if `enableAndroidGradlePlugin` is provided configure the Sentry Android Gradle Plugin
34
- if (props?.experimental_android && props?.experimental_android?.enableAndroidGradlePlugin) {
34
+ if (props?.experimental_android?.enableAndroidGradlePlugin) {
35
35
  try {
36
36
  cfg = (0, withSentryAndroidGradlePlugin_1.withSentryAndroidGradlePlugin)(cfg, props.experimental_android);
37
37
  }
@@ -9,7 +9,7 @@ export interface SentryAndroidGradlePluginOptions {
9
9
  includeNativeSources?: boolean;
10
10
  includeSourceContext?: boolean;
11
11
  }
12
- export declare const sentryAndroidGradlePluginVersion = "6.1.0";
12
+ export declare const sentryAndroidGradlePluginVersion = "6.2.0";
13
13
  /**
14
14
  * Adds the Sentry Android Gradle Plugin to the project.
15
15
  * https://docs.sentry.io/platforms/react-native/manual-setup/manual-setup/#enable-sentry-agp
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withSentryAndroidGradlePlugin = exports.sentryAndroidGradlePluginVersion = void 0;
4
4
  const config_plugins_1 = require("@expo/config-plugins");
5
5
  const logger_1 = require("./logger");
6
- exports.sentryAndroidGradlePluginVersion = '6.1.0';
6
+ exports.sentryAndroidGradlePluginVersion = '6.2.0';
7
7
  /**
8
8
  * Adds the Sentry Android Gradle Plugin to the project.
9
9
  * https://docs.sentry.io/platforms/react-native/manual-setup/manual-setup/#enable-sentry-agp
@@ -101,6 +101,20 @@ if [ "$SENTRY_COPY_OPTIONS_FILE" = true ]; then
101
101
  echo "[Sentry] $SENTRY_OPTIONS_FILE_PATH not found. $SENTRY_OPTIONS_FILE_ERROR_MESSAGE_POSTFIX" 1>&2
102
102
  else
103
103
  cp "$SENTRY_OPTIONS_FILE_PATH" "$SENTRY_OPTIONS_FILE_DESTINATION_PATH"
104
+
105
+ if [ -n "$SENTRY_ENVIRONMENT" ]; then
106
+ if "$LOCAL_NODE_BINARY" -e "
107
+ var fs = require('fs');
108
+ var destPath = process.argv[1];
109
+ var opts = JSON.parse(fs.readFileSync(destPath, 'utf8'));
110
+ opts.environment = process.env.SENTRY_ENVIRONMENT;
111
+ fs.writeFileSync(destPath, JSON.stringify(opts));
112
+ " -- "$SENTRY_OPTIONS_FILE_DESTINATION_PATH" 2>/dev/null; then
113
+ echo "[Sentry] Overriding 'environment' from SENTRY_ENVIRONMENT environment variable"
114
+ else
115
+ echo "[Sentry] Failed to override environment, copied file as-is." 1>&2
116
+ fi
117
+ fi
104
118
  echo "[Sentry] Copied $SENTRY_OPTIONS_FILE_PATH to $SENTRY_OPTIONS_FILE_DESTINATION_PATH"
105
119
  fi
106
120
  fi
package/sentry.gradle CHANGED
@@ -44,6 +44,19 @@ tasks.register("copySentryJsonConfiguration") {
44
44
  into androidAssetsDir
45
45
  rename { String fileName -> configFile }
46
46
  }
47
+
48
+ def sentryEnv = System.getenv('SENTRY_ENVIRONMENT')
49
+ if (sentryEnv) {
50
+ try {
51
+ def destFile = new File(androidAssetsDir, configFile)
52
+ def content = new groovy.json.JsonSlurper().parseText(destFile.text)
53
+ content.environment = sentryEnv
54
+ destFile.text = groovy.json.JsonOutput.toJson(content)
55
+ logger.lifecycle("Overriding 'environment' from SENTRY_ENVIRONMENT environment variable")
56
+ } catch (Exception e) {
57
+ logger.warn("Failed to override environment in ${configFile}: ${e.message}. Copied file as-is.")
58
+ }
59
+ }
47
60
  logger.lifecycle("Copied ${configFile} to Android assets")
48
61
  } else {
49
62
  logger.warn("${configFile} not found in app root (${appRoot})")
@@ -54,6 +54,8 @@ export interface Spec extends TurboModule {
54
54
  popTimeToDisplayFor(key: string): Promise<number | undefined | null>;
55
55
  setActiveSpanId(spanId: string): boolean;
56
56
  encodeToBase64(data: number[]): Promise<string | undefined | null>;
57
+ enableShakeDetection(): void;
58
+ disableShakeDetection(): void;
57
59
  }
58
60
 
59
61
  export type NativeStackFrame = {
@@ -50,6 +50,8 @@ export interface Spec extends TurboModule {
50
50
  popTimeToDisplayFor(key: string): Promise<number | undefined | null>;
51
51
  setActiveSpanId(spanId: string): boolean;
52
52
  encodeToBase64(data: number[]): Promise<string | undefined | null>;
53
+ enableShakeDetection(): void;
54
+ disableShakeDetection(): void;
53
55
  }
54
56
  export type NativeStackFrame = {
55
57
  platform: string;
@@ -49,5 +49,7 @@ declare const resetFeedbackButtonManager: () => void;
49
49
  declare const showScreenshotButton: () => void;
50
50
  declare const hideScreenshotButton: () => void;
51
51
  declare const resetScreenshotButtonManager: () => void;
52
- export { showFeedbackButton, hideFeedbackButton, showFeedbackWidget, showScreenshotButton, hideScreenshotButton, resetFeedbackButtonManager, resetFeedbackWidgetManager, resetScreenshotButtonManager };
52
+ declare const enableFeedbackOnShake: () => void;
53
+ declare const disableFeedbackOnShake: () => void;
54
+ export { showFeedbackButton, hideFeedbackButton, showFeedbackWidget, enableFeedbackOnShake, disableFeedbackOnShake, showScreenshotButton, hideScreenshotButton, resetFeedbackButtonManager, resetFeedbackWidgetManager, resetScreenshotButtonManager };
53
55
  //# sourceMappingURL=FeedbackWidgetManager.d.ts.map
@@ -21,14 +21,15 @@ export interface FeedbackWidgetProviderState {
21
21
  export declare class FeedbackWidgetProvider extends React.Component<FeedbackWidgetProviderProps> {
22
22
  state: FeedbackWidgetProviderState;
23
23
  private _themeListener;
24
+ private _startedShakeListener;
24
25
  private _panResponder;
25
26
  constructor(props: FeedbackWidgetProviderProps);
26
27
  /**
27
- * Add a listener to the theme change event.
28
+ * Add a listener to the theme change event and start shake detection if configured.
28
29
  */
29
30
  componentDidMount(): void;
30
31
  /**
31
- * Clean up the theme listener.
32
+ * Clean up the theme listener and stop shake detection.
32
33
  */
33
34
  componentWillUnmount(): void;
34
35
  /**
@@ -0,0 +1,27 @@
1
+ import type { NativeModule } from 'react-native';
2
+ import { NativeEventEmitter } from 'react-native';
3
+ export declare const OnShakeEventName = "rn_sentry_on_shake";
4
+ /**
5
+ * Creates a NativeEventEmitter for the given module.
6
+ * Can be overridden in tests via the `createEmitter` parameter.
7
+ */
8
+ type EmitterFactory = (nativeModule: NativeModule) => NativeEventEmitter;
9
+ /**
10
+ * Starts listening for device shake events and invokes the provided callback when a shake is detected.
11
+ *
12
+ * This starts native shake detection:
13
+ * - iOS: Uses UIKit's motion event detection (no permissions required)
14
+ * - Android: Uses the accelerometer sensor (no permissions required)
15
+ */
16
+ export declare function startShakeListener(onShake: () => void, createEmitter?: EmitterFactory): boolean;
17
+ /**
18
+ * Stops listening for device shake events.
19
+ */
20
+ export declare function stopShakeListener(): void;
21
+ /**
22
+ * Returns whether the shake listener is currently active.
23
+ * Exported for testing purposes.
24
+ */
25
+ export declare function isShakeListenerActive(): boolean;
26
+ export {};
27
+ //# sourceMappingURL=ShakeToReportBug.d.ts.map
@@ -9,6 +9,7 @@ type FeedbackIntegration = Integration & {
9
9
  colorScheme?: 'system' | 'light' | 'dark';
10
10
  themeLight: Partial<FeedbackWidgetTheme>;
11
11
  themeDark: Partial<FeedbackWidgetTheme>;
12
+ enableShakeToReport: boolean;
12
13
  };
13
14
  export declare const feedbackIntegration: (initOptions?: Partial<FeedbackWidgetProps> & {
14
15
  buttonOptions?: FeedbackButtonProps;
@@ -16,6 +17,15 @@ export declare const feedbackIntegration: (initOptions?: Partial<FeedbackWidgetP
16
17
  colorScheme?: 'system' | 'light' | 'dark';
17
18
  themeLight?: Partial<FeedbackWidgetTheme>;
18
19
  themeDark?: Partial<FeedbackWidgetTheme>;
20
+ /**
21
+ * Enable showing the feedback widget when the user shakes the device.
22
+ *
23
+ * - iOS: Uses UIKit's motion event detection (no permissions required)
24
+ * - Android: Uses the accelerometer sensor (no permissions required)
25
+ *
26
+ * @default false
27
+ */
28
+ enableShakeToReport?: boolean;
19
29
  }) => FeedbackIntegration;
20
30
  export declare const getFeedbackOptions: () => Partial<FeedbackWidgetProps>;
21
31
  export declare const getFeedbackButtonOptions: () => Partial<FeedbackButtonProps>;
@@ -23,5 +33,6 @@ export declare const getScreenshotButtonOptions: () => Partial<ScreenshotButtonP
23
33
  export declare const getColorScheme: () => 'system' | 'light' | 'dark';
24
34
  export declare const getFeedbackLightTheme: () => Partial<FeedbackWidgetTheme>;
25
35
  export declare const getFeedbackDarkTheme: () => Partial<FeedbackWidgetTheme>;
36
+ export declare const isShakeToReportEnabled: () => boolean;
26
37
  export {};
27
38
  //# sourceMappingURL=integration.d.ts.map
@@ -14,6 +14,6 @@ export type { TimeToDisplayProps, ExpoRouter, ExpoImage, ExpoAsset } from './tra
14
14
  export { Mask, Unmask } from './replay/CustomMask';
15
15
  export { FeedbackButton } from './feedback/FeedbackButton';
16
16
  export { FeedbackWidget } from './feedback/FeedbackWidget';
17
- export { showFeedbackWidget, showFeedbackButton, hideFeedbackButton } from './feedback/FeedbackWidgetManager';
17
+ export { showFeedbackWidget, showFeedbackButton, hideFeedbackButton, enableFeedbackOnShake, disableFeedbackOnShake, } from './feedback/FeedbackWidgetManager';
18
18
  export { getDataFromUri } from './wrapper';
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -12,6 +12,7 @@ export { screenshotIntegration } from './screenshot';
12
12
  export { viewHierarchyIntegration } from './viewhierarchy';
13
13
  export { expoContextIntegration } from './expocontext';
14
14
  export { expoConstantsIntegration } from './expoconstants';
15
+ export { expoUpdatesListenerIntegration } from './expoupdateslistener';
15
16
  export { spotlightIntegration } from './spotlight';
16
17
  export { mobileReplayIntegration } from '../replay/mobilereplay';
17
18
  export { feedbackIntegration } from '../feedback/integration';
@@ -0,0 +1,38 @@
1
+ import type { Integration } from '@sentry/core';
2
+ /**
3
+ * Describes the state machine context from `expo-updates`.
4
+ * We define our own minimal type to avoid a hard dependency on `expo-updates`.
5
+ */
6
+ interface UpdatesNativeStateMachineContext {
7
+ isChecking: boolean;
8
+ isDownloading: boolean;
9
+ isUpdateAvailable: boolean;
10
+ isUpdatePending: boolean;
11
+ isRestarting: boolean;
12
+ latestManifest?: {
13
+ id?: string;
14
+ };
15
+ downloadedManifest?: {
16
+ id?: string;
17
+ };
18
+ rollback?: {
19
+ commitTime: string;
20
+ };
21
+ checkError?: Error;
22
+ downloadError?: Error;
23
+ }
24
+ /**
25
+ * Listens to Expo Updates native state machine changes and records
26
+ * breadcrumbs for meaningful transitions such as checking for updates,
27
+ * downloading updates, errors, rollbacks, and restarts.
28
+ */
29
+ export declare const expoUpdatesListenerIntegration: () => Integration;
30
+ /**
31
+ * Compares previous and current state machine contexts and emits
32
+ * breadcrumbs for meaningful transitions (falsy→truthy).
33
+ *
34
+ * @internal Exposed for testing purposes
35
+ */
36
+ export declare function handleStateChange(previous: Partial<UpdatesNativeStateMachineContext>, current: UpdatesNativeStateMachineContext): void;
37
+ export {};
38
+ //# sourceMappingURL=expoupdateslistener.d.ts.map
@@ -59,6 +59,18 @@ export interface BaseReactNativeOptions {
59
59
  * @platform android
60
60
  */
61
61
  enableNdkScopeSync?: boolean;
62
+ /**
63
+ * When enabled, ANR events whose stacktraces contain only system frames
64
+ * (e.g. `java.lang`, `android.os`) are assigned a static fingerprint and
65
+ * grouped into a single issue instead of creating many separate issues.
66
+ *
67
+ * Enabled by default in the Android SDK since v8.35.0.
68
+ * Set to `false` to restore per-stacktrace ANR grouping.
69
+ *
70
+ * @default true
71
+ * @platform android
72
+ */
73
+ enableAnrFingerprinting?: boolean;
62
74
  /**
63
75
  * When enabled, all the threads are automatically attached to all logged events on Android
64
76
  *
@@ -37,6 +37,14 @@ export declare function _setRootComponentCreationTimestampMs(timestampMs: number
37
37
  * @private
38
38
  */
39
39
  export declare const _setAppStartEndData: (data: AppStartEndData) => void;
40
+ /**
41
+ * Updates only the endFrames on existing appStartEndData.
42
+ * Used after the async fetchNativeFrames completes to attach frame data
43
+ * without triggering the overwrite warning from _setAppStartEndData.
44
+ *
45
+ * @private
46
+ */
47
+ export declare const _updateAppStartEndFrames: (endFrames: NativeFramesResponse | null) => void;
40
48
  /**
41
49
  * For testing purposes only.
42
50
  *
@@ -1,5 +1,5 @@
1
1
  import type { ReactNativeOptions } from '../options';
2
- type DangerTypesWithoutCallSignature = Object | null | undefined;
2
+ type DangerTypesWithoutCallSignature = object | null | undefined;
3
3
  /**
4
4
  * Returns callback factory wrapped with try/catch
5
5
  * or the original passed value is it's not a function.
@@ -1,4 +1,4 @@
1
1
  export declare const SDK_PACKAGE_NAME = "npm:@sentry/react-native";
2
2
  export declare const SDK_NAME = "sentry.javascript.react-native";
3
- export declare const SDK_VERSION = "8.4.0";
3
+ export declare const SDK_VERSION = "8.5.0";
4
4
  //# sourceMappingURL=version.d.ts.map