@sentry/react-native 8.2.0 → 8.4.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/README.md +0 -1
- package/RNSentry.podspec +1 -1
- package/android/AGENTS.md +51 -0
- package/android/libs/replay-stubs.jar +0 -0
- package/android/src/main/java/io/sentry/react/RNSentryLogger.java +96 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +13 -3
- package/android/src/main/java/io/sentry/react/RNSentryStart.java +21 -9
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/NativeLogListener.d.ts +16 -0
- package/dist/js/NativeLogListener.d.ts.map +1 -0
- package/dist/js/NativeLogListener.js +72 -0
- package/dist/js/NativeLogListener.js.map +1 -0
- package/dist/js/client.d.ts +1 -0
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +14 -3
- package/dist/js/client.js.map +1 -1
- package/dist/js/index.d.ts +4 -4
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +2 -2
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +2 -1
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/expoconstants.d.ts +24 -0
- package/dist/js/integrations/expoconstants.d.ts.map +1 -0
- package/dist/js/integrations/expoconstants.js +77 -0
- package/dist/js/integrations/expoconstants.js.map +1 -0
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +35 -1
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/exports.d.ts +1 -0
- package/dist/js/integrations/exports.d.ts.map +1 -1
- package/dist/js/integrations/exports.js +1 -0
- package/dist/js/integrations/exports.js.map +1 -1
- package/dist/js/options.d.ts +26 -0
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +3 -2
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/easBuildHooks.d.ts +48 -0
- package/dist/js/tools/easBuildHooks.d.ts.map +1 -0
- package/dist/js/tools/easBuildHooks.js +228 -0
- package/dist/js/tools/easBuildHooks.js.map +1 -0
- package/dist/js/tools/metroconfig.d.ts +4 -0
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js +46 -1
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tracing/expoAsset.d.ts +42 -0
- package/dist/js/tracing/expoAsset.d.ts.map +1 -0
- package/dist/js/tracing/expoAsset.js +60 -0
- package/dist/js/tracing/expoAsset.js.map +1 -0
- package/dist/js/tracing/expoImage.d.ts +61 -0
- package/dist/js/tracing/expoImage.d.ts.map +1 -0
- package/dist/js/tracing/expoImage.js +101 -0
- package/dist/js/tracing/expoImage.js.map +1 -0
- package/dist/js/tracing/index.d.ts +4 -0
- package/dist/js/tracing/index.d.ts.map +1 -1
- package/dist/js/tracing/index.js +2 -0
- package/dist/js/tracing/index.js.map +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
- package/dist/js/tracing/integrations/appStart.js +4 -1
- package/dist/js/tracing/integrations/appStart.js.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
- package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.js +45 -6
- package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
- package/dist/js/tracing/origin.d.ts +2 -0
- package/dist/js/tracing/origin.d.ts.map +1 -1
- package/dist/js/tracing/origin.js +2 -0
- package/dist/js/tracing/origin.js.map +1 -1
- package/dist/js/tracing/reactnavigation.d.ts +15 -0
- package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
- package/dist/js/tracing/reactnavigation.js +50 -17
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/tracing/span.d.ts +6 -6
- package/dist/js/tracing/span.d.ts.map +1 -1
- package/dist/js/tracing/span.js +3 -3
- package/dist/js/tracing/span.js.map +1 -1
- package/dist/js/tracing/utils.d.ts +27 -1
- package/dist/js/tracing/utils.d.ts.map +1 -1
- package/dist/js/tracing/utils.js +66 -1
- package/dist/js/tracing/utils.js.map +1 -1
- package/dist/js/utils/expoglobalobject.d.ts +47 -7
- package/dist/js/utils/expoglobalobject.d.ts.map +1 -1
- package/dist/js/utils/expoglobalobject.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +6 -3
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +1 -1
- package/dist/js/wrapper.js.map +1 -1
- package/ios/AGENTS.md +60 -0
- package/ios/RNSentry.mm +4 -1
- package/ios/RNSentryEvents.h +1 -0
- package/ios/RNSentryEvents.m +1 -0
- package/ios/RNSentryNativeLogsForwarder.h +20 -0
- package/ios/RNSentryNativeLogsForwarder.m +145 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +14 -11
- package/plugin/build/utils.d.ts +1 -0
- package/plugin/build/utils.js +19 -1
- package/plugin/build/withSentry.d.ts +1 -0
- package/plugin/build/withSentry.js +28 -0
- package/scripts/eas-build-hook.js +234 -0
- package/scripts/sentry-xcode.sh +7 -0
- package/ts3.8/dist/js/NativeLogListener.d.ts +16 -0
- package/ts3.8/dist/js/client.d.ts +1 -0
- package/ts3.8/dist/js/index.d.ts +4 -4
- package/ts3.8/dist/js/integrations/expoconstants.d.ts +24 -0
- package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
- package/ts3.8/dist/js/options.d.ts +26 -0
- package/ts3.8/dist/js/tracing/expoAsset.d.ts +42 -0
- package/ts3.8/dist/js/tracing/expoImage.d.ts +61 -0
- package/ts3.8/dist/js/tracing/index.d.ts +4 -0
- package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
- package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
- package/ts3.8/dist/js/tracing/reactnavigation.d.ts +15 -0
- package/ts3.8/dist/js/tracing/span.d.ts +6 -6
- package/ts3.8/dist/js/tracing/utils.d.ts +27 -1
- package/ts3.8/dist/js/utils/expoglobalobject.d.ts +47 -7
- package/ts3.8/dist/js/version.d.ts +1 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#import "RNSentryNativeLogsForwarder.h"
|
|
2
|
+
#import "RNSentryEvents.h"
|
|
3
|
+
|
|
4
|
+
@import Sentry;
|
|
5
|
+
|
|
6
|
+
@interface RNSentryNativeLogsForwarder ()
|
|
7
|
+
|
|
8
|
+
@property (nonatomic, weak) RCTEventEmitter *eventEmitter;
|
|
9
|
+
|
|
10
|
+
@end
|
|
11
|
+
|
|
12
|
+
@implementation RNSentryNativeLogsForwarder
|
|
13
|
+
|
|
14
|
+
+ (instancetype)shared
|
|
15
|
+
{
|
|
16
|
+
static RNSentryNativeLogsForwarder *instance = nil;
|
|
17
|
+
static dispatch_once_t onceToken;
|
|
18
|
+
dispatch_once(&onceToken, ^{ instance = [[RNSentryNativeLogsForwarder alloc] init]; });
|
|
19
|
+
return instance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (void)configureWithEventEmitter:(RCTEventEmitter *)emitter
|
|
23
|
+
{
|
|
24
|
+
self.eventEmitter = emitter;
|
|
25
|
+
|
|
26
|
+
__weak RNSentryNativeLogsForwarder *weakSelf = self;
|
|
27
|
+
|
|
28
|
+
// Set up the Sentry SDK log output to forward logs to JS
|
|
29
|
+
[SentrySDKLog setOutput:^(NSString *_Nonnull message) {
|
|
30
|
+
// Always print to console (default behavior)
|
|
31
|
+
NSLog(@"%@", message);
|
|
32
|
+
|
|
33
|
+
// Forward to JS if we have an emitter
|
|
34
|
+
RNSentryNativeLogsForwarder *strongSelf = weakSelf;
|
|
35
|
+
if (strongSelf) {
|
|
36
|
+
[strongSelf forwardLogMessage:message];
|
|
37
|
+
}
|
|
38
|
+
}];
|
|
39
|
+
|
|
40
|
+
// Send a log to notify user the forwarding works
|
|
41
|
+
[self forwardLogMessage:
|
|
42
|
+
@"[Sentry] [info] [0] [RNSentryNativeLogsForwarder] Native log forwarding "
|
|
43
|
+
@"configured successfully"];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (void)stopForwarding
|
|
47
|
+
{
|
|
48
|
+
self.eventEmitter = nil;
|
|
49
|
+
|
|
50
|
+
// TODO: Ideally we should save the previous output block in configureWithEventEmitter:
|
|
51
|
+
// and restore it here instead of hardcoding NSLog.
|
|
52
|
+
// Reset to default print behavior
|
|
53
|
+
[SentrySDKLog setOutput:^(NSString *_Nonnull message) { NSLog(@"%@", message); }];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (void)forwardLogMessage:(NSString *)message
|
|
57
|
+
{
|
|
58
|
+
RCTEventEmitter *emitter = self.eventEmitter;
|
|
59
|
+
if (emitter == nil) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Only forward messages that look like Sentry SDK logs
|
|
64
|
+
if (![message hasPrefix:@"[Sentry]"]) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Parse the log message to extract level and component
|
|
69
|
+
// Format: "[Sentry] [level] [timestamp] [Component:line] message"
|
|
70
|
+
// or: "[Sentry] [level] [timestamp] message"
|
|
71
|
+
NSString *level = [self extractLevelFromMessage:message];
|
|
72
|
+
NSString *component = [self extractComponentFromMessage:message];
|
|
73
|
+
NSString *cleanMessage = [self extractCleanMessageFromMessage:message];
|
|
74
|
+
|
|
75
|
+
NSDictionary *body = @{
|
|
76
|
+
@"level" : level,
|
|
77
|
+
@"component" : component,
|
|
78
|
+
@"message" : cleanMessage,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Dispatch async to avoid blocking the calling thread and potential deadlocks
|
|
82
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
83
|
+
RCTEventEmitter *currentEmitter = self.eventEmitter;
|
|
84
|
+
if (currentEmitter != nil) {
|
|
85
|
+
[currentEmitter sendEventWithName:RNSentryNativeLogEvent body:body];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
- (NSString *)extractLevelFromMessage:(NSString *)message
|
|
91
|
+
{
|
|
92
|
+
// Look for patterns like [debug], [info], [warning], [error], [fatal]
|
|
93
|
+
NSRegularExpression *regex =
|
|
94
|
+
[NSRegularExpression regularExpressionWithPattern:@"\\[(debug|info|warning|error|fatal)\\]"
|
|
95
|
+
options:NSRegularExpressionCaseInsensitive
|
|
96
|
+
error:nil];
|
|
97
|
+
|
|
98
|
+
NSTextCheckingResult *match = [regex firstMatchInString:message
|
|
99
|
+
options:0
|
|
100
|
+
range:NSMakeRange(0, message.length)];
|
|
101
|
+
|
|
102
|
+
if (match && match.numberOfRanges > 1) {
|
|
103
|
+
return [[message substringWithRange:[match rangeAtIndex:1]] lowercaseString];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return @"info";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
- (NSString *)extractComponentFromMessage:(NSString *)message
|
|
110
|
+
{
|
|
111
|
+
// Look for pattern like [ComponentName:123]
|
|
112
|
+
NSRegularExpression *regex =
|
|
113
|
+
[NSRegularExpression regularExpressionWithPattern:@"\\[([A-Za-z]+):\\d+\\]"
|
|
114
|
+
options:0
|
|
115
|
+
error:nil];
|
|
116
|
+
|
|
117
|
+
NSTextCheckingResult *match = [regex firstMatchInString:message
|
|
118
|
+
options:0
|
|
119
|
+
range:NSMakeRange(0, message.length)];
|
|
120
|
+
|
|
121
|
+
if (match && match.numberOfRanges > 1) {
|
|
122
|
+
return [message substringWithRange:[match rangeAtIndex:1]];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return @"Sentry";
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
- (NSString *)extractCleanMessageFromMessage:(NSString *)message
|
|
129
|
+
{
|
|
130
|
+
// Remove the prefix parts: [Sentry] [level] [timestamp] [Component:line]
|
|
131
|
+
// and return just the actual message content
|
|
132
|
+
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:
|
|
133
|
+
@"^\\[Sentry\\]\\s*\\[[^\\]]+\\]\\s*\\[[^\\]]+\\]\\s*(?:\\[[^\\]]+\\]\\s*)?"
|
|
134
|
+
options:0
|
|
135
|
+
error:nil];
|
|
136
|
+
|
|
137
|
+
NSString *cleanMessage = [regex stringByReplacingMatchesInString:message
|
|
138
|
+
options:0
|
|
139
|
+
range:NSMakeRange(0, message.length)
|
|
140
|
+
withTemplate:@""];
|
|
141
|
+
|
|
142
|
+
return [cleanMessage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@end
|
package/ios/RNSentryVersion.m
CHANGED
|
@@ -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.
|
|
6
|
+
NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.4.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.
|
|
5
|
+
"version": "8.4.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",
|
|
@@ -45,6 +45,9 @@
|
|
|
45
45
|
"lint:prettier": "prettier --config ../../.prettierrc.json --ignore-path ../../.prettierignore --check \"{src,test,scripts,plugin/src}/**/**.ts\""
|
|
46
46
|
},
|
|
47
47
|
"bin": {
|
|
48
|
+
"sentry-eas-build-on-complete": "scripts/eas-build-hook.js",
|
|
49
|
+
"sentry-eas-build-on-error": "scripts/eas-build-hook.js",
|
|
50
|
+
"sentry-eas-build-on-success": "scripts/eas-build-hook.js",
|
|
48
51
|
"sentry-expo-upload-sourcemaps": "scripts/expo-upload-sourcemaps.js"
|
|
49
52
|
},
|
|
50
53
|
"keywords": [
|
|
@@ -68,22 +71,22 @@
|
|
|
68
71
|
"react-native": ">=0.65.0"
|
|
69
72
|
},
|
|
70
73
|
"dependencies": {
|
|
71
|
-
"@sentry/babel-plugin-component-annotate": "
|
|
72
|
-
"@sentry/browser": "10.
|
|
73
|
-
"@sentry/cli": "3.
|
|
74
|
-
"@sentry/core": "10.
|
|
75
|
-
"@sentry/react": "10.
|
|
76
|
-
"@sentry/types": "10.
|
|
74
|
+
"@sentry/babel-plugin-component-annotate": "5.1.1",
|
|
75
|
+
"@sentry/browser": "10.43.0",
|
|
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
80
|
},
|
|
78
81
|
"devDependencies": {
|
|
79
82
|
"@babel/core": "^7.26.7",
|
|
80
83
|
"@expo/metro-config": "~0.20.0",
|
|
81
84
|
"@mswjs/interceptors": "^0.25.15",
|
|
82
85
|
"@react-native/babel-preset": "0.80.0",
|
|
83
|
-
"@sentry-internal/eslint-config-sdk": "10.
|
|
84
|
-
"@sentry-internal/eslint-plugin-sdk": "10.
|
|
85
|
-
"@sentry-internal/typescript": "10.
|
|
86
|
-
"@sentry/wizard": "6.
|
|
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",
|
|
89
|
+
"@sentry/wizard": "6.12.0",
|
|
87
90
|
"@testing-library/react-native": "^13.2.2",
|
|
88
91
|
"@types/jest": "^29.5.13",
|
|
89
92
|
"@types/node": "^20.9.3",
|
package/plugin/build/utils.d.ts
CHANGED
package/plugin/build/utils.js
CHANGED
|
@@ -23,9 +23,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.writeSentryPropertiesTo = void 0;
|
|
26
|
+
exports.writeSentryOptions = exports.writeSentryPropertiesTo = void 0;
|
|
27
27
|
const fs = __importStar(require("fs"));
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
|
+
const logger_1 = require("./logger");
|
|
29
30
|
function writeSentryPropertiesTo(filepath, sentryProperties) {
|
|
30
31
|
if (!fs.existsSync(filepath)) {
|
|
31
32
|
throw new Error(`Directory '${filepath}' does not exist.`);
|
|
@@ -33,3 +34,20 @@ function writeSentryPropertiesTo(filepath, sentryProperties) {
|
|
|
33
34
|
fs.writeFileSync(path.resolve(filepath, 'sentry.properties'), sentryProperties);
|
|
34
35
|
}
|
|
35
36
|
exports.writeSentryPropertiesTo = writeSentryPropertiesTo;
|
|
37
|
+
const SENTRY_OPTIONS_FILE_NAME = 'sentry.options.json';
|
|
38
|
+
function writeSentryOptions(projectRoot, pluginOptions) {
|
|
39
|
+
const optionsFilePath = path.resolve(projectRoot, SENTRY_OPTIONS_FILE_NAME);
|
|
40
|
+
let existingOptions = {};
|
|
41
|
+
if (fs.existsSync(optionsFilePath)) {
|
|
42
|
+
try {
|
|
43
|
+
existingOptions = JSON.parse(fs.readFileSync(optionsFilePath, 'utf8'));
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
(0, logger_1.warnOnce)(`Failed to parse ${SENTRY_OPTIONS_FILE_NAME}: ${e}. These options will not be set.`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const mergedOptions = { ...existingOptions, ...pluginOptions };
|
|
51
|
+
fs.writeFileSync(optionsFilePath, `${JSON.stringify(mergedOptions, null, 2)}\n`);
|
|
52
|
+
}
|
|
53
|
+
exports.writeSentryOptions = writeSentryOptions;
|
|
@@ -6,6 +6,7 @@ interface PluginProps {
|
|
|
6
6
|
authToken?: string;
|
|
7
7
|
url?: string;
|
|
8
8
|
useNativeInit?: boolean;
|
|
9
|
+
options?: Record<string, unknown>;
|
|
9
10
|
experimental_android?: SentryAndroidGradlePluginOptions;
|
|
10
11
|
}
|
|
11
12
|
export declare function getSentryProperties(props: PluginProps | void): string | null;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.withSentry = exports.getSentryProperties = void 0;
|
|
4
4
|
const config_plugins_1 = require("expo/config-plugins");
|
|
5
5
|
const logger_1 = require("./logger");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
6
7
|
const version_1 = require("./version");
|
|
7
8
|
const withSentryAndroid_1 = require("./withSentryAndroid");
|
|
8
9
|
const withSentryAndroidGradlePlugin_1 = require("./withSentryAndroidGradlePlugin");
|
|
@@ -14,6 +15,14 @@ const withSentryPlugin = (config, props) => {
|
|
|
14
15
|
delete props.authToken;
|
|
15
16
|
}
|
|
16
17
|
let cfg = config;
|
|
18
|
+
const pluginOptions = props?.options ? { ...props.options } : {};
|
|
19
|
+
const environment = process.env.SENTRY_ENVIRONMENT;
|
|
20
|
+
if (environment) {
|
|
21
|
+
pluginOptions.environment = environment;
|
|
22
|
+
}
|
|
23
|
+
if (Object.keys(pluginOptions).length > 0) {
|
|
24
|
+
cfg = withSentryOptionsFile(cfg, pluginOptions);
|
|
25
|
+
}
|
|
17
26
|
if (sentryProperties !== null) {
|
|
18
27
|
try {
|
|
19
28
|
cfg = (0, withSentryAndroid_1.withSentryAndroid)(cfg, { sentryProperties, useNativeInit: props?.useNativeInit });
|
|
@@ -61,6 +70,25 @@ ${project ? `defaults.project=${project}` : missingProjectMessage}
|
|
|
61
70
|
${authToken ? `${existingAuthTokenMessage}\nauth.token=${authToken}` : missingAuthTokenMessage}`;
|
|
62
71
|
}
|
|
63
72
|
exports.getSentryProperties = getSentryProperties;
|
|
73
|
+
function withSentryOptionsFile(config, pluginOptions) {
|
|
74
|
+
// withDangerousMod requires a platform key, but sentry.options.json is at the project root.
|
|
75
|
+
// We apply to both platforms so it works with `expo prebuild --platform ios` or `--platform android`.
|
|
76
|
+
let cfg = (0, config_plugins_1.withDangerousMod)(config, [
|
|
77
|
+
'android',
|
|
78
|
+
mod => {
|
|
79
|
+
(0, utils_1.writeSentryOptions)(mod.modRequest.projectRoot, pluginOptions);
|
|
80
|
+
return mod;
|
|
81
|
+
},
|
|
82
|
+
]);
|
|
83
|
+
cfg = (0, config_plugins_1.withDangerousMod)(cfg, [
|
|
84
|
+
'ios',
|
|
85
|
+
mod => {
|
|
86
|
+
(0, utils_1.writeSentryOptions)(mod.modRequest.projectRoot, pluginOptions);
|
|
87
|
+
return mod;
|
|
88
|
+
},
|
|
89
|
+
]);
|
|
90
|
+
return cfg;
|
|
91
|
+
}
|
|
64
92
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
65
93
|
const withSentry = (0, config_plugins_1.createRunOncePlugin)(withSentryPlugin, version_1.PLUGIN_NAME, version_1.PLUGIN_VERSION);
|
|
66
94
|
exports.withSentry = withSentry;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* EAS Build Hook
|
|
4
|
+
*
|
|
5
|
+
* Unified entry point for all EAS build hooks (on-complete, on-error, on-success).
|
|
6
|
+
* The hook name is determined from the bin command name in process.argv[1]
|
|
7
|
+
* (e.g. sentry-eas-build-on-error → on-error) or can be passed as a CLI argument.
|
|
8
|
+
*
|
|
9
|
+
* Required environment variables:
|
|
10
|
+
* - SENTRY_DSN: Your Sentry DSN
|
|
11
|
+
*
|
|
12
|
+
* Optional environment variables:
|
|
13
|
+
* - SENTRY_EAS_BUILD_CAPTURE_SUCCESS: Set to 'true' to also capture successful builds
|
|
14
|
+
* - SENTRY_EAS_BUILD_TAGS: JSON string of additional tags
|
|
15
|
+
* - SENTRY_EAS_BUILD_ERROR_MESSAGE: Custom error message for failed builds
|
|
16
|
+
* - SENTRY_EAS_BUILD_SUCCESS_MESSAGE: Custom success message for successful builds
|
|
17
|
+
*
|
|
18
|
+
* @see https://docs.expo.dev/build-reference/npm-hooks/
|
|
19
|
+
* @see https://docs.sentry.io/platforms/react-native/
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/* eslint-disable no-console */
|
|
23
|
+
|
|
24
|
+
const path = require('path');
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
|
|
27
|
+
// ─── Environment loading ─────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Merges parsed env vars into process.env without overwriting existing values.
|
|
31
|
+
* This preserves EAS secrets and other pre-set environment variables.
|
|
32
|
+
* @param {object} parsed - Parsed environment variables from dotenv
|
|
33
|
+
*/
|
|
34
|
+
function mergeEnvWithoutOverwrite(parsed) {
|
|
35
|
+
for (const key of Object.keys(parsed)) {
|
|
36
|
+
if (process.env[key] === undefined) {
|
|
37
|
+
process.env[key] = parsed[key];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Loads environment variables from various sources:
|
|
44
|
+
* - @expo/env (if available)
|
|
45
|
+
* - .env file (via dotenv, if available)
|
|
46
|
+
* - .env.sentry-build-plugin file
|
|
47
|
+
*
|
|
48
|
+
* NOTE: Existing environment variables (like EAS secrets) are NOT overwritten.
|
|
49
|
+
*/
|
|
50
|
+
function loadEnv() {
|
|
51
|
+
// Try @expo/env first
|
|
52
|
+
try {
|
|
53
|
+
require('@expo/env').load('.');
|
|
54
|
+
} catch (_e) {
|
|
55
|
+
// Fallback to dotenv if available
|
|
56
|
+
try {
|
|
57
|
+
const dotenvPath = path.join(process.cwd(), '.env');
|
|
58
|
+
if (fs.existsSync(dotenvPath)) {
|
|
59
|
+
const dotenvFile = fs.readFileSync(dotenvPath, 'utf-8');
|
|
60
|
+
const dotenv = require('dotenv');
|
|
61
|
+
mergeEnvWithoutOverwrite(dotenv.parse(dotenvFile));
|
|
62
|
+
}
|
|
63
|
+
} catch (_e2) {
|
|
64
|
+
// No dotenv available, continue with existing env vars
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Also load .env.sentry-build-plugin if it exists
|
|
69
|
+
try {
|
|
70
|
+
const sentryEnvPath = path.join(process.cwd(), '.env.sentry-build-plugin');
|
|
71
|
+
if (fs.existsSync(sentryEnvPath)) {
|
|
72
|
+
const dotenvFile = fs.readFileSync(sentryEnvPath, 'utf-8');
|
|
73
|
+
const dotenv = require('dotenv');
|
|
74
|
+
mergeEnvWithoutOverwrite(dotenv.parse(dotenvFile));
|
|
75
|
+
}
|
|
76
|
+
} catch (_e) {
|
|
77
|
+
// Continue without .env.sentry-build-plugin
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ─── Hooks module & options ──────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Loads the EAS build hooks module from the compiled output.
|
|
85
|
+
* @returns {object} The hooks module exports
|
|
86
|
+
* @throws {Error} If the module cannot be loaded
|
|
87
|
+
*/
|
|
88
|
+
function loadHooksModule() {
|
|
89
|
+
try {
|
|
90
|
+
return require('../dist/js/tools/easBuildHooks.js');
|
|
91
|
+
} catch (_e) {
|
|
92
|
+
console.error('[Sentry] Could not load EAS build hooks module. Make sure @sentry/react-native is properly installed.');
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Parses common options from environment variables.
|
|
99
|
+
* @returns {object} Parsed options object
|
|
100
|
+
*/
|
|
101
|
+
function parseBaseOptions() {
|
|
102
|
+
const options = {
|
|
103
|
+
dsn: process.env.SENTRY_DSN,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Parse additional tags if provided
|
|
107
|
+
if (process.env.SENTRY_EAS_BUILD_TAGS) {
|
|
108
|
+
try {
|
|
109
|
+
const parsed = JSON.parse(process.env.SENTRY_EAS_BUILD_TAGS);
|
|
110
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
111
|
+
options.tags = parsed;
|
|
112
|
+
} else {
|
|
113
|
+
console.warn('[Sentry] SENTRY_EAS_BUILD_TAGS must be a JSON object (e.g., {"key":"value"}). Ignoring.');
|
|
114
|
+
}
|
|
115
|
+
} catch (_e) {
|
|
116
|
+
console.warn('[Sentry] Could not parse SENTRY_EAS_BUILD_TAGS as JSON. Ignoring.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return options;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ─── Hook configuration & execution ─────────────────────────────────────────
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Hook configuration keyed by hook name.
|
|
127
|
+
*
|
|
128
|
+
* Each entry defines which extra env vars to read and which hooks module
|
|
129
|
+
* method to call.
|
|
130
|
+
*/
|
|
131
|
+
const HOOK_CONFIGS = {
|
|
132
|
+
'on-complete': {
|
|
133
|
+
envKeys: {
|
|
134
|
+
errorMessage: 'SENTRY_EAS_BUILD_ERROR_MESSAGE',
|
|
135
|
+
successMessage: 'SENTRY_EAS_BUILD_SUCCESS_MESSAGE',
|
|
136
|
+
captureSuccessfulBuilds: 'SENTRY_EAS_BUILD_CAPTURE_SUCCESS',
|
|
137
|
+
},
|
|
138
|
+
method: 'captureEASBuildComplete',
|
|
139
|
+
},
|
|
140
|
+
'on-error': {
|
|
141
|
+
envKeys: {
|
|
142
|
+
errorMessage: 'SENTRY_EAS_BUILD_ERROR_MESSAGE',
|
|
143
|
+
},
|
|
144
|
+
method: 'captureEASBuildError',
|
|
145
|
+
},
|
|
146
|
+
'on-success': {
|
|
147
|
+
envKeys: {
|
|
148
|
+
successMessage: 'SENTRY_EAS_BUILD_SUCCESS_MESSAGE',
|
|
149
|
+
captureSuccessfulBuilds: 'SENTRY_EAS_BUILD_CAPTURE_SUCCESS',
|
|
150
|
+
},
|
|
151
|
+
// When a user explicitly configures the on-success hook, they intend to
|
|
152
|
+
// capture successful builds, so default captureSuccessfulBuilds to true.
|
|
153
|
+
defaults: { captureSuccessfulBuilds: true },
|
|
154
|
+
method: 'captureEASBuildSuccess',
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Runs an EAS build hook by name.
|
|
160
|
+
*
|
|
161
|
+
* Loads the environment, resolves hook-specific options from env vars,
|
|
162
|
+
* and calls the corresponding hooks module method.
|
|
163
|
+
*
|
|
164
|
+
* @param {'on-complete' | 'on-error' | 'on-success'} hookName
|
|
165
|
+
*/
|
|
166
|
+
async function runEASBuildHook(hookName) {
|
|
167
|
+
const config = HOOK_CONFIGS[hookName];
|
|
168
|
+
if (!config) {
|
|
169
|
+
throw new Error(`Unknown EAS build hook: ${hookName}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
loadEnv();
|
|
173
|
+
|
|
174
|
+
const hooks = loadHooksModule();
|
|
175
|
+
const options = {
|
|
176
|
+
...parseBaseOptions(),
|
|
177
|
+
...config.defaults,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
for (const [optionKey, envKey] of Object.entries(config.envKeys)) {
|
|
181
|
+
if (optionKey === 'captureSuccessfulBuilds') {
|
|
182
|
+
// Only override the default when the env var is explicitly set
|
|
183
|
+
if (process.env[envKey] !== undefined) {
|
|
184
|
+
options[optionKey] = process.env[envKey] === 'true';
|
|
185
|
+
}
|
|
186
|
+
} else if (process.env[envKey] !== undefined) {
|
|
187
|
+
options[optionKey] = process.env[envKey];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
await hooks[config.method](options);
|
|
193
|
+
console.log(`[Sentry] EAS build ${hookName} hook completed.`);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.error(`[Sentry] Error in eas-build-${hookName} hook:`, error);
|
|
196
|
+
// Don't fail the build hook itself
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ─── Hook name resolution & entry point ─────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
const HOOK_NAME_RE = /(?:sentry-eas-build-|build-)(on-(?:complete|error|success))/;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Resolves which hook to run.
|
|
206
|
+
*
|
|
207
|
+
* 1. Explicit CLI argument: `node build-hook.js on-error`
|
|
208
|
+
* 2. Derived from the script path in process.argv[1]
|
|
209
|
+
*/
|
|
210
|
+
function resolveHookName() {
|
|
211
|
+
const arg = process.argv[2];
|
|
212
|
+
if (arg && /^on-(complete|error|success)$/.test(arg)) {
|
|
213
|
+
return arg;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const caller = path.basename(process.argv[1] || '', '.js');
|
|
217
|
+
const match = caller.match(HOOK_NAME_RE);
|
|
218
|
+
if (match) {
|
|
219
|
+
return match[1];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.error(
|
|
223
|
+
'[Sentry] Could not determine EAS build hook name. ' +
|
|
224
|
+
'Pass one of: on-complete, on-error, on-success',
|
|
225
|
+
);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const hookName = resolveHookName();
|
|
230
|
+
|
|
231
|
+
runEASBuildHook(hookName).catch(error => {
|
|
232
|
+
console.error(`[Sentry] Unexpected error in eas-build-${hookName} hook:`, error);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
});
|
package/scripts/sentry-xcode.sh
CHANGED
|
@@ -15,6 +15,13 @@ RN_PROJECT_ROOT="${PROJECT_DIR}/.."
|
|
|
15
15
|
[ -z "$SENTRY_PROPERTIES" ] && export SENTRY_PROPERTIES=sentry.properties
|
|
16
16
|
[ -z "$SENTRY_DOTENV_PATH" ] && [ -f "$RN_PROJECT_ROOT/.env.sentry-build-plugin" ] && export SENTRY_DOTENV_PATH="$RN_PROJECT_ROOT/.env.sentry-build-plugin"
|
|
17
17
|
[ -z "$SOURCEMAP_FILE" ] && export SOURCEMAP_FILE="$DERIVED_FILE_DIR/main.jsbundle.map"
|
|
18
|
+
# Resolve relative SOURCEMAP_FILE to absolute. The script runs from `ios/` (Xcode's PWD),
|
|
19
|
+
# but users typically specify paths relative to the project root. Without this, sentry-cli
|
|
20
|
+
# would resolve relative paths against `ios/` and fail to find the file.
|
|
21
|
+
# See: https://github.com/getsentry/sentry-react-native/issues/3889
|
|
22
|
+
if [[ "$SOURCEMAP_FILE" != /* ]]; then
|
|
23
|
+
export SOURCEMAP_FILE="$(cd "$RN_PROJECT_ROOT" && pwd)/${SOURCEMAP_FILE#./}"
|
|
24
|
+
fi
|
|
18
25
|
|
|
19
26
|
if [ -z "$SENTRY_CLI_EXECUTABLE" ]; then
|
|
20
27
|
# Try standard resolution safely
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NativeLogEntry } from './options';
|
|
2
|
+
/**
|
|
3
|
+
* Sets up the native log listener that forwards logs from the native SDK to JS.
|
|
4
|
+
* This only works when `debug: true` is set in Sentry options.
|
|
5
|
+
*
|
|
6
|
+
* @param callback - The callback to invoke when a native log is received.
|
|
7
|
+
* @returns A function to remove the listener, or undefined if setup failed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function setupNativeLogListener(callback: (log: NativeLogEntry) => void): (() => void) | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Default handler for native logs that uses Sentry's debug logger.
|
|
12
|
+
* This avoids interference with captureConsoleIntegration which would
|
|
13
|
+
* otherwise capture these logs as breadcrumbs or events.
|
|
14
|
+
*/
|
|
15
|
+
export declare function defaultNativeLogHandler(log: NativeLogEntry): void;
|
|
16
|
+
//# sourceMappingURL=NativeLogListener.d.ts.map
|
|
@@ -10,6 +10,7 @@ import type { ReactNativeClientOptions } from './options';
|
|
|
10
10
|
export declare class ReactNativeClient extends Client<ReactNativeClientOptions> {
|
|
11
11
|
private _outcomesBuffer;
|
|
12
12
|
private _logFlushIdleTimeout;
|
|
13
|
+
private _removeNativeLogListener;
|
|
13
14
|
/**
|
|
14
15
|
* Creates a new React Native SDK instance.
|
|
15
16
|
* @param options Configuration options for this SDK.
|
package/ts3.8/dist/js/index.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export type { Breadcrumb, SdkInfo, Event, Exception, SendFeedbackParams, SeverityLevel, Span, StackFrame, Stacktrace, Thread, User, UserFeedback, ErrorEvent, TransactionEvent, Metric, } from '@sentry/core';
|
|
2
|
-
export { addBreadcrumb, addIntegration, captureException, captureEvent, captureFeedback, captureMessage, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startInactiveSpan, startSpan, startSpanManual, getActiveSpan, getRootSpan, withActiveSpan, suppressTracing, spanToJSON, spanIsSampled, setMeasurement, getCurrentScope, getGlobalScope, getIsolationScope, getClient, setCurrentClient, addEventProcessor, lastEventId, } from '@sentry/core';
|
|
2
|
+
export { addBreadcrumb, addIntegration, captureException, captureEvent, captureFeedback, captureMessage, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startInactiveSpan, startSpan, startSpanManual, getActiveSpan, getRootSpan, withActiveSpan, suppressTracing, spanToJSON, spanIsSampled, setMeasurement, getCurrentScope, getGlobalScope, getIsolationScope, getClient, setCurrentClient, addEventProcessor, lastEventId, consoleSandbox, } from '@sentry/core';
|
|
3
3
|
export { ErrorBoundary, withErrorBoundary, createReduxEnhancer, Profiler, useProfiler, withProfiler, } from '@sentry/react';
|
|
4
4
|
export type { FeatureFlagsIntegration } from '@sentry/browser';
|
|
5
5
|
export { logger, consoleLoggingIntegration, featureFlagsIntegration, metrics } from '@sentry/browser';
|
|
6
6
|
export * from './integrations/exports';
|
|
7
7
|
export { SDK_NAME, SDK_VERSION } from './version';
|
|
8
|
-
export type { ReactNativeOptions } from './options';
|
|
8
|
+
export type { ReactNativeOptions, NativeLogEntry } from './options';
|
|
9
9
|
export { ReactNativeClient } from './client';
|
|
10
10
|
export { init, wrap, nativeCrash, flush, close, withScope, crashedLastRun } from './sdk';
|
|
11
11
|
export { TouchEventBoundary, withTouchEventBoundary } from './touchevents';
|
|
12
|
-
export { reactNativeTracingIntegration, getCurrentReactNativeTracingIntegration, getReactNativeTracingIntegration, reactNavigationIntegration, reactNativeNavigationIntegration, sentryTraceGesture, TimeToInitialDisplay, TimeToFullDisplay, startTimeToInitialDisplaySpan, startTimeToFullDisplaySpan, startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions, createTimeToFullDisplay, createTimeToInitialDisplay, wrapExpoRouter, } from './tracing';
|
|
13
|
-
export type { TimeToDisplayProps, ExpoRouter } from './tracing';
|
|
12
|
+
export { reactNativeTracingIntegration, getCurrentReactNativeTracingIntegration, getReactNativeTracingIntegration, reactNavigationIntegration, reactNativeNavigationIntegration, sentryTraceGesture, TimeToInitialDisplay, TimeToFullDisplay, startTimeToInitialDisplaySpan, startTimeToFullDisplaySpan, startIdleNavigationSpan, startIdleSpan, getDefaultIdleNavigationSpanOptions, createTimeToFullDisplay, createTimeToInitialDisplay, wrapExpoRouter, wrapExpoImage, wrapExpoAsset, } from './tracing';
|
|
13
|
+
export type { TimeToDisplayProps, ExpoRouter, ExpoImage, ExpoAsset } from './tracing';
|
|
14
14
|
export { Mask, Unmask } from './replay/CustomMask';
|
|
15
15
|
export { FeedbackButton } from './feedback/FeedbackButton';
|
|
16
16
|
export { FeedbackWidget } from './feedback/FeedbackWidget';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Integration } from '@sentry/core';
|
|
2
|
+
export declare const EXPO_CONSTANTS_CONTEXT_KEY = "expo_constants";
|
|
3
|
+
/** Load Expo Constants as event context. */
|
|
4
|
+
export declare const expoConstantsIntegration: () => Integration;
|
|
5
|
+
/**
|
|
6
|
+
* @internal Exposed for testing purposes
|
|
7
|
+
*/
|
|
8
|
+
export declare function getExpoConstantsContext(): ExpoConstantsContext;
|
|
9
|
+
type ExpoConstantsContext = Partial<{
|
|
10
|
+
execution_environment: string;
|
|
11
|
+
app_ownership: string;
|
|
12
|
+
debug_mode: boolean;
|
|
13
|
+
expo_version: string;
|
|
14
|
+
expo_runtime_version: string;
|
|
15
|
+
session_id: string;
|
|
16
|
+
status_bar_height: number;
|
|
17
|
+
app_name: string;
|
|
18
|
+
app_slug: string;
|
|
19
|
+
app_version: string;
|
|
20
|
+
expo_sdk_version?: string;
|
|
21
|
+
eas_project_id: string;
|
|
22
|
+
}>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=expoconstants.d.ts.map
|
|
@@ -11,6 +11,7 @@ export { hermesProfilingIntegration } from '../profiling/integration';
|
|
|
11
11
|
export { screenshotIntegration } from './screenshot';
|
|
12
12
|
export { viewHierarchyIntegration } from './viewhierarchy';
|
|
13
13
|
export { expoContextIntegration } from './expocontext';
|
|
14
|
+
export { expoConstantsIntegration } from './expoconstants';
|
|
14
15
|
export { spotlightIntegration } from './spotlight';
|
|
15
16
|
export { mobileReplayIntegration } from '../replay/mobilereplay';
|
|
16
17
|
export { feedbackIntegration } from '../feedback/integration';
|
|
@@ -313,6 +313,32 @@ export interface BaseReactNativeOptions {
|
|
|
313
313
|
* @default 'all'
|
|
314
314
|
*/
|
|
315
315
|
logsOrigin?: 'all' | 'js' | 'native';
|
|
316
|
+
/**
|
|
317
|
+
* A callback that is invoked when the native SDK emits a log message.
|
|
318
|
+
* This is useful for surfacing native SDK logs (e.g., transport errors like HTTP 413)
|
|
319
|
+
* in the JavaScript console.
|
|
320
|
+
*
|
|
321
|
+
* Only works when `debug: true` is set.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```typescript
|
|
325
|
+
* Sentry.init({
|
|
326
|
+
* debug: true,
|
|
327
|
+
* onNativeLog: ({ level, component, message }) => {
|
|
328
|
+
* console.log(`[Sentry Native] [${level}] [${component}] ${message}`);
|
|
329
|
+
* },
|
|
330
|
+
* });
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
onNativeLog?: (log: NativeLogEntry) => void;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Represents a log entry from the native SDK.
|
|
337
|
+
*/
|
|
338
|
+
export interface NativeLogEntry {
|
|
339
|
+
level: string;
|
|
340
|
+
component: string;
|
|
341
|
+
message: string;
|
|
316
342
|
}
|
|
317
343
|
export type SentryReplayQuality = 'low' | 'medium' | 'high';
|
|
318
344
|
/**
|