@sentry/react-native 5.10.0 → 5.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/RNSentry.podspec +1 -1
  3. package/android/build.gradle +8 -1
  4. package/dist/js/client.d.ts.map +1 -1
  5. package/dist/js/client.js +1 -2
  6. package/dist/js/client.js.map +1 -1
  7. package/dist/js/integrations/screenshot.d.ts +4 -2
  8. package/dist/js/integrations/screenshot.d.ts.map +1 -1
  9. package/dist/js/integrations/screenshot.js +16 -2
  10. package/dist/js/integrations/screenshot.js.map +1 -1
  11. package/dist/js/sdk.d.ts +1 -1
  12. package/dist/js/sdk.d.ts.map +1 -1
  13. package/dist/js/sdk.js +0 -2
  14. package/dist/js/sdk.js.map +1 -1
  15. package/dist/js/tools/ModulesCollector.js +1 -1
  16. package/dist/js/tools/ModulesCollector.js.map +1 -1
  17. package/dist/js/tools/sentryMetroSerializer.d.ts +9 -0
  18. package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -0
  19. package/dist/js/tools/sentryMetroSerializer.js +146 -0
  20. package/dist/js/tools/sentryMetroSerializer.js.map +1 -0
  21. package/dist/js/tools/utils.d.ts +43 -0
  22. package/dist/js/tools/utils.d.ts.map +1 -0
  23. package/dist/js/tools/utils.js +39 -0
  24. package/dist/js/tools/utils.js.map +1 -0
  25. package/dist/js/tools/vendor/metro/utils.d.ts +23 -0
  26. package/dist/js/tools/vendor/metro/utils.d.ts.map +1 -0
  27. package/dist/js/tools/vendor/metro/utils.js +50 -0
  28. package/dist/js/tools/vendor/metro/utils.js.map +1 -0
  29. package/dist/js/tracing/reactnativetracing.d.ts +11 -0
  30. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  31. package/dist/js/tracing/reactnativetracing.js +49 -22
  32. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  33. package/dist/js/tracing/transaction.d.ts +5 -1
  34. package/dist/js/tracing/transaction.d.ts.map +1 -1
  35. package/dist/js/tracing/transaction.js +17 -0
  36. package/dist/js/tracing/transaction.js.map +1 -1
  37. package/dist/js/version.d.ts +1 -1
  38. package/dist/js/version.js +1 -1
  39. package/dist/js/version.js.map +1 -1
  40. package/package.json +20 -40
  41. package/scripts/copy-debugid.js +52 -0
  42. package/scripts/has-sourcemap-debugid.js +31 -0
  43. package/scripts/sentry-xcode-debug-files.sh +27 -0
  44. package/scripts/sentry-xcode.sh +32 -0
  45. package/sentry.gradle +130 -69
  46. package/ts3.8/dist/js/integrations/screenshot.d.ts +4 -2
  47. package/ts3.8/dist/js/sdk.d.ts +1 -1
  48. package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +11 -0
  49. package/ts3.8/dist/js/tracing/transaction.d.ts +5 -1
  50. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import { logger } from '@sentry/utils';
