@sentry/react-native 7.12.0 → 8.0.0-beta.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/RNSentry.podspec +9 -4
- package/android/libs/replay-stubs.jar +0 -0
- package/android/src/main/java/io/sentry/react/RNSentryCompositeOptionsConfiguration.java +25 -0
- package/android/src/main/java/io/sentry/react/RNSentryJsonConverter.java +76 -0
- package/android/src/main/java/io/sentry/react/RNSentryJsonUtils.java +41 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +2 -395
- package/android/src/main/java/io/sentry/react/RNSentrySDK.java +68 -0
- package/android/src/main/java/io/sentry/react/RNSentryStart.java +413 -0
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/replay/mobilereplay.d.ts +0 -26
- package/dist/js/replay/mobilereplay.d.ts.map +1 -1
- package/dist/js/replay/mobilereplay.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +21 -10
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/metroconfig.d.ts +9 -1
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js +9 -2
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -1
- package/dist/js/tools/sentryMetroSerializer.js +1 -0
- package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
- package/dist/js/tools/sentryOptionsSerializer.d.ts +6 -0
- package/dist/js/tools/sentryOptionsSerializer.d.ts.map +1 -0
- package/dist/js/tools/sentryOptionsSerializer.js +92 -0
- package/dist/js/tools/sentryOptionsSerializer.js.map +1 -0
- package/dist/js/tools/utils.d.ts +2 -1
- package/dist/js/tools/utils.d.ts.map +1 -1
- package/dist/js/tools/utils.js.map +1 -1
- package/dist/js/utils/worldwide.d.ts +2 -0
- package/dist/js/utils/worldwide.d.ts.map +1 -1
- package/dist/js/utils/worldwide.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/ios/RNSentry+fetchNativeStack.m +1 -0
- package/ios/RNSentry.h +3 -0
- package/ios/RNSentry.mm +12 -45
- package/ios/RNSentryDependencyContainer.h +2 -1
- package/ios/RNSentryDependencyContainer.m +1 -0
- package/ios/RNSentryEmitNewFrameEvent.h +3 -0
- package/ios/RNSentryExperimentalOptions.m +1 -1
- package/ios/RNSentryFramesTrackerListener.h +2 -2
- package/ios/RNSentryFramesTrackerListener.m +2 -0
- package/ios/RNSentryOnDrawReporter.h +2 -1
- package/ios/RNSentryOnDrawReporter.m +2 -0
- package/ios/RNSentryRNSScreen.m +3 -4
- package/ios/RNSentryReplay.mm +0 -5
- package/ios/RNSentryReplayBreadcrumbConverter.m +12 -12
- package/ios/RNSentrySDK.h +31 -0
- package/ios/RNSentrySDK.m +78 -0
- package/ios/RNSentryStart.h +25 -0
- package/ios/RNSentryStart.m +228 -0
- package/ios/RNSentryVersion.m +1 -1
- package/ios/SentrySDKWrapper.m +2 -2
- package/ios/SentryScreenFramesWrapper.h +14 -0
- package/ios/SentryScreenFramesWrapper.m +39 -0
- package/package.json +2 -2
- package/plugin/build/logger.d.ts +24 -0
- package/plugin/build/logger.js +44 -0
- package/plugin/build/utils.d.ts +0 -18
- package/plugin/build/utils.js +1 -34
- package/plugin/build/version.d.ts +2 -0
- package/plugin/build/version.js +6 -0
- package/plugin/build/withSentry.d.ts +1 -0
- package/plugin/build/withSentry.js +11 -10
- package/plugin/build/withSentryAndroid.d.ts +6 -1
- package/plugin/build/withSentryAndroid.js +52 -8
- package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
- package/plugin/build/withSentryAndroidGradlePlugin.js +8 -8
- package/plugin/build/withSentryIOS.d.ts +6 -1
- package/plugin/build/withSentryIOS.js +55 -7
- package/scripts/sentry-xcode.sh +20 -0
- package/sentry.gradle +51 -0
- package/ts3.8/dist/js/replay/mobilereplay.d.ts +0 -26
- package/ts3.8/dist/js/utils/worldwide.d.ts +2 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#import "RNSentryStart.h"
|
|
2
|
+
#import "RNSentryExperimentalOptions.h"
|
|
3
|
+
#import "RNSentryReplay.h"
|
|
4
|
+
#import "RNSentryVersion.h"
|
|
5
|
+
|
|
6
|
+
#import <Sentry/PrivateSentrySDKOnly.h>
|
|
7
|
+
#import <Sentry/Sentry.h>
|
|
8
|
+
@import Sentry;
|
|
9
|
+
|
|
10
|
+
@implementation RNSentryStart
|
|
11
|
+
|
|
12
|
+
+ (void)startWithOptions:(NSDictionary *_Nonnull)javascriptOptions
|
|
13
|
+
error:(NSError *_Nullable *_Nullable)errorPointer
|
|
14
|
+
{
|
|
15
|
+
SentryOptions *options = [self createOptionsWithDictionary:javascriptOptions
|
|
16
|
+
error:errorPointer];
|
|
17
|
+
[self updateWithReactDefaults:options];
|
|
18
|
+
[self updateWithReactFinals:options];
|
|
19
|
+
[self startWithOptions:options];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
+ (void)startWithOptions:(SentryOptions *)options NS_SWIFT_NAME(start(options:))
|
|
23
|
+
{
|
|
24
|
+
NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString];
|
|
25
|
+
[PrivateSentrySDKOnly setSdkName:NATIVE_SDK_NAME andVersionString:sdkVersion];
|
|
26
|
+
[PrivateSentrySDKOnly addSdkPackage:REACT_NATIVE_SDK_PACKAGE_NAME
|
|
27
|
+
version:REACT_NATIVE_SDK_PACKAGE_VERSION];
|
|
28
|
+
|
|
29
|
+
[SentrySDK startWithOptions:options];
|
|
30
|
+
|
|
31
|
+
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
32
|
+
[RNSentryReplay postInit];
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
[self postDidBecomeActiveNotification];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
+ (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
|
|
39
|
+
error:(NSError *_Nonnull *_Nonnull)errorPointer
|
|
40
|
+
{
|
|
41
|
+
NSMutableDictionary *mutableOptions = [options mutableCopy];
|
|
42
|
+
|
|
43
|
+
#if SENTRY_TARGET_REPLAY_SUPPORTED
|
|
44
|
+
BOOL isSessionReplayEnabled = [RNSentryReplay updateOptions:mutableOptions];
|
|
45
|
+
#else
|
|
46
|
+
BOOL isSessionReplayEnabled = NO;
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
SentryOptions *sentryOptions = [PrivateSentrySDKOnly optionsWithDictionary:mutableOptions
|
|
50
|
+
didFailWithError:errorPointer];
|
|
51
|
+
if (*errorPointer != nil) {
|
|
52
|
+
return nil;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Exclude Dev Server and Sentry Dsn request from Breadcrumbs
|
|
56
|
+
NSString *dsn = [self getURLFromDSN:[mutableOptions valueForKey:@"dsn"]];
|
|
57
|
+
// TODO: For Auto Init from JS dev server is resolved automatically, for init from options file
|
|
58
|
+
// dev server has to be specified manually
|
|
59
|
+
NSString *devServerUrl = [mutableOptions valueForKey:@"devServerUrl"];
|
|
60
|
+
sentryOptions.beforeBreadcrumb
|
|
61
|
+
= ^SentryBreadcrumb *_Nullable(SentryBreadcrumb *_Nonnull breadcrumb)
|
|
62
|
+
{
|
|
63
|
+
NSString *url = breadcrumb.data[@"url"] ?: @"";
|
|
64
|
+
|
|
65
|
+
if ([@"http" isEqualToString:breadcrumb.type]
|
|
66
|
+
&& ((dsn != nil && [url hasPrefix:dsn])
|
|
67
|
+
|| (devServerUrl != nil && [url hasPrefix:devServerUrl]))) {
|
|
68
|
+
return nil;
|
|
69
|
+
}
|
|
70
|
+
return breadcrumb;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// JS options.enableNativeCrashHandling equals to native options.enableCrashHandler
|
|
74
|
+
if ([mutableOptions valueForKey:@"enableNativeCrashHandling"] != nil) {
|
|
75
|
+
BOOL enableNativeCrashHandling = [mutableOptions[@"enableNativeCrashHandling"] boolValue];
|
|
76
|
+
|
|
77
|
+
if (!enableNativeCrashHandling) {
|
|
78
|
+
sentryOptions.enableCrashHandler = NO;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Set spotlight option
|
|
83
|
+
if ([mutableOptions valueForKey:@"spotlight"] != nil) {
|
|
84
|
+
id spotlightValue = [mutableOptions valueForKey:@"spotlight"];
|
|
85
|
+
if ([spotlightValue isKindOfClass:[NSString class]]) {
|
|
86
|
+
NSLog(@"Using Spotlight on address: %@", spotlightValue);
|
|
87
|
+
sentryOptions.enableSpotlight = true;
|
|
88
|
+
sentryOptions.spotlightUrl = spotlightValue;
|
|
89
|
+
} else if ([spotlightValue isKindOfClass:[NSNumber class]]) {
|
|
90
|
+
sentryOptions.enableSpotlight = [spotlightValue boolValue];
|
|
91
|
+
// TODO: For Auto init from JS set automatically for init from options file have to be
|
|
92
|
+
// set manually
|
|
93
|
+
id defaultSpotlightUrl = [mutableOptions valueForKey:@"defaultSidecarUrl"];
|
|
94
|
+
if (defaultSpotlightUrl != nil) {
|
|
95
|
+
sentryOptions.spotlightUrl = defaultSpotlightUrl;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (isSessionReplayEnabled) {
|
|
101
|
+
[RNSentryExperimentalOptions setEnableSessionReplayInUnreliableEnvironment:YES
|
|
102
|
+
sentryOptions:sentryOptions];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return sentryOptions;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* This function updates the options with RNSentry defaults. These default can be
|
|
110
|
+
* overwritten by users during manual native initialization.
|
|
111
|
+
*/
|
|
112
|
+
+ (void)updateWithReactDefaults:(SentryOptions *)options
|
|
113
|
+
{
|
|
114
|
+
// Failed requests are captured only in JS to avoid duplicates
|
|
115
|
+
options.enableCaptureFailedRequests = NO;
|
|
116
|
+
|
|
117
|
+
// Tracing is only enabled in JS to avoid duplicate navigation spans
|
|
118
|
+
options.tracesSampleRate = nil;
|
|
119
|
+
options.tracesSampler = nil;
|
|
120
|
+
// Note: enableTracing property is deprecated in Sentry Cocoa SDK v7
|
|
121
|
+
// Tracing is disabled by setting tracesSampleRate and tracesSampler to nil
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* This function updates options with changes RNSentry users should not change
|
|
126
|
+
* and so this is applied after the configureOptions callback during manual native initialization.
|
|
127
|
+
*/
|
|
128
|
+
+ (void)updateWithReactFinals:(SentryOptions *)options
|
|
129
|
+
{
|
|
130
|
+
SentryBeforeSendEventCallback userBeforeSend = options.beforeSend;
|
|
131
|
+
options.beforeSend = ^SentryEvent *(SentryEvent *event) {
|
|
132
|
+
// Unhandled JS Exception are processed by the SDK on JS layer
|
|
133
|
+
// To avoid duplicates we drop them in the native SDKs
|
|
134
|
+
if (nil != event.exceptions.firstObject.type &&
|
|
135
|
+
[event.exceptions.firstObject.type rangeOfString:@"Unhandled JS Exception"].location
|
|
136
|
+
!= NSNotFound) {
|
|
137
|
+
return nil;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
[self setEventOriginTag:event];
|
|
141
|
+
if (userBeforeSend == nil) {
|
|
142
|
+
return event;
|
|
143
|
+
} else {
|
|
144
|
+
return userBeforeSend(event);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// App Start Hybrid mode doesn't wait for didFinishLaunchNotification and the
|
|
149
|
+
// didBecomeVisibleNotification as they will be missed when auto initializing from JS
|
|
150
|
+
// App Start measurements are created right after the tracking starts
|
|
151
|
+
PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = options.enableAutoPerformanceTracing;
|
|
152
|
+
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
153
|
+
// Frames Tracking Hybrid Mode ensures tracking
|
|
154
|
+
// is enabled without tracing enabled in the native SDK
|
|
155
|
+
PrivateSentrySDKOnly.framesTrackingMeasurementHybridSDKMode
|
|
156
|
+
= options.enableAutoPerformanceTracing;
|
|
157
|
+
#endif
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
+ (void)setEventOriginTag:(SentryEvent *)event
|
|
161
|
+
{
|
|
162
|
+
if (event.sdk != nil) {
|
|
163
|
+
NSString *sdkName = event.sdk[@"name"];
|
|
164
|
+
|
|
165
|
+
// If the event is from react native, it gets set
|
|
166
|
+
// there and we do not handle it here.
|
|
167
|
+
if ([sdkName isEqual:NATIVE_SDK_NAME]) {
|
|
168
|
+
[self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
+ (void)setEventEnvironmentTag:(SentryEvent *)event
|
|
174
|
+
origin:(NSString *)origin
|
|
175
|
+
environment:(NSString *)environment
|
|
176
|
+
{
|
|
177
|
+
NSMutableDictionary *newTags = [NSMutableDictionary new];
|
|
178
|
+
|
|
179
|
+
if (nil != event.tags && [event.tags count] > 0) {
|
|
180
|
+
[newTags addEntriesFromDictionary:event.tags];
|
|
181
|
+
}
|
|
182
|
+
if (nil != origin) {
|
|
183
|
+
[newTags setValue:origin forKey:@"event.origin"];
|
|
184
|
+
}
|
|
185
|
+
if (nil != environment) {
|
|
186
|
+
[newTags setValue:environment forKey:@"event.environment"];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
event.tags = newTags;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
+ (NSString *_Nullable)getURLFromDSN:(NSString *)dsn
|
|
193
|
+
{
|
|
194
|
+
NSURL *url = [NSURL URLWithString:dsn];
|
|
195
|
+
if (!url) {
|
|
196
|
+
return nil;
|
|
197
|
+
}
|
|
198
|
+
return [NSString stringWithFormat:@"%@://%@", url.scheme, url.host];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static bool sentHybridSdkDidBecomeActive = NO;
|
|
202
|
+
|
|
203
|
+
+ (void)postDidBecomeActiveNotification
|
|
204
|
+
{
|
|
205
|
+
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
206
|
+
BOOL appIsActive =
|
|
207
|
+
[[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
|
|
208
|
+
#else
|
|
209
|
+
BOOL appIsActive = [[NSApplication sharedApplication] isActive];
|
|
210
|
+
#endif
|
|
211
|
+
|
|
212
|
+
// If the app is active/in foreground, and we have not sent the SentryHybridSdkDidBecomeActive
|
|
213
|
+
// notification, send it.
|
|
214
|
+
if (appIsActive && !sentHybridSdkDidBecomeActive
|
|
215
|
+
&& (PrivateSentrySDKOnly.options.enableAutoSessionTracking
|
|
216
|
+
|| PrivateSentrySDKOnly.options.enableWatchdogTerminationTracking)) {
|
|
217
|
+
// Updates Native App State Manager
|
|
218
|
+
// https://github.com/getsentry/sentry-cocoa/blob/888a145b144b8077e03151a886520f332e47e297/Sources/Sentry/SentryAppStateManager.m#L136
|
|
219
|
+
// Triggers Session Tracker
|
|
220
|
+
// https://github.com/getsentry/sentry-cocoa/blob/888a145b144b8077e03151a886520f332e47e297/Sources/Sentry/SentrySessionTracker.m#L144
|
|
221
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"SentryHybridSdkDidBecomeActive"
|
|
222
|
+
object:nil];
|
|
223
|
+
|
|
224
|
+
sentHybridSdkDidBecomeActive = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@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 = @"
|
|
6
|
+
NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.0.0-beta.0";
|
package/ios/SentrySDKWrapper.m
CHANGED
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
error:(NSError *__autoreleasing *)errorPointer
|
|
36
36
|
{
|
|
37
37
|
NSString *dsn = [self getURLFromDSN:[options valueForKey:@"dsn"]];
|
|
38
|
-
SentryOptions *sentryOptions = [
|
|
39
|
-
|
|
38
|
+
SentryOptions *sentryOptions = [PrivateSentrySDKOnly optionsWithDictionary:options
|
|
39
|
+
didFailWithError:errorPointer];
|
|
40
40
|
if (*errorPointer != nil) {
|
|
41
41
|
return nil;
|
|
42
42
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
4
|
+
|
|
5
|
+
@interface SentryScreenFramesWrapper : NSObject
|
|
6
|
+
|
|
7
|
+
+ (BOOL)canTrackFrames;
|
|
8
|
+
+ (NSNumber *)totalFrames;
|
|
9
|
+
+ (NSNumber *)frozenFrames;
|
|
10
|
+
+ (NSNumber *)slowFrames;
|
|
11
|
+
|
|
12
|
+
@end
|
|
13
|
+
|
|
14
|
+
#endif // TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#import "SentryScreenFramesWrapper.h"
|
|
2
|
+
@import Sentry;
|
|
3
|
+
|
|
4
|
+
#if TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
|
5
|
+
|
|
6
|
+
@implementation SentryScreenFramesWrapper
|
|
7
|
+
|
|
8
|
+
+ (BOOL)canTrackFrames
|
|
9
|
+
{
|
|
10
|
+
return PrivateSentrySDKOnly.currentScreenFrames != nil;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
+ (NSNumber *)totalFrames
|
|
14
|
+
{
|
|
15
|
+
if (![self canTrackFrames]) {
|
|
16
|
+
return nil;
|
|
17
|
+
}
|
|
18
|
+
return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.total];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
+ (NSNumber *)frozenFrames
|
|
22
|
+
{
|
|
23
|
+
if (![self canTrackFrames]) {
|
|
24
|
+
return nil;
|
|
25
|
+
}
|
|
26
|
+
return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.frozen];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
+ (NSNumber *)slowFrames
|
|
30
|
+
{
|
|
31
|
+
if (![self canTrackFrames]) {
|
|
32
|
+
return nil;
|
|
33
|
+
}
|
|
34
|
+
return [NSNumber numberWithLong:PrivateSentrySDKOnly.currentScreenFrames.slow];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@end
|
|
38
|
+
|
|
39
|
+
#endif // TARGET_OS_IPHONE || TARGET_OS_MACCATALYST
|
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": "
|
|
5
|
+
"version": "8.0.0-beta.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",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"@sentry/babel-plugin-component-annotate": "4.9.0",
|
|
72
72
|
"@sentry/browser": "10.38.0",
|
|
73
|
-
"@sentry/cli": "
|
|
73
|
+
"@sentry/cli": "3.1.0",
|
|
74
74
|
"@sentry/core": "10.38.0",
|
|
75
75
|
"@sentry/react": "10.38.0",
|
|
76
76
|
"@sentry/types": "10.38.0"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log a warning message only once per run.
|
|
3
|
+
* This is used to avoid spamming the console with the same message.
|
|
4
|
+
*/
|
|
5
|
+
export declare function warnOnce(message: string): void;
|
|
6
|
+
/**
|
|
7
|
+
* Prefix message with `› [value]`.
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* ```
|
|
11
|
+
* › [@sentry/react-native/expo] This is a warning message
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function prefix(value: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* The same as `chalk.yellow`
|
|
17
|
+
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
18
|
+
*/
|
|
19
|
+
export declare function yellow(message: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* The same as `chalk.bold`
|
|
22
|
+
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
23
|
+
*/
|
|
24
|
+
export declare function bold(message: string): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bold = exports.yellow = exports.prefix = exports.warnOnce = void 0;
|
|
4
|
+
const warningMap = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* Log a warning message only once per run.
|
|
7
|
+
* This is used to avoid spamming the console with the same message.
|
|
8
|
+
*/
|
|
9
|
+
function warnOnce(message) {
|
|
10
|
+
if (!warningMap.has(message)) {
|
|
11
|
+
warningMap.set(message, true);
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
console.warn(yellow(prefix(message)));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.warnOnce = warnOnce;
|
|
17
|
+
/**
|
|
18
|
+
* Prefix message with `› [value]`.
|
|
19
|
+
*
|
|
20
|
+
* Example:
|
|
21
|
+
* ```
|
|
22
|
+
* › [@sentry/react-native/expo] This is a warning message
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function prefix(value) {
|
|
26
|
+
return `› ${bold('[@sentry/react-native/expo]')} ${value}`;
|
|
27
|
+
}
|
|
28
|
+
exports.prefix = prefix;
|
|
29
|
+
/**
|
|
30
|
+
* The same as `chalk.yellow`
|
|
31
|
+
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
32
|
+
*/
|
|
33
|
+
function yellow(message) {
|
|
34
|
+
return `\x1b[33m${message}\x1b[0m`;
|
|
35
|
+
}
|
|
36
|
+
exports.yellow = yellow;
|
|
37
|
+
/**
|
|
38
|
+
* The same as `chalk.bold`
|
|
39
|
+
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
40
|
+
*/
|
|
41
|
+
function bold(message) {
|
|
42
|
+
return `\x1b[1m${message}\x1b[22m`;
|
|
43
|
+
}
|
|
44
|
+
exports.bold = bold;
|
package/plugin/build/utils.d.ts
CHANGED
|
@@ -1,19 +1 @@
|
|
|
1
1
|
export declare function writeSentryPropertiesTo(filepath: string, sentryProperties: string): void;
|
|
2
|
-
declare const sdkPackage: {
|
|
3
|
-
name: string;
|
|
4
|
-
version: string;
|
|
5
|
-
};
|
|
6
|
-
declare const SDK_PACKAGE_NAME: string;
|
|
7
|
-
export declare function warnOnce(message: string): void;
|
|
8
|
-
export declare function logPrefix(): string;
|
|
9
|
-
/**
|
|
10
|
-
* The same as `chalk.yellow`
|
|
11
|
-
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
12
|
-
*/
|
|
13
|
-
export declare function yellow(message: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* The same as `chalk.bold`
|
|
16
|
-
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
17
|
-
*/
|
|
18
|
-
export declare function bold(message: string): string;
|
|
19
|
-
export { sdkPackage, SDK_PACKAGE_NAME };
|
package/plugin/build/utils.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
26
|
+
exports.writeSentryPropertiesTo = void 0;
|
|
27
27
|
const fs = __importStar(require("fs"));
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
29
|
function writeSentryPropertiesTo(filepath, sentryProperties) {
|
|
@@ -33,36 +33,3 @@ function writeSentryPropertiesTo(filepath, sentryProperties) {
|
|
|
33
33
|
fs.writeFileSync(path.resolve(filepath, 'sentry.properties'), sentryProperties);
|
|
34
34
|
}
|
|
35
35
|
exports.writeSentryPropertiesTo = writeSentryPropertiesTo;
|
|
36
|
-
const sdkPackage = require('../../package.json');
|
|
37
|
-
exports.sdkPackage = sdkPackage;
|
|
38
|
-
const SDK_PACKAGE_NAME = `${sdkPackage.name}/expo`;
|
|
39
|
-
exports.SDK_PACKAGE_NAME = SDK_PACKAGE_NAME;
|
|
40
|
-
const warningMap = new Map();
|
|
41
|
-
function warnOnce(message) {
|
|
42
|
-
if (!warningMap.has(message)) {
|
|
43
|
-
warningMap.set(message, true);
|
|
44
|
-
// eslint-disable-next-line no-console
|
|
45
|
-
console.warn(yellow(`${logPrefix()} ${message}`));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
exports.warnOnce = warnOnce;
|
|
49
|
-
function logPrefix() {
|
|
50
|
-
return `› ${bold('[@sentry/react-native/expo]')}`;
|
|
51
|
-
}
|
|
52
|
-
exports.logPrefix = logPrefix;
|
|
53
|
-
/**
|
|
54
|
-
* The same as `chalk.yellow`
|
|
55
|
-
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
56
|
-
*/
|
|
57
|
-
function yellow(message) {
|
|
58
|
-
return `\x1b[33m${message}\x1b[0m`;
|
|
59
|
-
}
|
|
60
|
-
exports.yellow = yellow;
|
|
61
|
-
/**
|
|
62
|
-
* The same as `chalk.bold`
|
|
63
|
-
* This code is part of the SDK, we don't want to introduce a dependency on `chalk` just for this.
|
|
64
|
-
*/
|
|
65
|
-
function bold(message) {
|
|
66
|
-
return `\x1b[1m${message}\x1b[22m`;
|
|
67
|
-
}
|
|
68
|
-
exports.bold = bold;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_VERSION = exports.PLUGIN_NAME = void 0;
|
|
4
|
+
const packageJson = require('../../package.json');
|
|
5
|
+
exports.PLUGIN_NAME = `${packageJson.name}/expo`;
|
|
6
|
+
exports.PLUGIN_VERSION = packageJson.version;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
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
|
-
const
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
const version_1 = require("./version");
|
|
6
7
|
const withSentryAndroid_1 = require("./withSentryAndroid");
|
|
7
8
|
const withSentryAndroidGradlePlugin_1 = require("./withSentryAndroidGradlePlugin");
|
|
8
9
|
const withSentryIOS_1 = require("./withSentryIOS");
|
|
@@ -15,10 +16,10 @@ const withSentryPlugin = (config, props) => {
|
|
|
15
16
|
let cfg = config;
|
|
16
17
|
if (sentryProperties !== null) {
|
|
17
18
|
try {
|
|
18
|
-
cfg = (0, withSentryAndroid_1.withSentryAndroid)(cfg, sentryProperties);
|
|
19
|
+
cfg = (0, withSentryAndroid_1.withSentryAndroid)(cfg, { sentryProperties, useNativeInit: props?.useNativeInit });
|
|
19
20
|
}
|
|
20
21
|
catch (e) {
|
|
21
|
-
(0,
|
|
22
|
+
(0, logger_1.warnOnce)(`There was a problem with configuring your native Android project: ${e}`);
|
|
22
23
|
}
|
|
23
24
|
// if `enableAndroidGradlePlugin` is provided configure the Sentry Android Gradle Plugin
|
|
24
25
|
if (props?.experimental_android && props?.experimental_android?.enableAndroidGradlePlugin) {
|
|
@@ -26,14 +27,14 @@ const withSentryPlugin = (config, props) => {
|
|
|
26
27
|
cfg = (0, withSentryAndroidGradlePlugin_1.withSentryAndroidGradlePlugin)(cfg, props.experimental_android);
|
|
27
28
|
}
|
|
28
29
|
catch (e) {
|
|
29
|
-
(0,
|
|
30
|
+
(0, logger_1.warnOnce)(`There was a problem with configuring Sentry Android Gradle Plugin: ${e}`);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
try {
|
|
33
|
-
cfg = (0, withSentryIOS_1.withSentryIOS)(cfg, sentryProperties);
|
|
34
|
+
cfg = (0, withSentryIOS_1.withSentryIOS)(cfg, { sentryProperties, useNativeInit: props?.useNativeInit });
|
|
34
35
|
}
|
|
35
36
|
catch (e) {
|
|
36
|
-
(0,
|
|
37
|
+
(0, logger_1.warnOnce)(`There was a problem with configuring your native iOS project: ${e}`);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
return cfg;
|
|
@@ -47,12 +48,12 @@ function getSentryProperties(props) {
|
|
|
47
48
|
// eslint-disable-next-line no-prototype-builtins
|
|
48
49
|
const missingProperties = ['organization', 'project'].filter(each => !props?.hasOwnProperty(each));
|
|
49
50
|
if (missingProperties.length) {
|
|
50
|
-
const missingPropertiesString = (0,
|
|
51
|
+
const missingPropertiesString = (0, logger_1.bold)(missingProperties.join(', '));
|
|
51
52
|
const warningMessage = `Missing config for ${missingPropertiesString}. Environment variables will be used as a fallback during the build. https://docs.sentry.io/platforms/react-native/manual-setup/`;
|
|
52
|
-
(0,
|
|
53
|
+
(0, logger_1.warnOnce)(warningMessage);
|
|
53
54
|
}
|
|
54
55
|
if (authToken) {
|
|
55
|
-
(0,
|
|
56
|
+
(0, logger_1.warnOnce)(`Detected unsecure use of 'authToken' in Sentry plugin configuration. To avoid exposing the token use ${(0, logger_1.bold)('SENTRY_AUTH_TOKEN')} environment variable instead. https://docs.sentry.io/platforms/react-native/manual-setup/`);
|
|
56
57
|
}
|
|
57
58
|
return `defaults.url=${url}
|
|
58
59
|
${organization ? `defaults.org=${organization}` : missingOrgMessage}
|
|
@@ -61,5 +62,5 @@ ${authToken ? `${existingAuthTokenMessage}\nauth.token=${authToken}` : missingAu
|
|
|
61
62
|
}
|
|
62
63
|
exports.getSentryProperties = getSentryProperties;
|
|
63
64
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
64
|
-
const withSentry = (0, config_plugins_1.createRunOncePlugin)(withSentryPlugin,
|
|
65
|
+
const withSentry = (0, config_plugins_1.createRunOncePlugin)(withSentryPlugin, version_1.PLUGIN_NAME, version_1.PLUGIN_VERSION);
|
|
65
66
|
exports.withSentry = withSentry;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import type { ExpoConfig } from '@expo/config-types';
|
|
1
2
|
import type { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
-
export declare const withSentryAndroid: ConfigPlugin<
|
|
3
|
+
export declare const withSentryAndroid: ConfigPlugin<{
|
|
4
|
+
sentryProperties: string;
|
|
5
|
+
useNativeInit: boolean | undefined;
|
|
6
|
+
}>;
|
|
3
7
|
/**
|
|
4
8
|
* Writes to projectDirectory/android/app/build.gradle,
|
|
5
9
|
* adding the relevant @sentry/react-native script.
|
|
6
10
|
*/
|
|
7
11
|
export declare function modifyAppBuildGradle(buildGradle: string): string;
|
|
12
|
+
export declare function modifyMainApplication(config: ExpoConfig): ExpoConfig;
|
|
@@ -23,21 +23,23 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.modifyAppBuildGradle = exports.withSentryAndroid = void 0;
|
|
26
|
+
exports.modifyMainApplication = exports.modifyAppBuildGradle = exports.withSentryAndroid = void 0;
|
|
27
27
|
const config_plugins_1 = require("expo/config-plugins");
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
|
+
const logger_1 = require("./logger");
|
|
29
30
|
const utils_1 = require("./utils");
|
|
30
|
-
const withSentryAndroid = (config, sentryProperties) => {
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
|
|
31
|
+
const withSentryAndroid = (config, { sentryProperties, useNativeInit = false }) => {
|
|
32
|
+
const appBuildGradleCfg = (0, config_plugins_1.withAppBuildGradle)(config, config => {
|
|
33
|
+
if (config.modResults.language === 'groovy') {
|
|
34
|
+
config.modResults.contents = modifyAppBuildGradle(config.modResults.contents);
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
throw new Error('Cannot configure Sentry in the app gradle because the build.gradle is not groovy');
|
|
37
38
|
}
|
|
38
|
-
return
|
|
39
|
+
return config;
|
|
39
40
|
});
|
|
40
|
-
|
|
41
|
+
const mainApplicationCfg = useNativeInit ? modifyMainApplication(appBuildGradleCfg) : appBuildGradleCfg;
|
|
42
|
+
return (0, config_plugins_1.withDangerousMod)(mainApplicationCfg, [
|
|
41
43
|
'android',
|
|
42
44
|
dangerousMod => {
|
|
43
45
|
(0, utils_1.writeSentryPropertiesTo)(path.resolve(dangerousMod.modRequest.projectRoot, 'android'), sentryProperties);
|
|
@@ -59,10 +61,52 @@ function modifyAppBuildGradle(buildGradle) {
|
|
|
59
61
|
// See: https://github.com/getsentry/sentry-wizard/blob/e9b4522f27a852069c862bd458bdf9b07cab6e33/lib/Steps/Integrations/ReactNative.ts#L232
|
|
60
62
|
const pattern = /^android {/m;
|
|
61
63
|
if (!buildGradle.match(pattern)) {
|
|
62
|
-
(0,
|
|
64
|
+
(0, logger_1.warnOnce)('Could not find `^android {` in `android/app/build.gradle`. Please open a bug report at https://github.com/getsentry/sentry-react-native.');
|
|
63
65
|
return buildGradle;
|
|
64
66
|
}
|
|
65
67
|
const applyFrom = `apply from: new File(${resolveSentryReactNativePackageJsonPath}, "sentry.gradle")`;
|
|
66
68
|
return buildGradle.replace(pattern, match => `${applyFrom}\n\n${match}`);
|
|
67
69
|
}
|
|
68
70
|
exports.modifyAppBuildGradle = modifyAppBuildGradle;
|
|
71
|
+
function modifyMainApplication(config) {
|
|
72
|
+
return (0, config_plugins_1.withMainApplication)(config, config => {
|
|
73
|
+
if (!config.modResults?.path) {
|
|
74
|
+
(0, logger_1.warnOnce)("Can't add 'RNSentrySDK.init' to Android MainApplication, because the file was not found.");
|
|
75
|
+
return config;
|
|
76
|
+
}
|
|
77
|
+
const fileName = path.basename(config.modResults.path);
|
|
78
|
+
if (config.modResults.contents.includes('RNSentrySDK.init')) {
|
|
79
|
+
(0, logger_1.warnOnce)(`Your '${fileName}' already contains 'RNSentrySDK.init', the native code won't be updated.`);
|
|
80
|
+
return config;
|
|
81
|
+
}
|
|
82
|
+
if (config.modResults.language === 'java') {
|
|
83
|
+
// Add RNSentrySDK.init
|
|
84
|
+
const originalContents = config.modResults.contents;
|
|
85
|
+
config.modResults.contents = config.modResults.contents.replace(/(super\.onCreate\(\)[;\n]*)([ \t]*)/, '$1\n$2RNSentrySDK.init(this);\n$2');
|
|
86
|
+
if (config.modResults.contents === originalContents) {
|
|
87
|
+
(0, logger_1.warnOnce)(`Failed to insert 'RNSentrySDK.init' in '${fileName}'.`);
|
|
88
|
+
}
|
|
89
|
+
else if (!config.modResults.contents.includes('import io.sentry.react.RNSentrySDK;')) {
|
|
90
|
+
// Insert import statement after package declaration
|
|
91
|
+
config.modResults.contents = config.modResults.contents.replace(/(package .*;\n\n?)/, '$1import io.sentry.react.RNSentrySDK;\n');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (config.modResults.language === 'kt') {
|
|
95
|
+
// Add RNSentrySDK.init
|
|
96
|
+
const originalContents = config.modResults.contents;
|
|
97
|
+
config.modResults.contents = config.modResults.contents.replace(/(super\.onCreate\(\)[;\n]*)([ \t]*)/, '$1\n$2RNSentrySDK.init(this)\n$2');
|
|
98
|
+
if (config.modResults.contents === originalContents) {
|
|
99
|
+
(0, logger_1.warnOnce)(`Failed to insert 'RNSentrySDK.init' in '${fileName}'.`);
|
|
100
|
+
}
|
|
101
|
+
else if (!config.modResults.contents.includes('import io.sentry.react.RNSentrySDK')) {
|
|
102
|
+
// Insert import statement after package declaration
|
|
103
|
+
config.modResults.contents = config.modResults.contents.replace(/(package .*\n\n?)/, '$1import io.sentry.react.RNSentrySDK\n');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
(0, logger_1.warnOnce)(`Unsupported language '${config.modResults.language}' detected in '${fileName}', the native code won't be updated.`);
|
|
108
|
+
}
|
|
109
|
+
return config;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
exports.modifyMainApplication = modifyMainApplication;
|
|
@@ -9,7 +9,7 @@ export interface SentryAndroidGradlePluginOptions {
|
|
|
9
9
|
includeNativeSources?: boolean;
|
|
10
10
|
includeSourceContext?: boolean;
|
|
11
11
|
}
|
|
12
|
-
export declare const sentryAndroidGradlePluginVersion = "
|
|
12
|
+
export declare const sentryAndroidGradlePluginVersion = "6.0.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
|