@sentry/react-native 7.10.0 → 8.0.0-alpha.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 +8 -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 +22 -398
- package/android/src/main/java/io/sentry/react/RNSentrySDK.java +68 -0
- package/android/src/main/java/io/sentry/react/RNSentryStart.java +417 -0
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +10 -0
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +15 -0
- package/dist/js/NativeRNSentry.d.ts +2 -0
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/integrations/logEnricherIntegration.js +43 -3
- package/dist/js/integrations/logEnricherIntegration.js.map +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/scopeSync.d.ts.map +1 -1
- package/dist/js/scopeSync.js +21 -0
- package/dist/js/scopeSync.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/touchevents.d.ts +8 -0
- package/dist/js/touchevents.d.ts.map +1 -1
- package/dist/js/touchevents.js +33 -1
- package/dist/js/touchevents.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/dist/js/wrapper.d.ts +2 -0
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +32 -0
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.h +3 -0
- package/ios/RNSentry.mm +28 -44
- 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/SentryScreenFramesWrapper.h +14 -0
- package/ios/SentryScreenFramesWrapper.m +39 -0
- package/package.json +10 -10
- 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/src/js/NativeRNSentry.ts +2 -0
- package/ts3.8/dist/js/NativeRNSentry.d.ts +2 -0
- package/ts3.8/dist/js/replay/mobilereplay.d.ts +0 -26
- package/ts3.8/dist/js/touchevents.d.ts +8 -0
- package/ts3.8/dist/js/utils/worldwide.d.ts +2 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +2 -0
|
@@ -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
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
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
|
-
const
|
|
6
|
-
exports.sentryAndroidGradlePluginVersion = '
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
exports.sentryAndroidGradlePluginVersion = '6.0.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
|
|
@@ -13,29 +13,29 @@ function withSentryAndroidGradlePlugin(config, { includeProguardMapping = true,
|
|
|
13
13
|
const withSentryProjectBuildGradle = (config) => {
|
|
14
14
|
return (0, config_plugins_1.withProjectBuildGradle)(config, projectBuildGradle => {
|
|
15
15
|
if (!projectBuildGradle.modResults?.contents) {
|
|
16
|
-
(0,
|
|
16
|
+
(0, logger_1.warnOnce)('android/build.gradle content is missing or undefined.');
|
|
17
17
|
return projectBuildGradle;
|
|
18
18
|
}
|
|
19
19
|
if (projectBuildGradle.modResults.language !== 'groovy') {
|
|
20
|
-
(0,
|
|
20
|
+
(0, logger_1.warnOnce)('Cannot configure Sentry in android/build.gradle because it is not in Groovy.');
|
|
21
21
|
return projectBuildGradle;
|
|
22
22
|
}
|
|
23
23
|
const dependency = `classpath("io.sentry:sentry-android-gradle-plugin:${exports.sentryAndroidGradlePluginVersion}")`;
|
|
24
24
|
if (projectBuildGradle.modResults.contents.includes(dependency)) {
|
|
25
|
-
(0,
|
|
25
|
+
(0, logger_1.warnOnce)('sentry-android-gradle-plugin dependency in already in android/build.gradle.');
|
|
26
26
|
return projectBuildGradle;
|
|
27
27
|
}
|
|
28
28
|
try {
|
|
29
29
|
const updatedContents = projectBuildGradle.modResults.contents.replace(/dependencies\s*{/, `dependencies {\n ${dependency}`);
|
|
30
30
|
if (updatedContents === projectBuildGradle.modResults.contents) {
|
|
31
|
-
(0,
|
|
31
|
+
(0, logger_1.warnOnce)('Failed to inject the dependency. Could not find `dependencies` in build.gradle.');
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
projectBuildGradle.modResults.contents = updatedContents;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
|
-
(0,
|
|
38
|
+
(0, logger_1.warnOnce)('An error occurred while trying to modify build.gradle');
|
|
39
39
|
}
|
|
40
40
|
return projectBuildGradle;
|
|
41
41
|
});
|
|
@@ -44,7 +44,7 @@ function withSentryAndroidGradlePlugin(config, { includeProguardMapping = true,
|
|
|
44
44
|
const withSentryAppBuildGradle = (config) => {
|
|
45
45
|
return (0, config_plugins_1.withAppBuildGradle)(config, appBuildGradle => {
|
|
46
46
|
if (appBuildGradle.modResults.language !== 'groovy') {
|
|
47
|
-
(0,
|
|
47
|
+
(0, logger_1.warnOnce)('Cannot configure Sentry in android/app/build.gradle because it is not in Groovy.');
|
|
48
48
|
return appBuildGradle;
|
|
49
49
|
}
|
|
50
50
|
const sentryPlugin = 'apply plugin: "io.sentry.android.gradle"';
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import type { ExpoConfig } from '@expo/config-types';
|
|
1
2
|
import type { ConfigPlugin } from 'expo/config-plugins';
|
|
2
3
|
type BuildPhase = {
|
|
3
4
|
shellScript: string;
|
|
4
5
|
};
|
|
5
|
-
export declare const withSentryIOS: ConfigPlugin<
|
|
6
|
+
export declare const withSentryIOS: ConfigPlugin<{
|
|
7
|
+
sentryProperties: string;
|
|
8
|
+
useNativeInit: boolean | undefined;
|
|
9
|
+
}>;
|
|
6
10
|
export declare function modifyExistingXcodeBuildScript(script: BuildPhase): void;
|
|
7
11
|
export declare function addSentryWithBundledScriptsToBundleShellScript(script: string): string;
|
|
12
|
+
export declare function modifyAppDelegate(config: ExpoConfig): ExpoConfig;
|
|
8
13
|
export {};
|
|
@@ -23,14 +23,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.addSentryWithBundledScriptsToBundleShellScript = exports.modifyExistingXcodeBuildScript = exports.withSentryIOS = void 0;
|
|
26
|
+
exports.modifyAppDelegate = exports.addSentryWithBundledScriptsToBundleShellScript = exports.modifyExistingXcodeBuildScript = exports.withSentryIOS = 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
31
|
const SENTRY_REACT_NATIVE_XCODE_PATH = "`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"`";
|
|
31
32
|
const SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH = "`${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";
|
|
32
|
-
const withSentryIOS = (config, sentryProperties) => {
|
|
33
|
-
const
|
|
33
|
+
const withSentryIOS = (config, { sentryProperties, useNativeInit = false }) => {
|
|
34
|
+
const xcodeProjectCfg = (0, config_plugins_1.withXcodeProject)(config, config => {
|
|
34
35
|
const xcodeProject = config.modResults;
|
|
35
36
|
const sentryBuildPhase = xcodeProject.pbxItemByComment('Upload Debug Symbols to Sentry', 'PBXShellScriptBuildPhase');
|
|
36
37
|
if (!sentryBuildPhase) {
|
|
@@ -43,7 +44,8 @@ const withSentryIOS = (config, sentryProperties) => {
|
|
|
43
44
|
modifyExistingXcodeBuildScript(bundleReactNativePhase);
|
|
44
45
|
return config;
|
|
45
46
|
});
|
|
46
|
-
|
|
47
|
+
const appDelegateCfc = useNativeInit ? modifyAppDelegate(xcodeProjectCfg) : xcodeProjectCfg;
|
|
48
|
+
return (0, config_plugins_1.withDangerousMod)(appDelegateCfc, [
|
|
47
49
|
'ios',
|
|
48
50
|
config => {
|
|
49
51
|
(0, utils_1.writeSentryPropertiesTo)(path.resolve(config.modRequest.projectRoot, 'ios'), sentryProperties);
|
|
@@ -54,16 +56,16 @@ const withSentryIOS = (config, sentryProperties) => {
|
|
|
54
56
|
exports.withSentryIOS = withSentryIOS;
|
|
55
57
|
function modifyExistingXcodeBuildScript(script) {
|
|
56
58
|
if (!script.shellScript.match(/(packager|scripts)\/react-native-xcode\.sh\b/)) {
|
|
57
|
-
(0,
|
|
59
|
+
(0, logger_1.warnOnce)(`'react-native-xcode.sh' not found in 'Bundle React Native code and images'.
|
|
58
60
|
Please open a bug report at https://github.com/getsentry/sentry-react-native`);
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
if (script.shellScript.includes('sentry-xcode.sh')) {
|
|
62
|
-
(0,
|
|
64
|
+
(0, logger_1.warnOnce)("The latest 'sentry-xcode.sh' script already exists in 'Bundle React Native code and images'.");
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
if (script.shellScript.includes('@sentry')) {
|
|
66
|
-
(0,
|
|
68
|
+
(0, logger_1.warnOnce)(`Outdated or custom Sentry script found in 'Bundle React Native code and images'.
|
|
67
69
|
Regenerate the native project to use the latest script.
|
|
68
70
|
Run npx expo prebuild --clean`);
|
|
69
71
|
return;
|
|
@@ -78,3 +80,49 @@ function addSentryWithBundledScriptsToBundleShellScript(script) {
|
|
|
78
80
|
(match) => `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`);
|
|
79
81
|
}
|
|
80
82
|
exports.addSentryWithBundledScriptsToBundleShellScript = addSentryWithBundledScriptsToBundleShellScript;
|
|
83
|
+
function modifyAppDelegate(config) {
|
|
84
|
+
return (0, config_plugins_1.withAppDelegate)(config, async (config) => {
|
|
85
|
+
if (!config.modResults?.path) {
|
|
86
|
+
(0, logger_1.warnOnce)("Can't add 'RNSentrySDK.start()' to the iOS AppDelegate, because the file was not found.");
|
|
87
|
+
return config;
|
|
88
|
+
}
|
|
89
|
+
const fileName = path.basename(config.modResults.path);
|
|
90
|
+
if (config.modResults.language === 'swift') {
|
|
91
|
+
if (config.modResults.contents.includes('RNSentrySDK.start()')) {
|
|
92
|
+
(0, logger_1.warnOnce)(`Your '${fileName}' already contains 'RNSentrySDK.start()'.`);
|
|
93
|
+
return config;
|
|
94
|
+
}
|
|
95
|
+
// Add RNSentrySDK.start() at the beginning of application method
|
|
96
|
+
const originalContents = config.modResults.contents;
|
|
97
|
+
config.modResults.contents = config.modResults.contents.replace(/(func application\([^)]*\) -> Bool \{)\s*\n(\s*)/s, '$1\n$2RNSentrySDK.start()\n$2');
|
|
98
|
+
if (config.modResults.contents === originalContents) {
|
|
99
|
+
(0, logger_1.warnOnce)(`Failed to insert 'RNSentrySDK.start()' in '${fileName}'.`);
|
|
100
|
+
}
|
|
101
|
+
else if (!config.modResults.contents.includes('import RNSentry')) {
|
|
102
|
+
// Insert import statement after the first import (works for both UIKit and Expo imports)
|
|
103
|
+
config.modResults.contents = config.modResults.contents.replace(/(import \S+\n)/, '$1import RNSentry\n');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (['objcpp', 'objc'].includes(config.modResults.language)) {
|
|
107
|
+
if (config.modResults.contents.includes('[RNSentrySDK start]')) {
|
|
108
|
+
(0, logger_1.warnOnce)(`Your '${fileName}' already contains '[RNSentrySDK start]'.`);
|
|
109
|
+
return config;
|
|
110
|
+
}
|
|
111
|
+
// Add [RNSentrySDK start] at the beginning of application:didFinishLaunchingWithOptions method
|
|
112
|
+
const originalContents = config.modResults.contents;
|
|
113
|
+
config.modResults.contents = config.modResults.contents.replace(/(- \(BOOL\)application:[\s\S]*?didFinishLaunchingWithOptions:[\s\S]*?\{\n)(\s*)/s, '$1$2[RNSentrySDK start];\n$2');
|
|
114
|
+
if (config.modResults.contents === originalContents) {
|
|
115
|
+
(0, logger_1.warnOnce)(`Failed to insert '[RNSentrySDK start]' in '${fileName}.`);
|
|
116
|
+
}
|
|
117
|
+
else if (!config.modResults.contents.includes('#import <RNSentry/RNSentry.h>')) {
|
|
118
|
+
// Add import after AppDelegate.h
|
|
119
|
+
config.modResults.contents = config.modResults.contents.replace(/(#import "AppDelegate.h"\n)/, '$1#import <RNSentry/RNSentry.h>\n');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
(0, logger_1.warnOnce)(`Unsupported language '${config.modResults.language}' detected in '${fileName}', the native code won't be updated.`);
|
|
124
|
+
}
|
|
125
|
+
return config;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
exports.modifyAppDelegate = modifyAppDelegate;
|
package/scripts/sentry-xcode.sh
CHANGED
|
@@ -73,4 +73,24 @@ if [ -f "$SENTRY_COLLECT_MODULES" ]; then
|
|
|
73
73
|
/bin/sh "$SENTRY_COLLECT_MODULES"
|
|
74
74
|
fi
|
|
75
75
|
|
|
76
|
+
# sentry.options.json Block
|
|
77
|
+
SENTRY_OPTIONS_FILE_ERROR_MESSAGE_POSTFIX="Skipping options file copy. To disable this behavior, set SENTRY_COPY_OPTIONS_FILE=false in your environment variables."
|
|
78
|
+
SENTRY_OPTIONS_FILE_NAME="sentry.options.json"
|
|
79
|
+
SENTRY_OPTIONS_FILE_DESTINATION_PATH="$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/$SENTRY_OPTIONS_FILE_NAME"
|
|
80
|
+
[ -z "$SENTRY_OPTIONS_FILE_PATH" ] && SENTRY_OPTIONS_FILE_PATH="$RN_PROJECT_ROOT/$SENTRY_OPTIONS_FILE_NAME"
|
|
81
|
+
[ -z "$SENTRY_COPY_OPTIONS_FILE" ] && SENTRY_COPY_OPTIONS_FILE=true
|
|
82
|
+
|
|
83
|
+
if [ "$SENTRY_COPY_OPTIONS_FILE" = true ]; then
|
|
84
|
+
if [[ -z "$CONFIGURATION_BUILD_DIR" ]]; then
|
|
85
|
+
echo "[Sentry] CONFIGURATION_BUILD_DIR is not set. $SENTRY_OPTIONS_FILE_ERROR_MESSAGE_POSTFIX" 1>&2
|
|
86
|
+
elif [[ -z "$UNLOCALIZED_RESOURCES_FOLDER_PATH" ]]; then
|
|
87
|
+
echo "[Sentry] UNLOCALIZED_RESOURCES_FOLDER_PATH is not set. $SENTRY_OPTIONS_FILE_ERROR_MESSAGE_POSTFIX" 1>&2
|
|
88
|
+
elif [ ! -f "$SENTRY_OPTIONS_FILE_PATH" ]; then
|
|
89
|
+
echo "[Sentry] $SENTRY_OPTIONS_FILE_PATH not found. $SENTRY_OPTIONS_FILE_ERROR_MESSAGE_POSTFIX" 1>&2
|
|
90
|
+
else
|
|
91
|
+
cp "$SENTRY_OPTIONS_FILE_PATH" "$SENTRY_OPTIONS_FILE_DESTINATION_PATH"
|
|
92
|
+
echo "[Sentry] Copied $SENTRY_OPTIONS_FILE_PATH to $SENTRY_OPTIONS_FILE_DESTINATION_PATH"
|
|
93
|
+
fi
|
|
94
|
+
fi
|
|
95
|
+
|
|
76
96
|
exit $exitCode
|
package/sentry.gradle
CHANGED
|
@@ -20,8 +20,48 @@ interface InjectedExecOps {
|
|
|
20
20
|
ExecOperations getExecOps()
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
project.ext.shouldCopySentryOptionsFile = { -> // If not set, default to true
|
|
24
|
+
return System.getenv('SENTRY_COPY_OPTIONS_FILE') != 'false'
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
def config = project.hasProperty("sentryCli") ? project.sentryCli : [];
|
|
24
28
|
|
|
29
|
+
def configFile = "sentry.options.json" // Sentry configuration file
|
|
30
|
+
def androidAssetsDir = new File("$rootDir/app/src/main/assets") // Path to Android assets folder
|
|
31
|
+
|
|
32
|
+
tasks.register("copySentryJsonConfiguration") {
|
|
33
|
+
onlyIf { shouldCopySentryOptionsFile() }
|
|
34
|
+
doLast {
|
|
35
|
+
def appRoot = project.rootDir.parentFile ?: project.rootDir
|
|
36
|
+
def sentryOptionsFile = new File(appRoot, configFile)
|
|
37
|
+
if (sentryOptionsFile.exists()) {
|
|
38
|
+
if (!androidAssetsDir.exists()) {
|
|
39
|
+
androidAssetsDir.mkdirs()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
copy {
|
|
43
|
+
from sentryOptionsFile
|
|
44
|
+
into androidAssetsDir
|
|
45
|
+
rename { String fileName -> configFile }
|
|
46
|
+
}
|
|
47
|
+
logger.lifecycle("Copied ${configFile} to Android assets")
|
|
48
|
+
} else {
|
|
49
|
+
logger.warn("${configFile} not found in app root (${appRoot})")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
tasks.register("cleanupTemporarySentryJsonConfiguration") {
|
|
55
|
+
onlyIf { shouldCopySentryOptionsFile() }
|
|
56
|
+
doLast {
|
|
57
|
+
def sentryOptionsFile = new File(androidAssetsDir, configFile)
|
|
58
|
+
if (sentryOptionsFile.exists()) {
|
|
59
|
+
logger.lifecycle("Deleting temporary file: ${sentryOptionsFile.path}")
|
|
60
|
+
sentryOptionsFile.delete()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
25
65
|
plugins.withId('com.android.application') {
|
|
26
66
|
def androidComponents = extensions.getByName("androidComponents")
|
|
27
67
|
|
|
@@ -278,6 +318,17 @@ plugins.withId('com.android.application') {
|
|
|
278
318
|
// gradle.projectsEvaluated doesn't work with --configure-on-demand
|
|
279
319
|
// the task are create too late and not executed
|
|
280
320
|
project.afterEvaluate {
|
|
321
|
+
// Add a task that copies the sentry.options.json file before the build starts
|
|
322
|
+
tasks.named("preBuild").configure {
|
|
323
|
+
dependsOn("copySentryJsonConfiguration")
|
|
324
|
+
}
|
|
325
|
+
// Cleanup sentry.options.json from assets after the build
|
|
326
|
+
tasks.matching { task ->
|
|
327
|
+
task.name == "build" || task.name.startsWith("assemble") || task.name.startsWith("install")
|
|
328
|
+
}.configureEach {
|
|
329
|
+
finalizedBy("cleanupTemporarySentryJsonConfiguration")
|
|
330
|
+
}
|
|
331
|
+
|
|
281
332
|
if (config.flavorAware && config.sentryProperties) {
|
|
282
333
|
throw new GradleException("Incompatible sentry configuration. " +
|
|
283
334
|
"You cannot use both `flavorAware` and `sentryProperties`. " +
|
package/src/js/NativeRNSentry.ts
CHANGED
|
@@ -32,6 +32,8 @@ export interface Spec extends TurboModule {
|
|
|
32
32
|
setContext(key: string, value: UnsafeObject | null): void;
|
|
33
33
|
setExtra(key: string, value: string): void;
|
|
34
34
|
setTag(key: string, value: string): void;
|
|
35
|
+
setAttribute(key: string, value: string): void;
|
|
36
|
+
setAttributes(attributes: UnsafeObject): void;
|
|
35
37
|
enableNativeFramesTracking(): void;
|
|
36
38
|
fetchModules(): Promise<string | undefined | null>;
|
|
37
39
|
fetchViewHierarchy(): Promise<number[] | undefined | null>;
|
|
@@ -25,6 +25,8 @@ export interface Spec extends TurboModule {
|
|
|
25
25
|
setContext(key: string, value: UnsafeObject | null): void;
|
|
26
26
|
setExtra(key: string, value: string): void;
|
|
27
27
|
setTag(key: string, value: string): void;
|
|
28
|
+
setAttribute(key: string, value: string): void;
|
|
29
|
+
setAttributes(attributes: UnsafeObject): void;
|
|
28
30
|
enableNativeFramesTracking(): void;
|
|
29
31
|
fetchModules(): Promise<string | undefined | null>;
|
|
30
32
|
fetchViewHierarchy(): Promise<number[] | undefined | null>;
|
|
@@ -66,32 +66,6 @@ export interface MobileReplayOptions {
|
|
|
66
66
|
* @platform ios
|
|
67
67
|
*/
|
|
68
68
|
enableFastViewRendering?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Array of view class names to include in subtree traversal during session replay and screenshot capture on iOS.
|
|
71
|
-
*
|
|
72
|
-
* Only views that are instances of these classes (or subclasses) will be traversed.
|
|
73
|
-
* This helps prevent crashes when traversing problematic view hierarchies by allowing you to explicitly include only safe view classes.
|
|
74
|
-
*
|
|
75
|
-
* If both `includedViewClasses` and `excludedViewClasses` are set, `excludedViewClasses` takes precedence:
|
|
76
|
-
* views matching excluded classes won't be traversed even if they match an included class.
|
|
77
|
-
*
|
|
78
|
-
* @default undefined
|
|
79
|
-
* @platform ios
|
|
80
|
-
*/
|
|
81
|
-
includedViewClasses?: string[];
|
|
82
|
-
/**
|
|
83
|
-
* Array of view class names to exclude from subtree traversal during session replay and screenshot capture on iOS.
|
|
84
|
-
*
|
|
85
|
-
* Views of these classes (or subclasses) will be skipped entirely, including all their children.
|
|
86
|
-
* This helps prevent crashes when traversing problematic view hierarchies by allowing you to explicitly exclude problematic view classes.
|
|
87
|
-
*
|
|
88
|
-
* If both `includedViewClasses` and `excludedViewClasses` are set, `excludedViewClasses` takes precedence:
|
|
89
|
-
* views matching excluded classes won't be traversed even if they match an included class.
|
|
90
|
-
*
|
|
91
|
-
* @default undefined
|
|
92
|
-
* @platform ios
|
|
93
|
-
*/
|
|
94
|
-
excludedViewClasses?: string[];
|
|
95
69
|
/**
|
|
96
70
|
* Sets the screenshot strategy used by the Session Replay integration on Android.
|
|
97
71
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SpanAttributeValue } from '@sentry/core';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
export type TouchEventBoundaryProps = {
|
|
3
4
|
/**
|
|
@@ -30,6 +31,13 @@ export type TouchEventBoundaryProps = {
|
|
|
30
31
|
* Label Name used to identify the touched element.
|
|
31
32
|
*/
|
|
32
33
|
labelName?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Custom attributes to add to user interaction spans.
|
|
36
|
+
* Accepts an object with string keys and values that are strings, numbers, booleans, or arrays.
|
|
37
|
+
*
|
|
38
|
+
* @experimental This API is experimental and may change in future releases.
|
|
39
|
+
*/
|
|
40
|
+
spanAttributes?: Record<string, SpanAttributeValue>;
|
|
33
41
|
};
|
|
34
42
|
/**
|
|
35
43
|
* Boundary to log breadcrumbs for interaction events.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react-native" />
|
|
2
2
|
import type { InternalGlobal } from '@sentry/core';
|
|
3
3
|
import type { ErrorUtils } from 'react-native/types';
|
|
4
|
+
import type { ReactNativeOptions } from '../options';
|
|
4
5
|
import type { ExpoGlobalObject } from './expoglobalobject';
|
|
5
6
|
export interface HermesPromiseRejectionTrackingOptions {
|
|
6
7
|
allRejections: boolean;
|
|
@@ -32,6 +33,7 @@ export interface ReactNativeInternalGlobal extends InternalGlobal {
|
|
|
32
33
|
nativePerformanceNow?: () => number;
|
|
33
34
|
TextEncoder?: TextEncoder;
|
|
34
35
|
alert?: (message: string) => void;
|
|
36
|
+
__SENTRY_OPTIONS__?: ReactNativeOptions;
|
|
35
37
|
SENTRY_RELEASE?: {
|
|
36
38
|
/** Used by Sentry Webpack Plugin, not used by RN, only to silence TS */
|
|
37
39
|
id?: string;
|
|
@@ -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 = "
|
|
3
|
+
export declare const SDK_VERSION = "8.0.0-alpha.0";
|
|
4
4
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -60,6 +60,8 @@ interface SentryNativeWrapper {
|
|
|
60
60
|
setExtra(key: string, extra: unknown): void;
|
|
61
61
|
setUser(user: User | null): void;
|
|
62
62
|
setTag(key: string, value?: string): void;
|
|
63
|
+
setAttribute(key: string, value: string | number | boolean): void;
|
|
64
|
+
setAttributes(attributes: Record<string, string | number | boolean>): void;
|
|
63
65
|
nativeCrash(): void;
|
|
64
66
|
fetchModules(): Promise<Record<string, string> | null>;
|
|
65
67
|
fetchViewHierarchy(): PromiseLike<Uint8Array | null>;
|