2
+ import { AppState } from 'react-native';
2
3
  /**
3
4
  * Idle Transaction callback to only sample transactions with child spans.
4
5
  * To avoid side effects of other callbacks this should be hooked as the last callback.
@@ -11,4 +12,20 @@ export const onlySampleIfChildSpans = (transaction) => {
11
12
  transaction.sampled = false;
12
13
  }
13
14
  };
15
+ /**
16
+ * Hooks on AppState change to cancel the transaction if the app goes background.
17
+ */
18
+ export const cancelInBackground = (transaction) => {
19
+ const subscription = AppState.addEventListener('change', (newState) => {
20
+ if (newState === 'background') {
21
+ logger.debug(`Setting ${transaction.op} transaction to cancelled because the app is in the background.`);
22
+ transaction.setStatus('cancelled');
23
+ transaction.finish();
24
+ }
25
+ });
26
+ transaction.registerBeforeFinishCallback(() => {
27
+ logger.debug(`Removing AppState listener for ${transaction.op} transaction.`);
28
+ subscription.remove();
29
+ });
30
+ };
14
31
  //# sourceMappingURL=transaction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/js/tracing/transaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAyB,CAAC,WAA4B,EAAQ,EAAE;IACjG,MAAM,UAAU,GACd,WAAW,CAAC,YAAY;QACxB,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAE3F,IAAI,CAAC,UAAU,IAAI,UAAU,IAAI,CAAC,EAAE;QAClC,MAAM,CAAC,GAAG,CAAC,mBAAmB,WAAW,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAChF,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;KAC7B;AACH,CAAC,CAAC","sourcesContent":["import type { BeforeFinishCallback, IdleTransaction } from '@sentry/core';\nimport { logger } from '@sentry/utils';\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans: BeforeFinishCallback = (transaction: IdleTransaction): void => {\n const spansCount =\n transaction.spanRecorder &&\n transaction.spanRecorder.spans.filter(span => span.spanId !== transaction.spanId).length;\n\n if (!spansCount || spansCount <= 0) {\n logger.log(`Not sampling as ${transaction.op} transaction has no child spans.`);\n transaction.sampled = false;\n }\n};\n"]}
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/js/tracing/transaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAyB,CAAC,WAA4B,EAAQ,EAAE;IACjG,MAAM,UAAU,GACd,WAAW,CAAC,YAAY;QACxB,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAE3F,IAAI,CAAC,UAAU,IAAI,UAAU,IAAI,CAAC,EAAE;QAClC,MAAM,CAAC,GAAG,CAAC,mBAAmB,WAAW,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAChF,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;KAC7B;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,WAA4B,EAAQ,EAAE;IACvE,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,QAAwB,EAAE,EAAE;QACpF,IAAI,QAAQ,KAAK,YAAY,EAAE;YAC7B,MAAM,CAAC,KAAK,CAAC,WAAW,WAAW,CAAC,EAAE,iEAAiE,CAAC,CAAC;YACzG,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACnC,WAAW,CAAC,MAAM,EAAE,CAAC;SACtB;IACH,CAAC,CAAC,CAAC;IACH,WAAW,CAAC,4BAA4B,CAAC,GAAG,EAAE;QAC5C,MAAM,CAAC,KAAK,CAAC,kCAAkC,WAAW,CAAC,EAAE,eAAe,CAAC,CAAC;QAC9E,YAAY,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { type BeforeFinishCallback, type IdleTransaction } from '@sentry/core';\nimport { logger } from '@sentry/utils';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState } from 'react-native';\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans: BeforeFinishCallback = (transaction: IdleTransaction): void => {\n const spansCount =\n transaction.spanRecorder &&\n transaction.spanRecorder.spans.filter(span => span.spanId !== transaction.spanId).length;\n\n if (!spansCount || spansCount <= 0) {\n logger.log(`Not sampling as ${transaction.op} transaction has no child spans.`);\n transaction.sampled = false;\n }\n};\n\n/**\n * Hooks on AppState change to cancel the transaction if the app goes background.\n */\nexport const cancelInBackground = (transaction: IdleTransaction): void => {\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n logger.debug(`Setting ${transaction.op} transaction to cancelled because the app is in the background.`);\n transaction.setStatus('cancelled');\n transaction.finish();\n }\n });\n transaction.registerBeforeFinishCallback(() => {\n logger.debug(`Removing AppState listener for ${transaction.op} transaction.`);\n subscription.remove();\n });\n};\n"]}
@@ -1,4 +1,4 @@
1
1
  export declare const SDK_PACKAGE_NAME = "npm:@sentry/react-native";
2
2
  export declare const SDK_NAME = "sentry.javascript.react-native";
3
- export declare const SDK_VERSION = "5.10.0";
3
+ export declare const SDK_VERSION = "5.11.1";
4
4
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,4 @@
1
1
  export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';
2
2
  export const SDK_NAME = 'sentry.javascript.react-native';
3
- export const SDK_VERSION = '5.10.0';
3
+ export const SDK_VERSION = '5.11.1';
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '5.10.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '5.11.1';\n"]}
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.10.0",
5
+ "version": "5.11.1",
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",
@@ -24,7 +24,9 @@
24
24
  "build:tools": "tsc -p tsconfig.build.tools.json",
25
25
  "downlevel": "downlevel-dts dist ts3.8/dist --to=3.8",
26
26
  "clean": "rimraf dist coverage",
27
- "test": "jest",
27
+ "test": "yarn test:sdk && yarn test:tools",
28
+ "test:sdk": "jest",
29
+ "test:tools": "jest --config jest.config.tools.js",
28
30
  "fix": "yarn fix:eslint && yarn fix:prettier",
29
31
  "fix:eslint": "eslint --config .eslintrc.js --fix .",
30
32
  "fix:prettier": "prettier --write \"{src,test,scripts}/**/**.ts\"",
@@ -56,22 +58,24 @@
56
58
  "react-native": ">=0.65.0"
57
59
  },
58
60
  "dependencies": {
59
- "@sentry/browser": "7.69.0",
60
- "@sentry/cli": "2.20.7",
61
- "@sentry/core": "7.69.0",
62
- "@sentry/hub": "7.69.0",
63
- "@sentry/integrations": "7.69.0",
64
- "@sentry/react": "7.69.0",
65
- "@sentry/types": "7.69.0",
66
- "@sentry/utils": "7.69.0"
61
+ "@sentry/browser": "7.73.0",
62
+ "@sentry/cli": "2.21.2",
63
+ "@sentry/core": "7.73.0",
64
+ "@sentry/hub": "7.73.0",
65
+ "@sentry/integrations": "7.73.0",
66
+ "@sentry/react": "7.73.0",
67
+ "@sentry/types": "7.73.0",
68
+ "@sentry/utils": "7.73.0"
67
69
  },
68
70
  "devDependencies": {
69
- "@sentry-internal/eslint-config-sdk": "7.69.0",
70
- "@sentry-internal/eslint-plugin-sdk": "7.69.0",
71
+ "@sentry-internal/eslint-config-sdk": "7.73.0",
72
+ "@sentry-internal/eslint-plugin-sdk": "7.73.0",
71
73
  "@sentry/typescript": "^5.20.1",
72
74
  "@sentry/wizard": "3.13.0",
73
75
  "@types/jest": "^29.5.3",
74
76
  "@types/react": "^18.2.14",
77
+ "@types/uglify-js": "^3.17.2",
78
+ "@types/uuid": "^9.0.4",
75
79
  "babel-jest": "^29.6.2",
76
80
  "downlevel-dts": "^0.11.0",
77
81
  "eslint": "^7.6.0",
@@ -79,13 +83,16 @@
79
83
  "eslint-plugin-react-native": "^3.8.1",
80
84
  "jest": "^29.6.2",
81
85
  "jest-environment-jsdom": "^29.6.2",
86
+ "metro": "0.76",
82
87
  "prettier": "^2.0.5",
83
88
  "react": "18.2.0",
84
89
  "react-native": "0.72.4",
85
90
  "replace-in-file": "^7.0.1",
86
91
  "rimraf": "^4.1.1",
87
92
  "ts-jest": "^29.1.1",
88
- "typescript": "4.9.5"
93
+ "typescript": "4.9.5",
94
+ "uglify-js": "^3.17.4",
95
+ "uuid": "^9.0.1"
89
96
  },
90
97
  "rnpm": {
91
98
  "commands": {},
@@ -95,33 +102,6 @@
95
102
  },
96
103
  "ios": {}
97
104
  },
98
- "jest": {
99
- "collectCoverage": true,
100
- "preset": "react-native",
101
- "setupFilesAfterEnv": [
102
- "<rootDir>/test/mockConsole.ts"
103
- ],
104
- "globals": {
105
- "__DEV__": true,
106
- "ts-jest": {
107
- "tsConfig": "./tsconfig.json",
108
- "diagnostics": false
109
- }
110
- },
111
- "moduleFileExtensions": [
112
- "ts",
113
- "tsx",
114
- "js"
115
- ],
116
- "testPathIgnorePatterns": [
117
- "<rootDir>/test/e2e/",
118
- "<rootDir>/test/react-native/versions"
119
- ],
120
- "testEnvironment": "node",
121
- "testMatch": [
122
- "**/*.test.(ts|tsx)"
123
- ]
124
- },
125
105
  "codegenConfig": {
126
106
  "name": "RNSentrySpec",
127
107
  "type": "modules",
@@ -0,0 +1,52 @@
1
+ const process = require('process');
2
+ const fs = require('fs');
3
+
4
+ console.log('Copy `debugId` from packager source map to Hermes source map...');
5
+
6
+ const packagerSourceMapPath = process.argv[2];
7
+ const hermesSourceMapPath = process.argv[3];
8
+
9
+ if (!packagerSourceMapPath) {
10
+ console.log('Please provide packager source map path (A path to copy `debugId` from).');
11
+ process.exit(0);
12
+ }
13
+ if (!hermesSourceMapPath) {
14
+ console.log('Please provide Hermes source map path. ((A path to copy `debugId` to))');
15
+ process.exit(0);
16
+ }
17
+ if (!fs.existsSync(packagerSourceMapPath)) {
18
+ console.log('Packager source map path (A path to copy `debugId` from).');
19
+ process.exit(0);
20
+ }
21
+ if (!fs.existsSync(hermesSourceMapPath)) {
22
+ console.log('Hermes source map not found. ((A path to copy `debugId` to))');
23
+ process.exit(0);
24
+ }
25
+
26
+ const from = fs.readFileSync(process.argv[2], 'utf8');
27
+ const to = fs.readFileSync(process.argv[3], 'utf8');
28
+
29
+ const fromParsed = JSON.parse(from);
30
+ const toParsed = JSON.parse(to);
31
+
32
+ if (!fromParsed.debugId && !fromParsed.debug_id) {
33
+ console.log('Packager source map does not have `debugId`.');
34
+ process.exit(0);
35
+ }
36
+
37
+ if (toParsed.debugId || toParsed.debug_id) {
38
+ console.log('Hermes combined source map already has `debugId`.');
39
+ process.exit(0);
40
+ }
41
+
42
+ if (fromParsed.debugId) {
43
+ toParsed.debugId = fromParsed.debugId;
44
+ toParsed.debug_id = fromParsed.debugId;
45
+ } else if (fromParsed.debug_id) {
46
+ toParsed.debugId = fromParsed.debug_id;
47
+ toParsed.debug_id = fromParsed.debug_id;
48
+ }
49
+
50
+ fs.writeFileSync(process.argv[3], JSON.stringify(toParsed));
51
+
52
+ console.log('Done.');
@@ -0,0 +1,31 @@
1
+ const process = require('process');
2
+ const fs = require('fs');
3
+
4
+ const sourceMapPath = process.argv[2];
5
+
6
+ if (!sourceMapPath) {
7
+ console.log('Add source map path as first argument of the script.');
8
+ process.exit(1);
9
+ }
10
+
11
+ if (!fs.existsSync(sourceMapPath)) {
12
+ console.log(`${sourceMapPath} does not exist.`);
13
+ process.exit(1);
14
+ }
15
+
16
+ let sourceMap;
17
+ try {
18
+ sourceMap = JSON.parse(fs.readFileSync(sourceMapPath, 'utf8'));
19
+ } catch (e) {
20
+ console.log(`Sourcemap at ${sourceMapPath} was unable to be read.`, e);
21
+ process.exist(1);
22
+ }
23
+
24
+ if (typeof sourceMap.debugId === 'string' && sourceMap.debugId.length > 0) {
25
+ console.log(sourceMap.debugId);
26
+ } else if (typeof sourceMap.debug_id === 'string' && sourceMap.debug_id.length > 0) {
27
+ console.log(sourceMap.debug_id);
28
+ } else {
29
+ console.log(`${sourceMapPath} does not contain 'debugId' nor 'debug_id'.`);
30
+ process.exist(1);
31
+ }
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+ # Upload Debug Symbols to Sentry Xcode Build Phase
3
+ # PWD=ios
4
+
5
+ # print commands before executing them and stop on first error
6
+ set -x -e
7
+
8
+ # load envs if loader file exists (since rn 0.68)
9
+ WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
10
+ if [ -f "$WITH_ENVIRONMENT" ]; then
11
+ . "$WITH_ENVIRONMENT"
12
+ fi
13
+
14
+ [ -z "$SENTRY_PROPERTIES" ] && export SENTRY_PROPERTIES=sentry.properties
15
+ [ -z "$SENTRY_CLI_EXECUTABLE" ] && SENTRY_CLI_EXECUTABLE="../node_modules/@sentry/cli/bin/sentry-cli"
16
+
17
+ [[ $SENTRY_INCLUDE_NATIVE_SOURCES == "true" ]] && INCLUDE_SOURCES_FLAG="--include-sources" || INCLUDE_SOURCES_FLAG=""
18
+
19
+ EXTRA_ARGS="$SENTRY_CLI_EXTRA_ARGS $SENTRY_CLI_DEBUG_FILES_UPLOAD_EXTRA_ARGS $INCLUDE_SOURCES_FLAG"
20
+
21
+ UPLOAD_DEBUG_FILES="\"$SENTRY_CLI_EXECUTABLE\" debug-files upload $EXTRA_ARGS \"$DWARF_DSYM_FOLDER_PATH\""
22
+
23
+ if [ "$SENTRY_DISABLE_AUTO_UPLOAD" != true ]; then
24
+ /bin/sh -c "$UPLOAD_DEBUG_FILES"
25
+ else
26
+ echo "SENTRY_DISABLE_AUTO_UPLOAD=true, skipping debug files upload"
27
+ fi
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+ # Sentry Bundle React Native code and images
3
+ # PWD=ios
4
+
5
+ # print commands before executing them and stop on first error
6
+ set -x -e
7
+
8
+ # WITH_ENVIRONMENT is executed by React Native
9
+
10
+ [ -z "$SENTRY_PROPERTIES" ] && export SENTRY_PROPERTIES=sentry.properties
11
+ [ -z "$SOURCEMAP_FILE" ] && export SOURCEMAP_FILE="$DERIVED_FILE_DIR/main.jsbundle.map"
12
+ [ -z "$SENTRY_CLI_EXECUTABLE" ] && SENTRY_CLI_EXECUTABLE="../node_modules/@sentry/cli/bin/sentry-cli"
13
+
14
+ REACT_NATIVE_XCODE=$1
15
+
16
+ [[ "$AUTO_RELEASE" != true ]] && [[ -z "$BUNDLE_COMMAND" || "$BUNDLE_COMMAND" != "ram-bundle" ]] && NO_AUTO_RELEASE="--no-auto-release"
17
+ ARGS="$NO_AUTO_RELEASE $SENTRY_CLI_EXTRA_ARGS $SENTRY_CLI_RN_XCODE_EXTRA_ARGS"
18
+
19
+ REACT_NATIVE_XCODE_WITH_SENTRY="\"$SENTRY_CLI_EXECUTABLE\" react-native xcode $ARGS \"$REACT_NATIVE_XCODE\""
20
+
21
+ if [ "$SENTRY_DISABLE_AUTO_UPLOAD" != true ]; then
22
+ /bin/sh -c "$REACT_NATIVE_XCODE_WITH_SENTRY"
23
+ else
24
+ echo "SENTRY_DISABLE_AUTO_UPLOAD=true, skipping sourcemaps upload"
25
+ /bin/sh -c "$REACT_NATIVE_XCODE"
26
+ fi
27
+
28
+ [ -z "$SENTRY_COLLECT_MODULES" ] && SENTRY_COLLECT_MODULES="../../scripts/collect-modules.sh"
29
+
30
+ if [ -f "$SENTRY_COLLECT_MODULES" ]; then
31
+ /bin/sh "$SENTRY_COLLECT_MODULES"
32
+ fi
package/sentry.gradle CHANGED
@@ -3,6 +3,10 @@ import org.apache.tools.ant.taskdefs.condition.Os
3
3
  import java.util.regex.Matcher
4
4
  import java.util.regex.Pattern
5
5
 
6
+ project.ext.shouldSentryAutoUpload = { ->
7
+ return System.getenv('SENTRY_DISABLE_AUTO_UPLOAD') != 'true'
8
+ }
9
+
6
10
  def config = project.hasProperty("sentryCli") ? project.sentryCli : [];
7
11
 
8
12
  gradle.projectsEvaluated {
@@ -39,6 +43,8 @@ gradle.projectsEvaluated {
39
43
  def shouldCleanUp
40
44
  def sourcemapOutput
41
45
  def bundleOutput
46
+ def packagerSourcemapOutput
47
+ def bundleCommand
42
48
  def props = bundleTask.getProperties()
43
49
  def reactRoot = props.get("workingDir")
44
50
  if (reactRoot == null) {
@@ -47,7 +53,7 @@ gradle.projectsEvaluated {
47
53
  def modulesOutput = "$reactRoot/android/app/src/main/assets/modules.json"
48
54
  def modulesTask = null
49
55
 
50
- (shouldCleanUp, bundleOutput, sourcemapOutput) = forceSourceMapOutputFromBundleTask(bundleTask)
56
+ (shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = forceSourceMapOutputFromBundleTask(bundleTask)
51
57
 
52
58
  // Lets leave this here if we need to debug
53
59
  // println bundleTask.properties
@@ -94,71 +100,109 @@ gradle.projectsEvaluated {
94
100
  try { tasks.named(nameCliTask); return } catch (Exception e) {}
95
101
 
96
102
  /** Upload source map file to the sentry server via CLI call. */
97
- def cliTask = tasks.create(nameCliTask, Exec) {
103
+ def cliTask = tasks.create(nameCliTask) {
104
+ onlyIf { shouldSentryAutoUpload() }
98
105
  description = "upload debug symbols to sentry"
99
106
  group = 'sentry.io'
100
107
 
101
- workingDir reactRoot
102
-
103
- def propertiesFile = config.sentryProperties
104
- ? config.sentryProperties
105
- : "$reactRoot/android/sentry.properties"
106
-
107
- if (config.flavorAware) {
108
- propertiesFile = "$reactRoot/android/sentry-${variant}.properties"
109
- project.logger.info("For $variant using: $propertiesFile")
110
- } else {
111
- environment("SENTRY_PROPERTIES", propertiesFile)
108
+ def extraArgs = []
109
+
110
+ def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
111
+ def copyDebugIdScript = config.copyDebugIdScript
112
+ ? file(config.copyDebugIdScript).getAbsolutePath()
113
+ : "$sentryPackage/scripts/copy-debugid.js"
114
+ def hasSourceMapDebugIdScript = config.hasSourceMapDebugIdScript
115
+ ? file(config.hasSourceMapDebugIdScript).getAbsolutePath()
116
+ : "$sentryPackage/scripts/has-sourcemap-debugid.js"
117
+
118
+ doFirst {
119
+ // Copy Debug ID from packager source map to Hermes composed source map
120
+ exec {
121
+ def args = ["node",
122
+ copyDebugIdScript,
123
+ packagerSourcemapOutput,
124
+ sourcemapOutput]
125
+ def osCompatibilityCopyCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
126
+ commandLine(*osCompatibilityCopyCommand, *args)
127
+ }
128
+
129
+ // Add release and dist for backward compatibility if no Debug ID detected in output soruce map
130
+ def process = ["node", hasSourceMapDebugIdScript, sourcemapOutput].execute(null, new File("$reactRoot"))
131
+ def exitValue = process.waitFor()
132
+ project.logger.lifecycle("Check generated source map for Debug ID: ${process.text}")
133
+ def notIncludeRelease = "$bundleCommand" == "bundle" && exitValue == 0
134
+ def not = notIncludeRelease ? 'not ' : ''
135
+ project.logger.lifecycle("Sentry Source Maps upload will ${not}include the release name and dist.")
136
+ extraArgs.addAll(notIncludeRelease ? [] : [
137
+ "--release", releaseName,
138
+ "--dist", versionCode
139
+ ])
112
140
  }
113
141
 
114
- Properties sentryProps = new Properties()
115
- try {
116
- sentryProps.load(new FileInputStream(propertiesFile))
117
- } catch (FileNotFoundException e) {
118
- project.logger.info("file not found '$propertiesFile' for '$variant'")
142
+ doLast {
143
+ exec {
144
+ workingDir reactRoot
145
+
146
+ def propertiesFile = config.sentryProperties
147
+ ? config.sentryProperties
148
+ : "$reactRoot/android/sentry.properties"
149
+
150
+ if (config.flavorAware) {
151
+ propertiesFile = "$reactRoot/android/sentry-${variant}.properties"
152
+ project.logger.info("For $variant using: $propertiesFile")
153
+ } else {
154
+ environment("SENTRY_PROPERTIES", propertiesFile)
155
+ }
156
+
157
+ Properties sentryProps = new Properties()
158
+ try {
159
+ sentryProps.load(new FileInputStream(propertiesFile))
160
+ } catch (FileNotFoundException e) {
161
+ project.logger.info("file not found '$propertiesFile' for '$variant'")
162
+ }
163
+
164
+ def resolvedCliPackage = null
165
+ try {
166
+ resolvedCliPackage = new File(["node", "--print", "require.resolve('@sentry/cli/package.json')"].execute(null, rootDir).text.trim()).getParentFile();
167
+ } catch (Throwable ignored) {}
168
+ def cliPackage = resolvedCliPackage != null && resolvedCliPackage.exists() ? resolvedCliPackage.getAbsolutePath() : "$reactRoot/node_modules/@sentry/cli"
169
+ def cliExecutable = sentryProps.get("cli.executable", "$cliPackage/bin/sentry-cli")
170
+
171
+ // fix path separator for Windows
172
+ if (Os.isFamily(Os.FAMILY_WINDOWS)) {
173
+ cliExecutable = cliExecutable.replaceAll("/", "\\\\")
174
+ }
175
+
176
+ //
177
+ // based on:
178
+ // https://github.com/getsentry/sentry-cli/blob/master/src/commands/react_native_gradle.rs
179
+ //
180
+ def args = [cliExecutable]
181
+
182
+ args.addAll(!config.logLevel ? [] : [
183
+ "--log-level", config.logLevel // control verbosity of the output
184
+ ])
185
+ args.addAll(!config.flavorAware ? [] : [
186
+ "--url", sentryProps.get("defaults.url"),
187
+ "--auth-token", sentryProps.get("auth.token")
188
+ ])
189
+ args.addAll(["react-native", "gradle",
190
+ "--bundle", bundleOutput, // The path to a bundle that should be uploaded.
191
+ "--sourcemap", sourcemapOutput // The path to a sourcemap that should be uploaded.
192
+ ])
193
+ args.addAll(!config.flavorAware ? [] : [
194
+ "--org", sentryProps.get("defaults.org"),
195
+ "--project", sentryProps.get("defaults.project")
196
+ ])
197
+
198
+ args.addAll(extraArgs)
199
+
200
+ project.logger.lifecycle("Sentry-CLI arguments: ${args}")
201
+ def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'node'] : []
202
+ commandLine(*osCompatibility, *args)
203
+ }
119
204
  }
120
205
 
121
- def resolvedCliPackage = null
122
- try {
123
- resolvedCliPackage = new File(["node", "--print", "require.resolve('@sentry/cli/package.json')"].execute(null, rootDir).text.trim()).getParentFile();
124
- } catch (Throwable ignored) {}
125
- def cliPackage = resolvedCliPackage != null && resolvedCliPackage.exists() ? resolvedCliPackage.getAbsolutePath() : "$reactRoot/node_modules/@sentry/cli"
126
- def cliExecutable = sentryProps.get("cli.executable", "$cliPackage/bin/sentry-cli")
127
-
128
- // fix path separator for Windows
129
- if (Os.isFamily(Os.FAMILY_WINDOWS)) {
130
- cliExecutable = cliExecutable.replaceAll("/", "\\\\")
131
- }
132
-
133
- //
134
- // based on:
135
- // https://github.com/getsentry/sentry-cli/blob/master/src/commands/react_native_gradle.rs
136
- //
137
- def args = [cliExecutable]
138
-
139
- args.addAll(!config.logLevel ? [] : [
140
- "--log-level", config.logLevel // control verbosity of the output
141
- ])
142
- args.addAll(!config.flavorAware ? [] : [
143
- "--url", sentryProps.get("defaults.url"),
144
- "--auth-token", sentryProps.get("auth.token")
145
- ])
146
- args.addAll(["react-native", "gradle",
147
- "--bundle", bundleOutput, // The path to a bundle that should be uploaded.
148
- "--sourcemap", sourcemapOutput, // The path to a sourcemap that should be uploaded.
149
- "--release", releaseName, // The name of the release to publish.
150
- "--dist", versionCode
151
- ])
152
- args.addAll(!config.flavorAware ? [] : [
153
- "--org", sentryProps.get("defaults.org"),
154
- "--project", sentryProps.get("defaults.project")
155
- ])
156
-
157
- project.logger.info("Sentry-CLI arguments: ${args}")
158
-
159
- def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'node'] : []
160
- commandLine(*osCompatibility, *args)
161
-
162
206
  enabled true
163
207
  }
164
208
 
@@ -168,11 +212,7 @@ gradle.projectsEvaluated {
168
212
 
169
213
  workingDir reactRoot
170
214
 
171
- def resolvedSentryPath = null
172
- try {
173
- resolvedSentryPath = new File(["node", "--print", "require.resolve('@sentry/react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile();
174
- } catch (Throwable ignored) {} // if the resolve fails we fallback to the default path
175
- def sentryPackage = resolvedSentryPath != null && resolvedSentryPath.exists() ? resolvedSentryPath.getAbsolutePath() : "$reactRoot/node_modules/@sentry/react-native"
215
+ def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
176
216
 
177
217
  def collectModulesScript = config.collectModulesScript
178
218
  ? file(config.collectModulesScript).getAbsolutePath()
@@ -248,6 +288,15 @@ gradle.projectsEvaluated {
248
288
  }
249
289
  }
250
290
 
291
+ def resolveSentryReactNativeSDKPath(reactRoot) {
292
+ def resolvedSentryPath = null
293
+ try {
294
+ resolvedSentryPath = new File(["node", "--print", "require.resolve('@sentry/react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile();
295
+ } catch (Throwable ignored) {} // if the resolve fails we fallback to the default path
296
+ def sentryPackage = resolvedSentryPath != null && resolvedSentryPath.exists() ? resolvedSentryPath.getAbsolutePath() : "$reactRoot/node_modules/@sentry/react-native"
297
+ return sentryPackage
298
+ }
299
+
251
300
  /** Compose lookup map of build variants - to - outputs. */
252
301
  def extractReleasesInfo() {
253
302
  def releases = [:]
@@ -275,6 +324,8 @@ def extractReleasesInfo() {
275
324
  static extractBundleTaskArgumentsLegacy(cmdArgs, Project project) {
276
325
  def bundleOutput = null
277
326
  def sourcemapOutput = null
327
+ def packagerSourcemapOutput = null
328
+ // packagerBundleOutput doesn't exist, because packager output is overwritten by Hermes
278
329
 
279
330
  cmdArgs.eachWithIndex { String arg, int i ->
280
331
  if (arg == "--bundle-output") {
@@ -282,6 +333,7 @@ static extractBundleTaskArgumentsLegacy(cmdArgs, Project project) {
282
333
  project.logger.info("--bundle-output: `${bundleOutput}`")
283
334
  } else if (arg == "--sourcemap-output") {
284
335
  sourcemapOutput = cmdArgs[i + 1]
336
+ packagerSourcemapOutput = sourcemapOutput
285
337
  project.logger.info("--sourcemap-output param: `${sourcemapOutput}`")
286
338
  }
287
339
  }
@@ -313,7 +365,11 @@ static extractBundleTaskArgumentsLegacy(cmdArgs, Project project) {
313
365
  }
314
366
  }
315
367
 
316
- return [bundleOutput, sourcemapOutput]
368
+ // get the current bundle command, if not peresent use default plain "bundle"
369
+ // we use this later to decide how to upload source maps
370
+ def bundleCommand = project.ext.react.get("bundleCommand", "bundle")
371
+
372
+ return [bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand]
317
373
  }
318
374
 
319
375
  /** Extract bundle and sourcemap paths from bundle task props.
@@ -328,12 +384,15 @@ static extractBundleTaskArgumentsRN71AndAbove(bundleTask, logger) {
328
384
  return [null, null]
329
385
  }
330
386
 
387
+ def bundleCommand = props.bundleCommand.get()
331
388
  def bundleFile = new File(props.jsBundleDir.get().asFile.absolutePath, bundleAssetName)
332
389
  def outputSourceMap = new File(props.jsSourceMapsDir.get().asFile.absolutePath, "${bundleAssetName}.map")
390
+ def packagerOutputSourceMap = new File(props.jsIntermediateSourceMapsDir.get().asFile.absolutePath, "${bundleAssetName}.packager.map")
333
391
 
334
392
  logger.info("bundleFile: `${bundleFile}`")
335
393
  logger.info("outputSourceMap: `${outputSourceMap}`")
336
- return [bundleFile, outputSourceMap]
394
+ logger.info("packagerOutputSourceMap: `${packagerOutputSourceMap}`")
395
+ return [bundleFile, outputSourceMap, packagerOutputSourceMap, bundleCommand]
337
396
  }
338
397
 
339
398
  /** Force Bundle task to produce sourcemap files if they are not pre-configured by user yet. */
@@ -344,10 +403,12 @@ def forceSourceMapOutputFromBundleTask(bundleTask) {
344
403
  def shouldCleanUp = false
345
404
  def bundleOutput = null
346
405
  def sourcemapOutput = null
406
+ def packagerSourcemapOutput = null
407
+ def bundleCommand = null
347
408
 
348
- (bundleOutput, sourcemapOutput) = extractBundleTaskArgumentsRN71AndAbove(bundleTask, logger)
409
+ (bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = extractBundleTaskArgumentsRN71AndAbove(bundleTask, logger)
349
410
  if (bundleOutput == null) {
350
- (bundleOutput, sourcemapOutput) = extractBundleTaskArgumentsLegacy(cmdArgs, project)
411
+ (bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = extractBundleTaskArgumentsLegacy(cmdArgs, project)
351
412
  }
352
413
 
353
414
  if (sourcemapOutput == null) {
@@ -366,7 +427,7 @@ def forceSourceMapOutputFromBundleTask(bundleTask) {
366
427
  project.logger.info("Info: used pre-configured source map files: ${sourcemapOutput}")
367
428
  }
368
429
 
369
- return [shouldCleanUp, bundleOutput, sourcemapOutput]
430
+ return [shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand]
370
431
  }
371
432
 
372
433
  /** compose array with one item - current build flavor name */
@@ -1,4 +1,4 @@
1
- import type { EventHint, Integration } from '@sentry/types';
1
+ import type { EventHint, EventProcessor, Integration } from '@sentry/types';
2
2
  /** Adds screenshots to error events */
3
3
  export declare class Screenshot implements Integration {
4
4
  /**
@@ -11,6 +11,8 @@ export declare class Screenshot implements Integration {
11
11
  name: string;
12
12
  /**
13
13
  * If enabled attaches a screenshot to the event hint.
14
+ *
15
+ * @deprecated Screenshots are now added in global event processor.
14
16
  */
15
17
  static attachScreenshotToEventHint(hint: EventHint, { attachScreenshot }: {
16
18
  attachScreenshot?: boolean;
@@ -18,6 +20,6 @@ export declare class Screenshot implements Integration {
18
20
  /**
19
21
  * @inheritDoc
20
22
  */
21
- setupOnce(): void;
23
+ setupOnce(addGlobalEventProcessor: (e: EventProcessor) => void): void;
22
24
  }
23
25
  //# sourceMappingURL=screenshot.d.ts.map
@@ -10,7 +10,7 @@ export declare function init(passedOptions: ReactNativeOptions): void;
10
10
  /**
11
11
  * Inits the Sentry React Native SDK with automatic instrumentation and wrapped features.
12
12
  */
13
- export declare function wrap<P extends JSX.IntrinsicAttributes>(RootComponent: React.ComponentType<P>, options?: ReactNativeWrapperOptions): React.ComponentType<P>;
13
+ export declare function wrap<P extends Record<string, unknown>>(RootComponent: React.ComponentType<P>, options?: ReactNativeWrapperOptions): React.ComponentType<P>;
14
14
  /**
15
15
  * Deprecated. Sets the release on the event.
16
16
  * NOTE: Does not set the release on sessions.