@sentry/wizard 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +19 -19
  3. package/dist/e2e-tests/tests/angular-17.test.d.ts +1 -0
  4. package/dist/e2e-tests/tests/angular-17.test.js +196 -0
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -0
  6. package/dist/e2e-tests/tests/angular-19.test.d.ts +1 -0
  7. package/dist/e2e-tests/tests/angular-19.test.js +194 -0
  8. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -0
  9. package/dist/e2e-tests/tests/expo.test.d.ts +1 -0
  10. package/dist/e2e-tests/tests/expo.test.js +103 -0
  11. package/dist/e2e-tests/tests/expo.test.js.map +1 -0
  12. package/dist/e2e-tests/tests/help-message.test.js +2 -2
  13. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/react-native.test.d.ts +1 -0
  15. package/dist/e2e-tests/tests/react-native.test.js +132 -0
  16. package/dist/e2e-tests/tests/react-native.test.js.map +1 -0
  17. package/dist/e2e-tests/tests/remix.test.js +4 -4
  18. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  19. package/dist/e2e-tests/tests/sveltekit.test.js +2 -2
  20. package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
  21. package/dist/e2e-tests/utils/index.d.ts +7 -0
  22. package/dist/e2e-tests/utils/index.js +32 -7
  23. package/dist/e2e-tests/utils/index.js.map +1 -1
  24. package/dist/lib/Constants.d.ts +1 -0
  25. package/dist/lib/Constants.js +3 -0
  26. package/dist/lib/Constants.js.map +1 -1
  27. package/dist/lib/Helper/SentryCli.d.ts +0 -11
  28. package/dist/lib/Helper/SentryCli.js +0 -52
  29. package/dist/lib/Helper/SentryCli.js.map +1 -1
  30. package/dist/src/android/templates.js +2 -0
  31. package/dist/src/android/templates.js.map +1 -1
  32. package/dist/src/angular/angular-wizard.d.ts +3 -0
  33. package/dist/src/angular/angular-wizard.js +186 -0
  34. package/dist/src/angular/angular-wizard.js.map +1 -0
  35. package/dist/src/angular/codemods/app-config.d.ts +3 -0
  36. package/dist/src/angular/codemods/app-config.js +211 -0
  37. package/dist/src/angular/codemods/app-config.js.map +1 -0
  38. package/dist/src/angular/codemods/main.d.ts +20 -0
  39. package/dist/src/angular/codemods/main.js +62 -0
  40. package/dist/src/angular/codemods/main.js.map +1 -0
  41. package/dist/src/angular/codemods/sourcemaps.d.ts +21 -0
  42. package/dist/src/angular/codemods/sourcemaps.js +94 -0
  43. package/dist/src/angular/codemods/sourcemaps.js.map +1 -0
  44. package/dist/src/angular/example-component.d.ts +8 -0
  45. package/dist/src/angular/example-component.js +286 -0
  46. package/dist/src/angular/example-component.js.map +1 -0
  47. package/dist/src/angular/sdk-setup.d.ts +6 -0
  48. package/dist/src/angular/sdk-setup.js +99 -0
  49. package/dist/src/angular/sdk-setup.js.map +1 -0
  50. package/dist/src/apple/code-tools.d.ts +4 -2
  51. package/dist/src/apple/code-tools.js +21 -11
  52. package/dist/src/apple/code-tools.js.map +1 -1
  53. package/dist/src/apple/inject-code-snippet.js +5 -3
  54. package/dist/src/apple/inject-code-snippet.js.map +1 -1
  55. package/dist/src/apple/macos-system-helper.d.ts +5 -0
  56. package/dist/src/apple/macos-system-helper.js +86 -0
  57. package/dist/src/apple/macos-system-helper.js.map +1 -0
  58. package/dist/src/apple/templates.js +10 -0
  59. package/dist/src/apple/templates.js.map +1 -1
  60. package/dist/src/apple/xcode-manager.d.ts +237 -11
  61. package/dist/src/apple/xcode-manager.js +736 -65
  62. package/dist/src/apple/xcode-manager.js.map +1 -1
  63. package/dist/src/apple/xcode-project-object-with-id.d.ts +5 -0
  64. package/dist/src/apple/xcode-project-object-with-id.js +3 -0
  65. package/dist/src/apple/xcode-project-object-with-id.js.map +1 -0
  66. package/dist/src/flutter/flutter-wizard.js +10 -2
  67. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  68. package/dist/src/flutter/templates.js +7 -1
  69. package/dist/src/flutter/templates.js.map +1 -1
  70. package/dist/src/nextjs/nextjs-wizard.js +27 -15
  71. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  72. package/dist/src/nextjs/templates.js +56 -7
  73. package/dist/src/nextjs/templates.js.map +1 -1
  74. package/dist/src/nuxt/nuxt-wizard.js +1 -3
  75. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  76. package/dist/src/nuxt/templates.js +30 -0
  77. package/dist/src/nuxt/templates.js.map +1 -1
  78. package/dist/src/react-native/expo-env-file.js +5 -0
  79. package/dist/src/react-native/expo-env-file.js.map +1 -1
  80. package/dist/src/react-native/expo-metro.js +22 -6
  81. package/dist/src/react-native/expo-metro.js.map +1 -1
  82. package/dist/src/react-native/expo.js +11 -1
  83. package/dist/src/react-native/expo.js.map +1 -1
  84. package/dist/src/react-native/glob.js +14 -4
  85. package/dist/src/react-native/glob.js.map +1 -1
  86. package/dist/src/react-native/gradle.js +14 -4
  87. package/dist/src/react-native/gradle.js.map +1 -1
  88. package/dist/src/react-native/javascript.d.ts +9 -4
  89. package/dist/src/react-native/javascript.js +52 -23
  90. package/dist/src/react-native/javascript.js.map +1 -1
  91. package/dist/src/react-native/metro.d.ts +1 -1
  92. package/dist/src/react-native/metro.js +36 -4
  93. package/dist/src/react-native/metro.js.map +1 -1
  94. package/dist/src/react-native/react-native-wizard.d.ts +4 -0
  95. package/dist/src/react-native/react-native-wizard.js +32 -4
  96. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  97. package/dist/src/react-native/xcode.js +29 -10
  98. package/dist/src/react-native/xcode.js.map +1 -1
  99. package/dist/src/remix/remix-wizard.js +1 -3
  100. package/dist/src/remix/remix-wizard.js.map +1 -1
  101. package/dist/src/remix/sdk-example.js +30 -1
  102. package/dist/src/remix/sdk-example.js.map +1 -1
  103. package/dist/src/remix/sdk-setup.js +11 -5
  104. package/dist/src/remix/sdk-setup.js.map +1 -1
  105. package/dist/src/run.d.ts +1 -1
  106. package/dist/src/run.js +5 -0
  107. package/dist/src/run.js.map +1 -1
  108. package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +1 -1
  109. package/dist/src/sourcemaps/sourcemaps-wizard.js +35 -20
  110. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  111. package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
  112. package/dist/src/sourcemaps/tools/angular.js +7 -7
  113. package/dist/src/sourcemaps/tools/angular.js.map +1 -1
  114. package/dist/src/sourcemaps/tools/sentry-cli.d.ts +5 -1
  115. package/dist/src/sourcemaps/tools/sentry-cli.js +6 -3
  116. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  117. package/dist/src/sourcemaps/tools/tsc.js +5 -1
  118. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  119. package/dist/src/sourcemaps/tools/vite.js +4 -1
  120. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  121. package/dist/src/sourcemaps/tools/webpack.js +4 -1
  122. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  123. package/dist/src/sveltekit/sdk-example.js +1 -1
  124. package/dist/src/sveltekit/sdk-example.js.map +1 -1
  125. package/dist/src/sveltekit/sveltekit-wizard.js +3 -5
  126. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  127. package/dist/src/sveltekit/templates.js +28 -1
  128. package/dist/src/sveltekit/templates.js.map +1 -1
  129. package/dist/src/utils/clack/index.d.ts +13 -15
  130. package/dist/src/utils/clack/index.js +17 -50
  131. package/dist/src/utils/clack/index.js.map +1 -1
  132. package/dist/src/utils/git.d.ts +11 -0
  133. package/dist/src/utils/git.js +69 -0
  134. package/dist/src/utils/git.js.map +1 -0
  135. package/dist/src/utils/sentrycli-utils.js +13 -4
  136. package/dist/src/utils/sentrycli-utils.js.map +1 -1
  137. package/dist/src/version.d.ts +1 -1
  138. package/dist/src/version.js +1 -1
  139. package/dist/src/version.js.map +1 -1
  140. package/dist/test/angular/angular-wizard.test.d.ts +1 -0
  141. package/dist/test/angular/angular-wizard.test.js +27 -0
  142. package/dist/test/angular/angular-wizard.test.js.map +1 -0
  143. package/dist/test/angular/codemods/sourcemaps.test.d.ts +1 -0
  144. package/dist/test/angular/codemods/sourcemaps.test.js +237 -0
  145. package/dist/test/angular/codemods/sourcemaps.test.js.map +1 -0
  146. package/dist/test/angular/example-component.test.d.ts +1 -0
  147. package/dist/test/angular/example-component.test.js +105 -0
  148. package/dist/test/angular/example-component.test.js.map +1 -0
  149. package/dist/test/apple/code-tools.test.js +54 -35
  150. package/dist/test/apple/code-tools.test.js.map +1 -1
  151. package/dist/test/apple/configure-sentry-cli.test.d.ts +1 -0
  152. package/dist/test/apple/configure-sentry-cli.test.js +131 -0
  153. package/dist/test/apple/configure-sentry-cli.test.js.map +1 -0
  154. package/dist/test/apple/macos-system-helper-mocked.test.d.ts +1 -0
  155. package/dist/test/apple/macos-system-helper-mocked.test.js +46 -0
  156. package/dist/test/apple/macos-system-helper-mocked.test.js.map +1 -0
  157. package/dist/test/apple/macos-system-helper.test.d.ts +1 -0
  158. package/dist/test/apple/macos-system-helper.test.js +88 -0
  159. package/dist/test/apple/macos-system-helper.test.js.map +1 -0
  160. package/dist/test/apple/templates.test.js +10 -0
  161. package/dist/test/apple/templates.test.js.map +1 -1
  162. package/dist/test/apple/xcode-manager.test.js +745 -379
  163. package/dist/test/apple/xcode-manager.test.js.map +1 -1
  164. package/dist/test/flutter/templates.test.js +9 -0
  165. package/dist/test/flutter/templates.test.js.map +1 -1
  166. package/dist/test/react-native/javascript.test.js +119 -0
  167. package/dist/test/react-native/javascript.test.js.map +1 -1
  168. package/dist/test/react-native/metro.test.js +113 -0
  169. package/dist/test/react-native/metro.test.js.map +1 -1
  170. package/dist/test/remix/client-entry.test.js +10 -10
  171. package/dist/test/remix/client-entry.test.js.map +1 -1
  172. package/dist/test/utils/git.test.d.ts +1 -0
  173. package/dist/test/utils/git.test.js +70 -0
  174. package/dist/test/utils/git.test.js.map +1 -0
  175. package/package.json +1 -1
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.doesContainSentryWrap = exports.replaceDefaultExport = exports.wrapWithSentry = exports.getDefaultExport = exports.checkAndWrapRootComponent = exports.SentryWrapResult = exports.wrapRootComponent = exports.getSentryInitPlainTextSnippet = exports.getSentryInitColoredCodeSnippet = exports.doesJsCodeIncludeSdkSentryImport = exports.addSentryInitWithSdkImport = exports.addSentryInit = void 0;
29
+ exports.doesContainSentryWrap = exports.replaceDefaultExport = exports.wrapWithSentry = exports.getDefaultExport = exports.checkAndWrapRootComponent = exports.SentryWrapResult = exports.wrapRootComponent = exports.getSentryIntegrationsPlainTextSnippet = exports.getSentryInitPlainTextSnippet = exports.getSentryInitColoredCodeSnippet = exports.doesJsCodeIncludeSdkSentryImport = exports.addSentryInitWithSdkImport = exports.addSentryInit = exports.sessionReplayOnErrorSampleRate = exports.sessionReplaySampleRate = void 0;
30
30
  /* eslint-disable max-lines */
31
31
  // @ts-expect-error - clack is ESM and TS complains about that. It works though
32
32
  const prompts_1 = __importDefault(require("@clack/prompts"));
@@ -42,14 +42,19 @@ const react_native_wizard_1 = require("./react-native-wizard");
42
42
  // @ts-expect-error - magicast is ESM and TS complains about that. It works though
43
43
  const magicast_1 = require("magicast");
44
44
  const t = __importStar(require("@babel/types"));
45
- const sessionReplaySampleRate = 0.1;
46
- const sessionReplayOnErrorSampleRate = 1.0;
47
- async function addSentryInit({ dsn, enableSessionReplay = false, }) {
45
+ exports.sessionReplaySampleRate = 0.1;
46
+ exports.sessionReplayOnErrorSampleRate = 1.0;
47
+ async function addSentryInit({ dsn, enableSessionReplay = false, enableFeedbackWidget = false, }) {
48
48
  const jsPath = getMainAppFilePath();
49
49
  Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');
50
50
  if (!jsPath) {
51
51
  prompts_1.default.log.warn(`Could not find main App file. Place the following code snippet close to the Apps Root component.`);
52
- await (0, clack_1.showCopyPasteInstructions)('App.js or _layout.tsx', getSentryInitColoredCodeSnippet(dsn, enableSessionReplay), 'This ensures the Sentry SDK is ready to capture errors.');
52
+ Sentry.captureException('Could not find main App file.');
53
+ await (0, clack_1.showCopyPasteInstructions)({
54
+ filename: 'App.js or _layout.tsx',
55
+ codeSnippet: getSentryInitColoredCodeSnippet(dsn, enableSessionReplay, enableFeedbackWidget),
56
+ hint: 'This ensures the Sentry SDK is ready to capture errors.',
57
+ });
53
58
  return;
54
59
  }
55
60
  const jsRelativePath = path.relative(process.cwd(), jsPath);
@@ -62,55 +67,69 @@ async function addSentryInit({ dsn, enableSessionReplay = false, }) {
62
67
  prompts_1.default.log.warn(`${chalk_1.default.cyan(jsRelativePath)} already includes Sentry. We wont't add it again.`);
63
68
  return;
64
69
  }
65
- if (enableSessionReplay) {
66
- prompts_1.default.log.info(`Session Replay will be enabled with default settings (replaysSessionSampleRate: ${sessionReplaySampleRate}, replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate}).`);
67
- prompts_1.default.log.message('By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.');
68
- }
69
70
  (0, telemetry_1.traceStep)('add-sentry-init', () => {
70
71
  const newContent = addSentryInitWithSdkImport(js, {
71
72
  dsn,
72
73
  enableSessionReplay,
74
+ enableFeedbackWidget,
73
75
  });
74
- prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.init')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
75
- fs.writeFileSync(jsPath, newContent, 'utf-8');
76
+ try {
77
+ fs.writeFileSync(jsPath, newContent, 'utf-8');
78
+ prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.init')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
79
+ }
80
+ catch (error) {
81
+ prompts_1.default.log.error(`Error while writing ${jsPath}`);
82
+ Sentry.captureException('Error while writing app.js');
83
+ }
76
84
  });
77
85
  Sentry.setTag('app-js-file-status', 'added-sentry-init');
78
86
  prompts_1.default.log.success(chalk_1.default.green(`${chalk_1.default.cyan(jsRelativePath)} changes saved.`));
79
87
  }
80
88
  exports.addSentryInit = addSentryInit;
81
- function addSentryInitWithSdkImport(js, { dsn, enableSessionReplay = false, }) {
89
+ function addSentryInitWithSdkImport(js, { dsn, enableSessionReplay = false, enableFeedbackWidget = false, }) {
82
90
  return js.replace(/^([^]*)(import\s+[^;]*?;$)/m, (match) => `${match}
83
- ${getSentryInitPlainTextSnippet(dsn, enableSessionReplay)}`);
91
+ ${getSentryInitPlainTextSnippet(dsn, enableSessionReplay, enableFeedbackWidget)}`);
84
92
  }
85
93
  exports.addSentryInitWithSdkImport = addSentryInitWithSdkImport;
86
94
  function doesJsCodeIncludeSdkSentryImport(js, { sdkPackageName }) {
87
95
  return !!js.match(sdkPackageName);
88
96
  }
89
97
  exports.doesJsCodeIncludeSdkSentryImport = doesJsCodeIncludeSdkSentryImport;
90
- function getSentryInitColoredCodeSnippet(dsn, enableSessionReplay = false) {
98
+ function getSentryInitColoredCodeSnippet(dsn, enableSessionReplay = false, enableFeedbackWidget = false) {
91
99
  return (0, clack_1.makeCodeSnippet)(true, (_unchanged, plus, _minus) => {
92
- return plus(getSentryInitPlainTextSnippet(dsn, enableSessionReplay));
100
+ return plus(getSentryInitPlainTextSnippet(dsn, enableSessionReplay, enableFeedbackWidget));
93
101
  });
94
102
  }
95
103
  exports.getSentryInitColoredCodeSnippet = getSentryInitColoredCodeSnippet;
96
- function getSentryInitPlainTextSnippet(dsn, enableSessionReplay = false) {
104
+ function getSentryInitPlainTextSnippet(dsn, enableSessionReplay = false, enableFeedbackWidget = false) {
97
105
  return `import * as Sentry from '@sentry/react-native';
98
106
 
99
107
  Sentry.init({
100
108
  dsn: '${dsn}',
109
+
110
+ // Adds more context data to events (IP address, cookies, user, etc.)
111
+ // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
112
+ sendDefaultPii: true,
101
113
  ${enableSessionReplay
102
114
  ? `
103
115
  // Configure Session Replay
104
- replaysSessionSampleRate: ${sessionReplaySampleRate},
105
- replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate},
106
- integrations: [Sentry.mobileReplayIntegration()],
116
+ replaysSessionSampleRate: ${exports.sessionReplaySampleRate},
117
+ replaysOnErrorSampleRate: ${exports.sessionReplayOnErrorSampleRate},
107
118
  `
108
- : ''}
119
+ : ''}${getSentryIntegrationsPlainTextSnippet(enableSessionReplay, enableFeedbackWidget)}
109
120
  // uncomment the line below to enable Spotlight (https://spotlightjs.com)
110
121
  // spotlight: __DEV__,
111
122
  });`;
112
123
  }
113
124
  exports.getSentryInitPlainTextSnippet = getSentryInitPlainTextSnippet;
125
+ function getSentryIntegrationsPlainTextSnippet(enableSessionReplay = false, enableFeedbackWidget = false) {
126
+ if (!enableSessionReplay && !enableFeedbackWidget) {
127
+ return '';
128
+ }
129
+ return ` integrations: [${enableSessionReplay ? 'Sentry.mobileReplayIntegration()' : ''}${enableSessionReplay && enableFeedbackWidget ? ', ' : ''}${enableFeedbackWidget ? 'Sentry.feedbackIntegration()' : ''}],
130
+ `;
131
+ }
132
+ exports.getSentryIntegrationsPlainTextSnippet = getSentryIntegrationsPlainTextSnippet;
114
133
  function getMainAppFilePath() {
115
134
  const prefixGlob = '{.,./src,./app}';
116
135
  const suffixGlob = '@(j|t|cj|mj)s?(x)';
@@ -123,7 +142,10 @@ function getMainAppFilePath() {
123
142
  * This step should be executed after `addSentryInit`
124
143
  */
125
144
  async function wrapRootComponent() {
126
- const showInstructions = () => (0, clack_1.showCopyPasteInstructions)('App.js or _layout.tsx', getSentryWrapColoredCodeSnippet());
145
+ const showInstructions = () => (0, clack_1.showCopyPasteInstructions)({
146
+ filename: 'App.js or _layout.tsx',
147
+ codeSnippet: getSentryWrapColoredCodeSnippet(),
148
+ });
127
149
  const jsPath = getMainAppFilePath();
128
150
  Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');
129
151
  if (!jsPath) {
@@ -146,8 +168,15 @@ async function wrapRootComponent() {
146
168
  return;
147
169
  }
148
170
  (0, telemetry_1.traceStep)('add-sentry-wrap', () => {
149
- prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.wrap')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
150
- fs.writeFileSync(jsPath, (0, magicast_1.generateCode)(mod.$ast).code, 'utf-8');
171
+ try {
172
+ fs.writeFileSync(jsPath, (0, magicast_1.generateCode)(mod.$ast).code, 'utf-8');
173
+ prompts_1.default.log.success(`Added ${chalk_1.default.cyan('Sentry.wrap')} to ${chalk_1.default.cyan(jsRelativePath)}.`);
174
+ }
175
+ catch (error) {
176
+ prompts_1.default.log.error(`Error while writing ${jsPath}`);
177
+ Sentry.captureException('Error while writing app.js');
178
+ return;
179
+ }
151
180
  });
152
181
  Sentry.setTag('app-js-file-status', 'added-sentry-wrap');
153
182
  prompts_1.default.log.success(chalk_1.default.green(`${chalk_1.default.cyan(jsRelativePath)} changes saved.`));
@@ -1 +1 @@
1
- {"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/react-native/javascript.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport { traceStep } from '../telemetry';\nimport { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, ProxifiedModule, parseModule } from 'magicast';\nimport * as t from '@babel/types';\n\nconst sessionReplaySampleRate = 0.1;\nconst sessionReplayOnErrorSampleRate = 1.0;\n\nexport async function addSentryInit({\n dsn,\n enableSessionReplay = false,\n}: {\n dsn: string;\n enableSessionReplay?: boolean;\n}) {\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Place the following code snippet close to the Apps Root component.`,\n );\n await showCopyPasteInstructions(\n 'App.js or _layout.tsx',\n getSentryInitColoredCodeSnippet(dsn, enableSessionReplay),\n 'This ensures the Sentry SDK is ready to capture errors.',\n );\n return;\n }\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n const includesSentry = doesJsCodeIncludeSdkSentryImport(js, {\n sdkPackageName: RN_SDK_PACKAGE,\n });\n if (includesSentry) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry. We wont't add it again.`,\n );\n return;\n }\n\n if (enableSessionReplay) {\n clack.log.info(\n `Session Replay will be enabled with default settings (replaysSessionSampleRate: ${sessionReplaySampleRate}, replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate}).`,\n );\n clack.log.message(\n 'By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.',\n );\n }\n\n traceStep('add-sentry-init', () => {\n const newContent = addSentryInitWithSdkImport(js, {\n dsn,\n enableSessionReplay,\n });\n\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-init');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport function addSentryInitWithSdkImport(\n js: string,\n {\n dsn,\n enableSessionReplay = false,\n }: { dsn: string; enableSessionReplay?: boolean },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(dsn, enableSessionReplay)}`,\n );\n}\n\nexport function doesJsCodeIncludeSdkSentryImport(\n js: string,\n { sdkPackageName }: { sdkPackageName: string },\n): boolean {\n return !!js.match(sdkPackageName);\n}\n\nexport function getSentryInitColoredCodeSnippet(\n dsn: string,\n enableSessionReplay = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(getSentryInitPlainTextSnippet(dsn, enableSessionReplay));\n });\n}\n\nexport function getSentryInitPlainTextSnippet(\n dsn: string,\n enableSessionReplay = false,\n) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n${\n enableSessionReplay\n ? `\n // Configure Session Replay\n replaysSessionSampleRate: ${sessionReplaySampleRate},\n replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate},\n integrations: [Sentry.mobileReplayIntegration()],\n`\n : ''\n}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n\nfunction getMainAppFilePath(): string | undefined {\n const prefixGlob = '{.,./src,./app}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const universalGlob = `@(App|_layout).${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;\n const jsPath = traceStep('find-app-js-file', () =>\n getFirstMatchedPath(jsFileGlob),\n );\n return jsPath;\n}\n\n/**\n * This step should be executed after `addSentryInit`\n */\nexport async function wrapRootComponent() {\n const showInstructions = () =>\n showCopyPasteInstructions(\n 'App.js or _layout.tsx',\n getSentryWrapColoredCodeSnippet(),\n );\n\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Please wrap your App's Root component.`,\n );\n await showInstructions();\n return;\n }\n\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n\n const mod = parseModule(js);\n const result = checkAndWrapRootComponent(mod);\n\n if (result === SentryWrapResult.AlreadyWrapped) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry-wrap');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry.wrap. We wont't add it again.`,\n );\n return;\n }\n\n if (result === SentryWrapResult.NotFound) {\n clack.log.warn(\n `Could not find your App's Root component. Please wrap your App's Root component manually.`,\n );\n await showInstructions();\n return;\n }\n\n traceStep('add-sentry-wrap', () => {\n clack.log.success(\n `Added ${chalk.cyan('Sentry.wrap')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n\n fs.writeFileSync(jsPath, generateCode(mod.$ast).code, 'utf-8');\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-wrap');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport enum SentryWrapResult {\n NotFound = 'RootComponentNotFound',\n AlreadyWrapped = 'AlreadyWrapped',\n Success = 'Success',\n}\n\nexport function checkAndWrapRootComponent(\n mod: ProxifiedModule,\n): SentryWrapResult {\n if (doesContainSentryWrap(mod.$ast as t.Program)) {\n return SentryWrapResult.AlreadyWrapped;\n }\n\n const defaultExport = getDefaultExport(mod.$ast as t.Program);\n if (!defaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n const wrappedConfig = wrapWithSentry(defaultExport);\n\n const replacedDefaultExport = replaceDefaultExport(\n mod.$ast as t.Program,\n wrappedConfig,\n );\n\n if (!replacedDefaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n return SentryWrapResult.Success;\n}\n\nexport function getDefaultExport(\n program: t.Program,\n):\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration\n | undefined {\n for (const node of program.body) {\n if (\n t.isExportDefaultDeclaration(node) &&\n (t.isIdentifier(node.declaration) ||\n t.isCallExpression(node.declaration) ||\n t.isObjectExpression(node.declaration) ||\n t.isFunctionDeclaration(node.declaration) ||\n t.isArrowFunctionExpression(node.declaration) ||\n t.isClassDeclaration(node.declaration))\n ) {\n Sentry.setTag('app-js-file-status', 'default-export');\n return node.declaration;\n }\n }\n\n Sentry.setTag('app-js-file-status', 'default-export-not-found');\n return undefined;\n}\n\nexport function wrapWithSentry(\n configObj:\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration,\n): t.CallExpression {\n if (t.isFunctionDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.functionExpression(\n configObj.id,\n configObj.params,\n configObj.body,\n configObj.generator,\n configObj.async,\n ),\n ],\n );\n }\n\n if (t.isArrowFunctionExpression(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n }\n\n if (t.isClassDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.classExpression(\n configObj.id,\n configObj.superClass,\n configObj.body,\n configObj.decorators,\n ),\n ],\n );\n }\n\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n}\n\nexport function replaceDefaultExport(\n program: t.Program,\n wrappedDefaultExport: t.CallExpression,\n): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n node.declaration = wrappedDefaultExport;\n return true;\n }\n }\n return false;\n}\n\nexport function doesContainSentryWrap(program: t.Program): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n const declaration = node.declaration;\n if (t.isCallExpression(declaration)) {\n const callExpr = declaration;\n if (t.isMemberExpression(callExpr.callee)) {\n const callee = callExpr.callee;\n if (\n t.isIdentifier(callee.object) &&\n callee.object.name === 'Sentry' &&\n t.isIdentifier(callee.property) &&\n callee.property.name === 'wrap'\n ) {\n return true;\n }\n }\n }\n }\n }\n return false;\n}\n\nfunction getSentryWrapColoredCodeSnippet() {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(`import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(App);`);\n });\n}\n"]}
1
+ {"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/react-native/javascript.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport { traceStep } from '../telemetry';\nimport { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { getFirstMatchedPath } from './glob';\nimport { RN_SDK_PACKAGE } from './react-native-wizard';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, ProxifiedModule, parseModule } from 'magicast';\nimport * as t from '@babel/types';\n\nexport const sessionReplaySampleRate = 0.1;\nexport const sessionReplayOnErrorSampleRate = 1.0;\n\nexport async function addSentryInit({\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n}: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n}) {\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Place the following code snippet close to the Apps Root component.`,\n );\n Sentry.captureException('Could not find main App file.');\n await showCopyPasteInstructions({\n filename: 'App.js or _layout.tsx',\n codeSnippet: getSentryInitColoredCodeSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n ),\n hint: 'This ensures the Sentry SDK is ready to capture errors.',\n });\n return;\n }\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n const includesSentry = doesJsCodeIncludeSdkSentryImport(js, {\n sdkPackageName: RN_SDK_PACKAGE,\n });\n if (includesSentry) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry. We wont't add it again.`,\n );\n return;\n }\n\n traceStep('add-sentry-init', () => {\n const newContent = addSentryInitWithSdkImport(js, {\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n });\n\n try {\n fs.writeFileSync(jsPath, newContent, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.init')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n }\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-init');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport function addSentryInitWithSdkImport(\n js: string,\n {\n dsn,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n }: {\n dsn: string;\n enableSessionReplay?: boolean;\n enableFeedbackWidget?: boolean;\n },\n): string {\n return js.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n (match: string) => `${match}\n${getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n)}`,\n );\n}\n\nexport function doesJsCodeIncludeSdkSentryImport(\n js: string,\n { sdkPackageName }: { sdkPackageName: string },\n): boolean {\n return !!js.match(sdkPackageName);\n}\n\nexport function getSentryInitColoredCodeSnippet(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(\n getSentryInitPlainTextSnippet(\n dsn,\n enableSessionReplay,\n enableFeedbackWidget,\n ),\n );\n });\n}\n\nexport function getSentryInitPlainTextSnippet(\n dsn: string,\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n) {\n return `import * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: '${dsn}',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n${\n enableSessionReplay\n ? `\n // Configure Session Replay\n replaysSessionSampleRate: ${sessionReplaySampleRate},\n replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate},\n`\n : ''\n}${getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay,\n enableFeedbackWidget,\n )}\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});`;\n}\n\nexport function getSentryIntegrationsPlainTextSnippet(\n enableSessionReplay = false,\n enableFeedbackWidget = false,\n) {\n if (!enableSessionReplay && !enableFeedbackWidget) {\n return '';\n }\n return ` integrations: [${\n enableSessionReplay ? 'Sentry.mobileReplayIntegration()' : ''\n }${enableSessionReplay && enableFeedbackWidget ? ', ' : ''}${\n enableFeedbackWidget ? 'Sentry.feedbackIntegration()' : ''\n }],\n`;\n}\n\nfunction getMainAppFilePath(): string | undefined {\n const prefixGlob = '{.,./src,./app}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const universalGlob = `@(App|_layout).${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${universalGlob})`;\n const jsPath = traceStep('find-app-js-file', () =>\n getFirstMatchedPath(jsFileGlob),\n );\n return jsPath;\n}\n\n/**\n * This step should be executed after `addSentryInit`\n */\nexport async function wrapRootComponent() {\n const showInstructions = () =>\n showCopyPasteInstructions({\n filename: 'App.js or _layout.tsx',\n codeSnippet: getSentryWrapColoredCodeSnippet(),\n });\n\n const jsPath = getMainAppFilePath();\n Sentry.setTag('app-js-file-status', jsPath ? 'found' : 'not-found');\n if (!jsPath) {\n clack.log.warn(\n `Could not find main App file. Please wrap your App's Root component.`,\n );\n await showInstructions();\n return;\n }\n\n const jsRelativePath = path.relative(process.cwd(), jsPath);\n\n const js = fs.readFileSync(jsPath, 'utf-8');\n\n const mod = parseModule(js);\n const result = checkAndWrapRootComponent(mod);\n\n if (result === SentryWrapResult.AlreadyWrapped) {\n Sentry.setTag('app-js-file-status', 'already-includes-sentry-wrap');\n clack.log.warn(\n `${chalk.cyan(\n jsRelativePath,\n )} already includes Sentry.wrap. We wont't add it again.`,\n );\n return;\n }\n\n if (result === SentryWrapResult.NotFound) {\n clack.log.warn(\n `Could not find your App's Root component. Please wrap your App's Root component manually.`,\n );\n await showInstructions();\n return;\n }\n\n traceStep('add-sentry-wrap', () => {\n try {\n fs.writeFileSync(jsPath, generateCode(mod.$ast).code, 'utf-8');\n clack.log.success(\n `Added ${chalk.cyan('Sentry.wrap')} to ${chalk.cyan(jsRelativePath)}.`,\n );\n } catch (error) {\n clack.log.error(`Error while writing ${jsPath}`);\n Sentry.captureException('Error while writing app.js');\n return;\n }\n });\n\n Sentry.setTag('app-js-file-status', 'added-sentry-wrap');\n clack.log.success(\n chalk.green(`${chalk.cyan(jsRelativePath)} changes saved.`),\n );\n}\n\nexport enum SentryWrapResult {\n NotFound = 'RootComponentNotFound',\n AlreadyWrapped = 'AlreadyWrapped',\n Success = 'Success',\n}\n\nexport function checkAndWrapRootComponent(\n mod: ProxifiedModule,\n): SentryWrapResult {\n if (doesContainSentryWrap(mod.$ast as t.Program)) {\n return SentryWrapResult.AlreadyWrapped;\n }\n\n const defaultExport = getDefaultExport(mod.$ast as t.Program);\n if (!defaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n const wrappedConfig = wrapWithSentry(defaultExport);\n\n const replacedDefaultExport = replaceDefaultExport(\n mod.$ast as t.Program,\n wrappedConfig,\n );\n\n if (!replacedDefaultExport) {\n return SentryWrapResult.NotFound;\n }\n\n return SentryWrapResult.Success;\n}\n\nexport function getDefaultExport(\n program: t.Program,\n):\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration\n | undefined {\n for (const node of program.body) {\n if (\n t.isExportDefaultDeclaration(node) &&\n (t.isIdentifier(node.declaration) ||\n t.isCallExpression(node.declaration) ||\n t.isObjectExpression(node.declaration) ||\n t.isFunctionDeclaration(node.declaration) ||\n t.isArrowFunctionExpression(node.declaration) ||\n t.isClassDeclaration(node.declaration))\n ) {\n Sentry.setTag('app-js-file-status', 'default-export');\n return node.declaration;\n }\n }\n\n Sentry.setTag('app-js-file-status', 'default-export-not-found');\n return undefined;\n}\n\nexport function wrapWithSentry(\n configObj:\n | t.Identifier\n | t.CallExpression\n | t.ObjectExpression\n | t.FunctionDeclaration\n | t.ArrowFunctionExpression\n | t.ClassDeclaration,\n): t.CallExpression {\n if (t.isFunctionDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.functionExpression(\n configObj.id,\n configObj.params,\n configObj.body,\n configObj.generator,\n configObj.async,\n ),\n ],\n );\n }\n\n if (t.isArrowFunctionExpression(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n }\n\n if (t.isClassDeclaration(configObj)) {\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [\n t.classExpression(\n configObj.id,\n configObj.superClass,\n configObj.body,\n configObj.decorators,\n ),\n ],\n );\n }\n\n return t.callExpression(\n t.memberExpression(t.identifier('Sentry'), t.identifier('wrap')),\n [configObj],\n );\n}\n\nexport function replaceDefaultExport(\n program: t.Program,\n wrappedDefaultExport: t.CallExpression,\n): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n node.declaration = wrappedDefaultExport;\n return true;\n }\n }\n return false;\n}\n\nexport function doesContainSentryWrap(program: t.Program): boolean {\n for (const node of program.body) {\n if (t.isExportDefaultDeclaration(node)) {\n const declaration = node.declaration;\n if (t.isCallExpression(declaration)) {\n const callExpr = declaration;\n if (t.isMemberExpression(callExpr.callee)) {\n const callee = callExpr.callee;\n if (\n t.isIdentifier(callee.object) &&\n callee.object.name === 'Sentry' &&\n t.isIdentifier(callee.property) &&\n callee.property.name === 'wrap'\n ) {\n return true;\n }\n }\n }\n }\n }\n return false;\n}\n\nfunction getSentryWrapColoredCodeSnippet() {\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(`import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(App);`);\n });\n}\n"]}
@@ -9,7 +9,7 @@ export declare function patchMetroConfigWithSentrySerializer(): Promise<void>;
9
9
  export declare function unPatchMetroConfig(): Promise<void>;
10
10
  export declare function removeSentrySerializerFromMetroConfig(program: t.Program): boolean;
11
11
  export declare function removeSentryRequire(program: t.Program): boolean;
12
- export declare function parseMetroConfig(): Promise<ProxifiedModule>;
12
+ export declare function parseMetroConfig(): Promise<ProxifiedModule | undefined>;
13
13
  export declare function writeMetroConfig(mod: ProxifiedModule): Promise<boolean>;
14
14
  export declare function addSentrySerializerToMetroConfig(configObj: t.ObjectExpression): boolean;
15
15
  export declare function addSentrySerializerRequireToMetroConfig(program: t.Program): boolean;
@@ -40,8 +40,15 @@ const chalk_1 = __importDefault(require("chalk"));
40
40
  const b = recast.types.builders;
41
41
  exports.metroConfigPath = 'metro.config.js';
42
42
  async function patchMetroWithSentryConfig() {
43
+ const showInstructions = () => (0, clack_1.showCopyPasteInstructions)({
44
+ filename: exports.metroConfigPath,
45
+ codeSnippet: getMetroWithSentryConfigSnippet(true),
46
+ });
43
47
  const mod = await parseMetroConfig();
44
- const showInstructions = () => (0, clack_1.showCopyPasteInstructions)(exports.metroConfigPath, getMetroWithSentryConfigSnippet(true));
48
+ if (!mod) {
49
+ clack.log.error(`Could read from file ${chalk_1.default.cyan(exports.metroConfigPath)}, please follow the manual steps.`);
50
+ return await showInstructions();
51
+ }
45
52
  const success = await patchMetroWithSentryConfigInMemory(mod, showInstructions);
46
53
  if (!success) {
47
54
  return;
@@ -67,6 +74,7 @@ async function patchMetroWithSentryConfigInMemory(mod, showInstructions) {
67
74
  const configExpression = getModuleExportsAssignmentRight(mod.$ast);
68
75
  if (!configExpression) {
69
76
  clack.log.warn('Could not find Metro config, please follow the manual steps.');
77
+ Sentry.captureException('Could not find Metro config.');
70
78
  await showInstructions();
71
79
  return false;
72
80
  }
@@ -74,12 +82,14 @@ async function patchMetroWithSentryConfigInMemory(mod, showInstructions) {
74
82
  const replacedModuleExportsRight = replaceModuleExportsRight(mod.$ast, wrappedConfig);
75
83
  if (!replacedModuleExportsRight) {
76
84
  clack.log.warn('Could not automatically wrap the config export, please follow the manual steps.');
85
+ Sentry.captureException('Could not automatically wrap the config export.');
77
86
  await showInstructions();
78
87
  return false;
79
88
  }
80
89
  const addedSentryMetroImport = addSentryMetroRequireToMetroConfig(mod.$ast);
81
90
  if (!addedSentryMetroImport) {
82
91
  clack.log.warn('Could not add `@sentry/react-native/metro` import to Metro config, please follow the manual steps.');
92
+ Sentry.captureException('Could not add `@sentry/react-native/metro` import to Metro config.');
83
93
  await showInstructions();
84
94
  return false;
85
95
  }
@@ -88,8 +98,15 @@ async function patchMetroWithSentryConfigInMemory(mod, showInstructions) {
88
98
  }
89
99
  exports.patchMetroWithSentryConfigInMemory = patchMetroWithSentryConfigInMemory;
90
100
  async function patchMetroConfigWithSentrySerializer() {
101
+ const showInstructions = () => (0, clack_1.showCopyPasteInstructions)({
102
+ filename: exports.metroConfigPath,
103
+ codeSnippet: getMetroSentrySerializerSnippet(true),
104
+ });
91
105
  const mod = await parseMetroConfig();
92
- const showInstructions = () => (0, clack_1.showCopyPasteInstructions)(exports.metroConfigPath, getMetroSentrySerializerSnippet(true));
106
+ if (!mod) {
107
+ clack.log.error(`Could read from file ${chalk_1.default.cyan(exports.metroConfigPath)}, please follow the manual steps.`);
108
+ return await showInstructions();
109
+ }
93
110
  if ((0, ast_utils_1.hasSentryContent)(mod.$ast)) {
94
111
  const shouldContinue = await confirmPathMetroConfig();
95
112
  if (!shouldContinue) {
@@ -99,16 +116,19 @@ async function patchMetroConfigWithSentrySerializer() {
99
116
  const configObj = getMetroConfigObject(mod.$ast);
100
117
  if (!configObj) {
101
118
  clack.log.warn('Could not find Metro config object, please follow the manual steps.');
119
+ Sentry.captureException('Could not find Metro config object.');
102
120
  return showInstructions();
103
121
  }
104
122
  const addedSentrySerializer = addSentrySerializerToMetroConfig(configObj);
105
123
  if (!addedSentrySerializer) {
106
124
  clack.log.warn('Could not add Sentry serializer to Metro config, please follow the manual steps.');
125
+ Sentry.captureException('Could not add Sentry serializer to Metro config.');
107
126
  return await showInstructions();
108
127
  }
109
128
  const addedSentrySerializerImport = addSentrySerializerRequireToMetroConfig(mod.$ast);
110
129
  if (!addedSentrySerializerImport) {
111
130
  clack.log.warn('Could not add Sentry serializer import to Metro config, please follow the manual steps.');
131
+ Sentry.captureException('Could not add Sentry serializer import to Metro config.');
112
132
  return await showInstructions();
113
133
  }
114
134
  clack.log.success(`Added Sentry Metro plugin to ${chalk_1.default.cyan(exports.metroConfigPath)}.`);
@@ -124,6 +144,10 @@ async function patchMetroConfigWithSentrySerializer() {
124
144
  exports.patchMetroConfigWithSentrySerializer = patchMetroConfigWithSentrySerializer;
125
145
  async function unPatchMetroConfig() {
126
146
  const mod = await parseMetroConfig();
147
+ if (!mod) {
148
+ clack.log.error(`Could read from file ${chalk_1.default.cyan(exports.metroConfigPath)}, please remove the Sentry Metro plugin manually.`);
149
+ return;
150
+ }
127
151
  const removedAtLeastOneRequire = removeSentryRequire(mod.$ast);
128
152
  const removedSerializerConfig = removeSentrySerializerFromMetroConfig(mod.$ast);
129
153
  if (removedAtLeastOneRequire || removedSerializerConfig) {
@@ -189,8 +213,15 @@ function removeSentryRequire(program) {
189
213
  }
190
214
  exports.removeSentryRequire = removeSentryRequire;
191
215
  async function parseMetroConfig() {
192
- const metroConfigContent = (await fs.promises.readFile(exports.metroConfigPath)).toString();
193
- return (0, magicast_1.parseModule)(metroConfigContent);
216
+ try {
217
+ const metroConfigContent = (await fs.promises.readFile(exports.metroConfigPath)).toString();
218
+ return (0, magicast_1.parseModule)(metroConfigContent);
219
+ }
220
+ catch (error) {
221
+ clack.log.error(`Could not read Metro config file ${chalk_1.default.cyan(exports.metroConfigPath)}`);
222
+ Sentry.captureException('Could not read Metro config file');
223
+ return undefined;
224
+ }
194
225
  }
195
226
  exports.parseMetroConfig = parseMetroConfig;
196
227
  async function writeMetroConfig(mod) {
@@ -199,6 +230,7 @@ async function writeMetroConfig(mod) {
199
230
  }
200
231
  catch (e) {
201
232
  clack.log.error(`Failed to write to ${chalk_1.default.cyan(exports.metroConfigPath)}: ${JSON.stringify(e)}`);
233
+ Sentry.captureException('Failed to write to Metro config file');
202
234
  return false;
203
235
  }
204
236
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"metro.js","sourceRoot":"","sources":["../../../src/react-native/metro.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { ProxifiedModule, parseModule, writeFile } from 'magicast';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport {\n getLastRequireIndex,\n hasSentryContent,\n removeRequire,\n} from '../utils/ast-utils';\nimport {\n abortIfCancelled,\n makeCodeSnippet,\n showCopyPasteInstructions,\n} from '../utils/clack';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\nimport chalk from 'chalk';\n\nconst b = recast.types.builders;\n\nexport const metroConfigPath = 'metro.config.js';\n\nexport async function patchMetroWithSentryConfig() {\n const mod = await parseMetroConfig();\n\n const showInstructions = () =>\n showCopyPasteInstructions(\n metroConfigPath,\n getMetroWithSentryConfigSnippet(true),\n );\n\n const success = await patchMetroWithSentryConfigInMemory(\n mod,\n showInstructions,\n );\n if (!success) {\n return;\n }\n\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n chalk.green(`${chalk.cyan(metroConfigPath)} changes saved.`),\n );\n } else {\n clack.log.warn(\n `Could not save changes to ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n}\n\nexport async function patchMetroWithSentryConfigInMemory(\n mod: ProxifiedModule,\n showInstructions: () => Promise<void>,\n): Promise<boolean> {\n if (hasSentryContent(mod.$ast as t.Program)) {\n const shouldContinue = await confirmPathMetroConfig();\n if (!shouldContinue) {\n await showInstructions();\n return false;\n }\n }\n\n const configExpression = getModuleExportsAssignmentRight(\n mod.$ast as t.Program,\n );\n if (!configExpression) {\n clack.log.warn(\n 'Could not find Metro config, please follow the manual steps.',\n );\n await showInstructions();\n return false;\n }\n\n const wrappedConfig = wrapWithSentryConfig(configExpression);\n\n const replacedModuleExportsRight = replaceModuleExportsRight(\n mod.$ast as t.Program,\n wrappedConfig,\n );\n if (!replacedModuleExportsRight) {\n clack.log.warn(\n 'Could not automatically wrap the config export, please follow the manual steps.',\n );\n await showInstructions();\n return false;\n }\n\n const addedSentryMetroImport = addSentryMetroRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n if (!addedSentryMetroImport) {\n clack.log.warn(\n 'Could not add `@sentry/react-native/metro` import to Metro config, please follow the manual steps.',\n );\n await showInstructions();\n return false;\n }\n\n clack.log.success(\n `Added Sentry Metro plugin to ${chalk.cyan(metroConfigPath)}.`,\n );\n return true;\n}\n\nexport async function patchMetroConfigWithSentrySerializer() {\n const mod = await parseMetroConfig();\n\n const showInstructions = () =>\n showCopyPasteInstructions(\n metroConfigPath,\n getMetroSentrySerializerSnippet(true),\n );\n\n if (hasSentryContent(mod.$ast as t.Program)) {\n const shouldContinue = await confirmPathMetroConfig();\n if (!shouldContinue) {\n return await showInstructions();\n }\n }\n\n const configObj = getMetroConfigObject(mod.$ast as t.Program);\n if (!configObj) {\n clack.log.warn(\n 'Could not find Metro config object, please follow the manual steps.',\n );\n return showInstructions();\n }\n\n const addedSentrySerializer = addSentrySerializerToMetroConfig(configObj);\n if (!addedSentrySerializer) {\n clack.log.warn(\n 'Could not add Sentry serializer to Metro config, please follow the manual steps.',\n );\n return await showInstructions();\n }\n\n const addedSentrySerializerImport = addSentrySerializerRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n if (!addedSentrySerializerImport) {\n clack.log.warn(\n 'Could not add Sentry serializer import to Metro config, please follow the manual steps.',\n );\n return await showInstructions();\n }\n\n clack.log.success(\n `Added Sentry Metro plugin to ${chalk.cyan(metroConfigPath)}.`,\n );\n\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n chalk.green(`${chalk.cyan(metroConfigPath)} changes saved.`),\n );\n } else {\n clack.log.warn(\n `Could not save changes to ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n}\n\nexport async function unPatchMetroConfig() {\n const mod = await parseMetroConfig();\n\n const removedAtLeastOneRequire = removeSentryRequire(mod.$ast as t.Program);\n const removedSerializerConfig = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n\n if (removedAtLeastOneRequire || removedSerializerConfig) {\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n `Removed Sentry Metro plugin from ${chalk.cyan(metroConfigPath)}.`,\n );\n }\n } else {\n clack.log.warn(\n `No Sentry Metro plugin found in ${chalk.cyan(metroConfigPath)}.`,\n );\n }\n}\n\nexport function removeSentrySerializerFromMetroConfig(\n program: t.Program,\n): boolean {\n const configObject = getMetroConfigObject(program);\n if (!configObject) {\n return false;\n }\n\n const serializerProp = getSerializerProp(configObject);\n if ('invalid' === serializerProp || 'undefined' === serializerProp) {\n return false;\n }\n\n const customSerializerProp = getCustomSerializerProp(serializerProp);\n if (\n 'invalid' === customSerializerProp ||\n 'undefined' === customSerializerProp\n ) {\n return false;\n }\n\n if (\n serializerProp.value.type === 'ObjectExpression' &&\n customSerializerProp.value.type === 'CallExpression' &&\n customSerializerProp.value.callee.type === 'Identifier' &&\n customSerializerProp.value.callee.name === 'createSentryMetroSerializer'\n ) {\n if (customSerializerProp.value.arguments.length === 0) {\n // FROM serializer: { customSerializer: createSentryMetroSerializer() }\n // TO serializer: {}\n let removed = false;\n serializerProp.value.properties = serializerProp.value.properties.filter(\n (p) => {\n if (\n p.type === 'ObjectProperty' &&\n p.key.type === 'Identifier' &&\n p.key.name === 'customSerializer'\n ) {\n removed = true;\n return false;\n }\n return true;\n },\n );\n\n if (removed) {\n return true;\n }\n } else {\n if (customSerializerProp.value.arguments[0].type !== 'SpreadElement') {\n // FROM serializer: { customSerializer: createSentryMetroSerializer(wrapperSerializer) }\n // TO serializer: { customSerializer: wrapperSerializer }\n customSerializerProp.value = customSerializerProp.value.arguments[0];\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function removeSentryRequire(program: t.Program): boolean {\n return removeRequire(program, '@sentry');\n}\n\nexport async function parseMetroConfig(): Promise<ProxifiedModule> {\n const metroConfigContent = (\n await fs.promises.readFile(metroConfigPath)\n ).toString();\n\n return parseModule(metroConfigContent);\n}\n\nexport async function writeMetroConfig(mod: ProxifiedModule): Promise<boolean> {\n try {\n await writeFile(mod.$ast, metroConfigPath);\n } catch (e) {\n clack.log.error(\n `Failed to write to ${chalk.cyan(metroConfigPath)}: ${JSON.stringify(e)}`,\n );\n return false;\n }\n return true;\n}\n\nexport function addSentrySerializerToMetroConfig(\n configObj: t.ObjectExpression,\n): boolean {\n const serializerProp = getSerializerProp(configObj);\n if ('invalid' === serializerProp) {\n return false;\n }\n\n // case 1: serializer property doesn't exist yet, so we can just add it\n if ('undefined' === serializerProp) {\n configObj.properties.push(\n b.objectProperty(\n b.identifier('serializer'),\n b.objectExpression([\n b.objectProperty(\n b.identifier('customSerializer'),\n b.callExpression(b.identifier('createSentryMetroSerializer'), []),\n ),\n ]),\n ),\n );\n return true;\n }\n\n const customSerializerProp = getCustomSerializerProp(serializerProp);\n // case 2: serializer.customSerializer property doesn't exist yet, so we just add it\n if (\n 'undefined' === customSerializerProp &&\n serializerProp.value.type === 'ObjectExpression'\n ) {\n serializerProp.value.properties.push(\n b.objectProperty(\n b.identifier('customSerializer'),\n b.callExpression(b.identifier('createSentryMetroSerializer'), []),\n ),\n );\n return true;\n }\n\n return false;\n}\n\nfunction getCustomSerializerProp(\n prop: t.ObjectProperty,\n): t.ObjectProperty | 'undefined' | 'invalid' {\n const customSerializerProp =\n prop.value.type === 'ObjectExpression' &&\n prop.value.properties.find(\n (p: t.ObjectProperty) =>\n p.key.type === 'Identifier' && p.key.name === 'customSerializer',\n );\n\n if (!customSerializerProp) {\n return 'undefined';\n }\n\n if (customSerializerProp.type === 'ObjectProperty') {\n return customSerializerProp;\n }\n\n return 'invalid';\n}\n\nfunction getSerializerProp(\n obj: t.ObjectExpression,\n): t.ObjectProperty | 'undefined' | 'invalid' {\n const serializerProp = obj.properties.find(\n (p: t.ObjectProperty) =>\n p.key.type === 'Identifier' && p.key.name === 'serializer',\n );\n\n if (!serializerProp) {\n return 'undefined';\n }\n\n if (serializerProp.type === 'ObjectProperty') {\n return serializerProp;\n }\n\n return 'invalid';\n}\n\nexport function addSentrySerializerRequireToMetroConfig(\n program: t.Program,\n): boolean {\n const lastRequireIndex = getLastRequireIndex(program);\n const sentrySerializerRequire = createSentrySerializerRequire();\n const sentryImportIndex = lastRequireIndex + 1;\n if (sentryImportIndex < program.body.length) {\n // insert after last require\n program.body.splice(lastRequireIndex + 1, 0, sentrySerializerRequire);\n } else {\n // insert at the beginning\n program.body.unshift(sentrySerializerRequire);\n }\n return true;\n}\n\nexport function addSentryMetroRequireToMetroConfig(\n program: t.Program,\n): boolean {\n const lastRequireIndex = getLastRequireIndex(program);\n const sentryMetroRequire = createSentryMetroRequire();\n const sentryImportIndex = lastRequireIndex + 1;\n if (sentryImportIndex < program.body.length) {\n // insert after last require\n program.body.splice(lastRequireIndex + 1, 0, sentryMetroRequire);\n } else {\n // insert at the beginning\n program.body.unshift(sentryMetroRequire);\n }\n return true;\n}\n\nfunction wrapWithSentryConfig(\n configObj: t.Identifier | t.CallExpression | t.ObjectExpression,\n): t.CallExpression {\n return b.callExpression(b.identifier('withSentryConfig'), [configObj]);\n}\n\nfunction replaceModuleExportsRight(\n program: t.Program,\n wrappedConfig: t.CallExpression,\n): boolean {\n const moduleExports = getModuleExports(program);\n if (!moduleExports) {\n return false;\n }\n\n if (moduleExports.expression.type === 'AssignmentExpression') {\n moduleExports.expression.right = wrappedConfig;\n return true;\n }\n\n return false;\n}\n\n/**\n * Creates const {createSentryMetroSerializer} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\n */\nfunction createSentrySerializerRequire() {\n return b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.objectProperty.from({\n key: b.identifier('createSentryMetroSerializer'),\n value: b.identifier('createSentryMetroSerializer'),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier('require'), [\n b.literal('@sentry/react-native/dist/js/tools/sentryMetroSerializer'),\n ]),\n ),\n ]);\n}\n\n/**\n * Creates const {withSentryConfig} = require('@sentry/react-native/metro');\n */\nfunction createSentryMetroRequire() {\n return b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.objectProperty.from({\n key: b.identifier('withSentryConfig'),\n value: b.identifier('withSentryConfig'),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier('require'), [\n b.literal('@sentry/react-native/metro'),\n ]),\n ),\n ]);\n}\n\nasync function confirmPathMetroConfig() {\n const shouldContinue = await abortIfCancelled(\n clack.select({\n message: `Metro Config already contains Sentry-related code. Should the wizard modify it anyway?`,\n options: [\n {\n label: 'Yes, add the Sentry Metro plugin',\n value: true,\n },\n {\n label: 'No, show me instructions to manually add the plugin',\n value: false,\n },\n ],\n initialValue: true,\n }),\n );\n\n if (!shouldContinue) {\n Sentry.setTag('ast-mod-fail-reason', 'has-sentry-content');\n }\n\n return shouldContinue;\n}\n\n/**\n * Returns value from `module.exports = value` or `const config = value`\n */\nexport function getMetroConfigObject(\n program: t.Program,\n): t.ObjectExpression | undefined {\n // check config variable\n const configVariable = program.body.find((s) => {\n if (\n s.type === 'VariableDeclaration' &&\n s.declarations.length === 1 &&\n s.declarations[0].type === 'VariableDeclarator' &&\n s.declarations[0].id.type === 'Identifier' &&\n s.declarations[0].id.name === 'config'\n ) {\n return true;\n }\n return false;\n }) as t.VariableDeclaration | undefined;\n\n if (\n configVariable?.declarations[0].type === 'VariableDeclarator' &&\n configVariable?.declarations[0].init?.type === 'ObjectExpression'\n ) {\n Sentry.setTag('metro-config', 'config-variable');\n return configVariable.declarations[0].init;\n }\n\n return getModuleExportsObject(program);\n}\n\nfunction getModuleExportsObject(\n program: t.Program,\n): t.ObjectExpression | undefined {\n // check module.exports\n const moduleExports = getModuleExportsAssignmentRight(program);\n\n if (moduleExports?.type === 'ObjectExpression') {\n return moduleExports;\n }\n\n Sentry.setTag('metro-config', 'not-found');\n return undefined;\n}\n\nexport function getModuleExportsAssignmentRight(\n program: t.Program,\n): t.Identifier | t.CallExpression | t.ObjectExpression | undefined {\n // check module.exports\n const moduleExports = getModuleExports(program);\n\n if (\n moduleExports?.expression.type === 'AssignmentExpression' &&\n (moduleExports.expression.right.type === 'ObjectExpression' ||\n moduleExports.expression.right.type === 'CallExpression' ||\n moduleExports.expression.right.type === 'Identifier')\n ) {\n Sentry.setTag('metro-config', 'module-exports');\n return moduleExports?.expression.right;\n }\n\n Sentry.setTag('metro-config', 'not-found');\n return undefined;\n}\n\nfunction getModuleExports(\n program: t.Program,\n): t.ExpressionStatement | undefined {\n // find module.exports\n return program.body.find((s) => {\n if (\n s.type === 'ExpressionStatement' &&\n s.expression.type === 'AssignmentExpression' &&\n s.expression.left.type === 'MemberExpression' &&\n s.expression.left.object.type === 'Identifier' &&\n s.expression.left.object.name === 'module' &&\n s.expression.left.property.type === 'Identifier' &&\n s.expression.left.property.name === 'exports'\n ) {\n return true;\n }\n return false;\n }) as t.ExpressionStatement | undefined;\n}\n\nfunction getMetroSentrySerializerSnippet(colors: boolean) {\n return makeCodeSnippet(colors, (unchanged, plus, _) =>\n unchanged(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\";\n${plus(\n \"const {createSentryMetroSerializer} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\",\n)}\n\nconst config = {\n ${plus(`serializer: {\n customSerializer: createSentryMetroSerializer(),\n },`)}\n};\n\nmodule.exports = mergeConfig(getDefaultConfig(__dirname), config);\n`),\n );\n}\n\nfunction getMetroWithSentryConfigSnippet(colors: boolean) {\n return makeCodeSnippet(colors, (unchanged, plus, _) =>\n unchanged(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\";\n${plus(\"const {withSentryConfig} = require('@sentry/react-native/metro');\")}\n\nconst config = {};\n\nmodule.exports = ${plus(\n 'withSentryConfig(',\n )}mergeConfig(getDefaultConfig(__dirname), config)${plus(')')};\n`),\n );\n}\n"]}
1
+ {"version":3,"file":"metro.js","sourceRoot":"","sources":["../../../src/react-native/metro.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { ProxifiedModule, parseModule, writeFile } from 'magicast';\nimport * as fs from 'fs';\nimport * as Sentry from '@sentry/node';\n\nimport {\n getLastRequireIndex,\n hasSentryContent,\n removeRequire,\n} from '../utils/ast-utils';\nimport {\n abortIfCancelled,\n makeCodeSnippet,\n showCopyPasteInstructions,\n} from '../utils/clack';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\nimport chalk from 'chalk';\n\nconst b = recast.types.builders;\n\nexport const metroConfigPath = 'metro.config.js';\n\nexport async function patchMetroWithSentryConfig() {\n const showInstructions = () =>\n showCopyPasteInstructions({\n filename: metroConfigPath,\n codeSnippet: getMetroWithSentryConfigSnippet(true),\n });\n\n const mod = await parseMetroConfig();\n if (!mod) {\n clack.log.error(\n `Could read from file ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n\n const success = await patchMetroWithSentryConfigInMemory(\n mod,\n showInstructions,\n );\n if (!success) {\n return;\n }\n\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n chalk.green(`${chalk.cyan(metroConfigPath)} changes saved.`),\n );\n } else {\n clack.log.warn(\n `Could not save changes to ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n}\n\nexport async function patchMetroWithSentryConfigInMemory(\n mod: ProxifiedModule,\n showInstructions: () => Promise<void>,\n): Promise<boolean> {\n if (hasSentryContent(mod.$ast as t.Program)) {\n const shouldContinue = await confirmPathMetroConfig();\n if (!shouldContinue) {\n await showInstructions();\n return false;\n }\n }\n\n const configExpression = getModuleExportsAssignmentRight(\n mod.$ast as t.Program,\n );\n if (!configExpression) {\n clack.log.warn(\n 'Could not find Metro config, please follow the manual steps.',\n );\n Sentry.captureException('Could not find Metro config.');\n await showInstructions();\n return false;\n }\n\n const wrappedConfig = wrapWithSentryConfig(configExpression);\n\n const replacedModuleExportsRight = replaceModuleExportsRight(\n mod.$ast as t.Program,\n wrappedConfig,\n );\n if (!replacedModuleExportsRight) {\n clack.log.warn(\n 'Could not automatically wrap the config export, please follow the manual steps.',\n );\n Sentry.captureException('Could not automatically wrap the config export.');\n await showInstructions();\n return false;\n }\n\n const addedSentryMetroImport = addSentryMetroRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n if (!addedSentryMetroImport) {\n clack.log.warn(\n 'Could not add `@sentry/react-native/metro` import to Metro config, please follow the manual steps.',\n );\n Sentry.captureException(\n 'Could not add `@sentry/react-native/metro` import to Metro config.',\n );\n await showInstructions();\n return false;\n }\n\n clack.log.success(\n `Added Sentry Metro plugin to ${chalk.cyan(metroConfigPath)}.`,\n );\n return true;\n}\n\nexport async function patchMetroConfigWithSentrySerializer() {\n const showInstructions = () =>\n showCopyPasteInstructions({\n filename: metroConfigPath,\n codeSnippet: getMetroSentrySerializerSnippet(true),\n });\n\n const mod = await parseMetroConfig();\n if (!mod) {\n clack.log.error(\n `Could read from file ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n\n if (hasSentryContent(mod.$ast as t.Program)) {\n const shouldContinue = await confirmPathMetroConfig();\n if (!shouldContinue) {\n return await showInstructions();\n }\n }\n\n const configObj = getMetroConfigObject(mod.$ast as t.Program);\n if (!configObj) {\n clack.log.warn(\n 'Could not find Metro config object, please follow the manual steps.',\n );\n Sentry.captureException('Could not find Metro config object.');\n return showInstructions();\n }\n\n const addedSentrySerializer = addSentrySerializerToMetroConfig(configObj);\n if (!addedSentrySerializer) {\n clack.log.warn(\n 'Could not add Sentry serializer to Metro config, please follow the manual steps.',\n );\n Sentry.captureException('Could not add Sentry serializer to Metro config.');\n return await showInstructions();\n }\n\n const addedSentrySerializerImport = addSentrySerializerRequireToMetroConfig(\n mod.$ast as t.Program,\n );\n if (!addedSentrySerializerImport) {\n clack.log.warn(\n 'Could not add Sentry serializer import to Metro config, please follow the manual steps.',\n );\n Sentry.captureException(\n 'Could not add Sentry serializer import to Metro config.',\n );\n return await showInstructions();\n }\n\n clack.log.success(\n `Added Sentry Metro plugin to ${chalk.cyan(metroConfigPath)}.`,\n );\n\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n chalk.green(`${chalk.cyan(metroConfigPath)} changes saved.`),\n );\n } else {\n clack.log.warn(\n `Could not save changes to ${chalk.cyan(\n metroConfigPath,\n )}, please follow the manual steps.`,\n );\n return await showInstructions();\n }\n}\n\nexport async function unPatchMetroConfig() {\n const mod = await parseMetroConfig();\n if (!mod) {\n clack.log.error(\n `Could read from file ${chalk.cyan(\n metroConfigPath,\n )}, please remove the Sentry Metro plugin manually.`,\n );\n return;\n }\n\n const removedAtLeastOneRequire = removeSentryRequire(mod.$ast as t.Program);\n const removedSerializerConfig = removeSentrySerializerFromMetroConfig(\n mod.$ast as t.Program,\n );\n\n if (removedAtLeastOneRequire || removedSerializerConfig) {\n const saved = await writeMetroConfig(mod);\n if (saved) {\n clack.log.success(\n `Removed Sentry Metro plugin from ${chalk.cyan(metroConfigPath)}.`,\n );\n }\n } else {\n clack.log.warn(\n `No Sentry Metro plugin found in ${chalk.cyan(metroConfigPath)}.`,\n );\n }\n}\n\nexport function removeSentrySerializerFromMetroConfig(\n program: t.Program,\n): boolean {\n const configObject = getMetroConfigObject(program);\n if (!configObject) {\n return false;\n }\n\n const serializerProp = getSerializerProp(configObject);\n if ('invalid' === serializerProp || 'undefined' === serializerProp) {\n return false;\n }\n\n const customSerializerProp = getCustomSerializerProp(serializerProp);\n if (\n 'invalid' === customSerializerProp ||\n 'undefined' === customSerializerProp\n ) {\n return false;\n }\n\n if (\n serializerProp.value.type === 'ObjectExpression' &&\n customSerializerProp.value.type === 'CallExpression' &&\n customSerializerProp.value.callee.type === 'Identifier' &&\n customSerializerProp.value.callee.name === 'createSentryMetroSerializer'\n ) {\n if (customSerializerProp.value.arguments.length === 0) {\n // FROM serializer: { customSerializer: createSentryMetroSerializer() }\n // TO serializer: {}\n let removed = false;\n serializerProp.value.properties = serializerProp.value.properties.filter(\n (p) => {\n if (\n p.type === 'ObjectProperty' &&\n p.key.type === 'Identifier' &&\n p.key.name === 'customSerializer'\n ) {\n removed = true;\n return false;\n }\n return true;\n },\n );\n\n if (removed) {\n return true;\n }\n } else {\n if (customSerializerProp.value.arguments[0].type !== 'SpreadElement') {\n // FROM serializer: { customSerializer: createSentryMetroSerializer(wrapperSerializer) }\n // TO serializer: { customSerializer: wrapperSerializer }\n customSerializerProp.value = customSerializerProp.value.arguments[0];\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function removeSentryRequire(program: t.Program): boolean {\n return removeRequire(program, '@sentry');\n}\n\nexport async function parseMetroConfig(): Promise<ProxifiedModule | undefined> {\n try {\n const metroConfigContent = (\n await fs.promises.readFile(metroConfigPath)\n ).toString();\n\n return parseModule(metroConfigContent);\n } catch (error) {\n clack.log.error(\n `Could not read Metro config file ${chalk.cyan(metroConfigPath)}`,\n );\n Sentry.captureException('Could not read Metro config file');\n return undefined;\n }\n}\n\nexport async function writeMetroConfig(mod: ProxifiedModule): Promise<boolean> {\n try {\n await writeFile(mod.$ast, metroConfigPath);\n } catch (e) {\n clack.log.error(\n `Failed to write to ${chalk.cyan(metroConfigPath)}: ${JSON.stringify(e)}`,\n );\n Sentry.captureException('Failed to write to Metro config file');\n return false;\n }\n return true;\n}\n\nexport function addSentrySerializerToMetroConfig(\n configObj: t.ObjectExpression,\n): boolean {\n const serializerProp = getSerializerProp(configObj);\n if ('invalid' === serializerProp) {\n return false;\n }\n\n // case 1: serializer property doesn't exist yet, so we can just add it\n if ('undefined' === serializerProp) {\n configObj.properties.push(\n b.objectProperty(\n b.identifier('serializer'),\n b.objectExpression([\n b.objectProperty(\n b.identifier('customSerializer'),\n b.callExpression(b.identifier('createSentryMetroSerializer'), []),\n ),\n ]),\n ),\n );\n return true;\n }\n\n const customSerializerProp = getCustomSerializerProp(serializerProp);\n // case 2: serializer.customSerializer property doesn't exist yet, so we just add it\n if (\n 'undefined' === customSerializerProp &&\n serializerProp.value.type === 'ObjectExpression'\n ) {\n serializerProp.value.properties.push(\n b.objectProperty(\n b.identifier('customSerializer'),\n b.callExpression(b.identifier('createSentryMetroSerializer'), []),\n ),\n );\n return true;\n }\n\n return false;\n}\n\nfunction getCustomSerializerProp(\n prop: t.ObjectProperty,\n): t.ObjectProperty | 'undefined' | 'invalid' {\n const customSerializerProp =\n prop.value.type === 'ObjectExpression' &&\n prop.value.properties.find(\n (p: t.ObjectProperty) =>\n p.key.type === 'Identifier' && p.key.name === 'customSerializer',\n );\n\n if (!customSerializerProp) {\n return 'undefined';\n }\n\n if (customSerializerProp.type === 'ObjectProperty') {\n return customSerializerProp;\n }\n\n return 'invalid';\n}\n\nfunction getSerializerProp(\n obj: t.ObjectExpression,\n): t.ObjectProperty | 'undefined' | 'invalid' {\n const serializerProp = obj.properties.find(\n (p: t.ObjectProperty) =>\n p.key.type === 'Identifier' && p.key.name === 'serializer',\n );\n\n if (!serializerProp) {\n return 'undefined';\n }\n\n if (serializerProp.type === 'ObjectProperty') {\n return serializerProp;\n }\n\n return 'invalid';\n}\n\nexport function addSentrySerializerRequireToMetroConfig(\n program: t.Program,\n): boolean {\n const lastRequireIndex = getLastRequireIndex(program);\n const sentrySerializerRequire = createSentrySerializerRequire();\n const sentryImportIndex = lastRequireIndex + 1;\n if (sentryImportIndex < program.body.length) {\n // insert after last require\n program.body.splice(lastRequireIndex + 1, 0, sentrySerializerRequire);\n } else {\n // insert at the beginning\n program.body.unshift(sentrySerializerRequire);\n }\n return true;\n}\n\nexport function addSentryMetroRequireToMetroConfig(\n program: t.Program,\n): boolean {\n const lastRequireIndex = getLastRequireIndex(program);\n const sentryMetroRequire = createSentryMetroRequire();\n const sentryImportIndex = lastRequireIndex + 1;\n if (sentryImportIndex < program.body.length) {\n // insert after last require\n program.body.splice(lastRequireIndex + 1, 0, sentryMetroRequire);\n } else {\n // insert at the beginning\n program.body.unshift(sentryMetroRequire);\n }\n return true;\n}\n\nfunction wrapWithSentryConfig(\n configObj: t.Identifier | t.CallExpression | t.ObjectExpression,\n): t.CallExpression {\n return b.callExpression(b.identifier('withSentryConfig'), [configObj]);\n}\n\nfunction replaceModuleExportsRight(\n program: t.Program,\n wrappedConfig: t.CallExpression,\n): boolean {\n const moduleExports = getModuleExports(program);\n if (!moduleExports) {\n return false;\n }\n\n if (moduleExports.expression.type === 'AssignmentExpression') {\n moduleExports.expression.right = wrappedConfig;\n return true;\n }\n\n return false;\n}\n\n/**\n * Creates const {createSentryMetroSerializer} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\n */\nfunction createSentrySerializerRequire() {\n return b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.objectProperty.from({\n key: b.identifier('createSentryMetroSerializer'),\n value: b.identifier('createSentryMetroSerializer'),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier('require'), [\n b.literal('@sentry/react-native/dist/js/tools/sentryMetroSerializer'),\n ]),\n ),\n ]);\n}\n\n/**\n * Creates const {withSentryConfig} = require('@sentry/react-native/metro');\n */\nfunction createSentryMetroRequire() {\n return b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern([\n b.objectProperty.from({\n key: b.identifier('withSentryConfig'),\n value: b.identifier('withSentryConfig'),\n shorthand: true,\n }),\n ]),\n b.callExpression(b.identifier('require'), [\n b.literal('@sentry/react-native/metro'),\n ]),\n ),\n ]);\n}\n\nasync function confirmPathMetroConfig() {\n const shouldContinue = await abortIfCancelled(\n clack.select({\n message: `Metro Config already contains Sentry-related code. Should the wizard modify it anyway?`,\n options: [\n {\n label: 'Yes, add the Sentry Metro plugin',\n value: true,\n },\n {\n label: 'No, show me instructions to manually add the plugin',\n value: false,\n },\n ],\n initialValue: true,\n }),\n );\n\n if (!shouldContinue) {\n Sentry.setTag('ast-mod-fail-reason', 'has-sentry-content');\n }\n\n return shouldContinue;\n}\n\n/**\n * Returns value from `module.exports = value` or `const config = value`\n */\nexport function getMetroConfigObject(\n program: t.Program,\n): t.ObjectExpression | undefined {\n // check config variable\n const configVariable = program.body.find((s) => {\n if (\n s.type === 'VariableDeclaration' &&\n s.declarations.length === 1 &&\n s.declarations[0].type === 'VariableDeclarator' &&\n s.declarations[0].id.type === 'Identifier' &&\n s.declarations[0].id.name === 'config'\n ) {\n return true;\n }\n return false;\n }) as t.VariableDeclaration | undefined;\n\n if (\n configVariable?.declarations[0].type === 'VariableDeclarator' &&\n configVariable?.declarations[0].init?.type === 'ObjectExpression'\n ) {\n Sentry.setTag('metro-config', 'config-variable');\n return configVariable.declarations[0].init;\n }\n\n return getModuleExportsObject(program);\n}\n\nfunction getModuleExportsObject(\n program: t.Program,\n): t.ObjectExpression | undefined {\n // check module.exports\n const moduleExports = getModuleExportsAssignmentRight(program);\n\n if (moduleExports?.type === 'ObjectExpression') {\n return moduleExports;\n }\n\n Sentry.setTag('metro-config', 'not-found');\n return undefined;\n}\n\nexport function getModuleExportsAssignmentRight(\n program: t.Program,\n): t.Identifier | t.CallExpression | t.ObjectExpression | undefined {\n // check module.exports\n const moduleExports = getModuleExports(program);\n\n if (\n moduleExports?.expression.type === 'AssignmentExpression' &&\n (moduleExports.expression.right.type === 'ObjectExpression' ||\n moduleExports.expression.right.type === 'CallExpression' ||\n moduleExports.expression.right.type === 'Identifier')\n ) {\n Sentry.setTag('metro-config', 'module-exports');\n return moduleExports?.expression.right;\n }\n\n Sentry.setTag('metro-config', 'not-found');\n return undefined;\n}\n\nfunction getModuleExports(\n program: t.Program,\n): t.ExpressionStatement | undefined {\n // find module.exports\n return program.body.find((s) => {\n if (\n s.type === 'ExpressionStatement' &&\n s.expression.type === 'AssignmentExpression' &&\n s.expression.left.type === 'MemberExpression' &&\n s.expression.left.object.type === 'Identifier' &&\n s.expression.left.object.name === 'module' &&\n s.expression.left.property.type === 'Identifier' &&\n s.expression.left.property.name === 'exports'\n ) {\n return true;\n }\n return false;\n }) as t.ExpressionStatement | undefined;\n}\n\nfunction getMetroSentrySerializerSnippet(colors: boolean) {\n return makeCodeSnippet(colors, (unchanged, plus, _) =>\n unchanged(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\";\n${plus(\n \"const {createSentryMetroSerializer} = require('@sentry/react-native/dist/js/tools/sentryMetroSerializer');\",\n)}\n\nconst config = {\n ${plus(`serializer: {\n customSerializer: createSentryMetroSerializer(),\n },`)}\n};\n\nmodule.exports = mergeConfig(getDefaultConfig(__dirname), config);\n`),\n );\n}\n\nfunction getMetroWithSentryConfigSnippet(colors: boolean) {\n return makeCodeSnippet(colors, (unchanged, plus, _) =>\n unchanged(`const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');\";\n${plus(\"const {withSentryConfig} = require('@sentry/react-native/metro');\")}\n\nconst config = {};\n\nmodule.exports = ${plus(\n 'withSentryConfig(',\n )}mergeConfig(getDefaultConfig(__dirname), config)${plus(')')};\n`),\n );\n}\n"]}
@@ -19,6 +19,10 @@ export declare const SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = ">=5.11.0";
19
19
  * The following SDK version supports mobile Session Replay
20
20
  */
21
21
  export declare const SESSION_REPLAY_SUPPORTED_SDK_RANGE = ">=6.5.0";
22
+ /**
23
+ * The following SDK version supports the Feedback Widget
24
+ */
25
+ export declare const FEEDBACK_WIDGET_SUPPORTED_SDK_RANGE = ">=6.9.0";
22
26
  /**
23
27
  * The following SDK version ship with bundled Expo plugin
24
28
  */
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.runReactNativeWizardWithTelemetry = exports.runReactNativeWizard = exports.METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE = exports.EXPO_SUPPORTED_SDK_RANGE = exports.SESSION_REPLAY_SUPPORTED_SDK_RANGE = exports.SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = exports.XCODE_SCRIPTS_SUPPORTED_SDK_RANGE = exports.SUPPORTED_EXPO_RANGE = exports.SUPPORTED_RN_RANGE = exports.RN_HUMAN_NAME = exports.RN_PACKAGE = exports.RN_SDK_SUPPORTED_RANGE = exports.RN_SDK_PACKAGE = void 0;
29
+ exports.runReactNativeWizardWithTelemetry = exports.runReactNativeWizard = exports.METRO_WITH_SENTRY_CONFIG_SUPPORTED_SDK_RANGE = exports.EXPO_SUPPORTED_SDK_RANGE = exports.FEEDBACK_WIDGET_SUPPORTED_SDK_RANGE = exports.SESSION_REPLAY_SUPPORTED_SDK_RANGE = exports.SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = exports.XCODE_SCRIPTS_SUPPORTED_SDK_RANGE = exports.SUPPORTED_EXPO_RANGE = exports.SUPPORTED_RN_RANGE = exports.RN_HUMAN_NAME = exports.RN_PACKAGE = exports.RN_SDK_SUPPORTED_RANGE = exports.RN_SDK_PACKAGE = void 0;
30
30
  /* eslint-disable max-lines */
31
31
  // @ts-expect-error - clack is ESM and TS complains about that. It works though
32
32
  const prompts_1 = __importDefault(require("@clack/prompts"));
@@ -69,6 +69,10 @@ exports.SENTRY_METRO_PLUGIN_SUPPORTED_SDK_RANGE = '>=5.11.0';
69
69
  * The following SDK version supports mobile Session Replay
70
70
  */
71
71
  exports.SESSION_REPLAY_SUPPORTED_SDK_RANGE = '>=6.5.0';
72
+ /**
73
+ * The following SDK version supports the Feedback Widget
74
+ */
75
+ exports.FEEDBACK_WIDGET_SUPPORTED_SDK_RANGE = '>=6.9.0';
72
76
  /**
73
77
  * The following SDK version ship with bundled Expo plugin
74
78
  */
@@ -182,14 +186,40 @@ Or setup using ${chalk_1.default.cyan('https://docs.sentry.io/platforms/react-na
182
186
  message: 'Do you want to enable Session Replay to help debug issues? (See https://docs.sentry.io/platforms/react-native/session-replay/)',
183
187
  }));
184
188
  Sentry.setTag('enable-session-replay', enableSessionReplay);
189
+ if (enableSessionReplay) {
190
+ prompts_1.default.log.info(`Session Replay will be enabled with default settings (replaysSessionSampleRate: ${javascript_1.sessionReplaySampleRate}, replaysOnErrorSampleRate: ${javascript_1.sessionReplayOnErrorSampleRate}).`);
191
+ prompts_1.default.log.message('By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.');
192
+ }
185
193
  }
186
194
  else if (sdkVersion) {
187
195
  prompts_1.default.log.info(`Session Replay is supported from Sentry React Native SDK version ${exports.SESSION_REPLAY_SUPPORTED_SDK_RANGE}. Your version (${sdkVersion}) doesn't support it yet.`);
188
196
  prompts_1.default.log.message(`To use Session Replay, please upgrade your Sentry SDK: npm install ${exports.RN_SDK_PACKAGE}@latest --save`);
189
197
  }
198
+ // Check if SDK version supports the Feedback Widget
199
+ let enableFeedbackWidget = false;
200
+ if (sdkVersion &&
201
+ (0, semver_1.fulfillsVersionRange)({
202
+ version: sdkVersion,
203
+ acceptableVersions: exports.FEEDBACK_WIDGET_SUPPORTED_SDK_RANGE,
204
+ canBeLatest: true,
205
+ })) {
206
+ // Ask if user wants to enable the Feedback Widget
207
+ enableFeedbackWidget = await (0, clack_1.abortIfCancelled)(prompts_1.default.confirm({
208
+ message: 'Do you want to enable the Feedback Widget to collect feedback from your users? (See https://docs.sentry.io/platforms/react-native/user-feedback/)',
209
+ }));
210
+ Sentry.setTag('enable-feedback-widget', enableFeedbackWidget);
211
+ if (enableFeedbackWidget) {
212
+ prompts_1.default.log.info(`The Feedback Widget will be enabled with default settings. You can show the widget by calling Sentry.showFeedbackWidget() in your code.`);
213
+ }
214
+ }
215
+ else if (sdkVersion) {
216
+ prompts_1.default.log.info(`The Feedback Widget is supported from Sentry React Native SDK version ${exports.FEEDBACK_WIDGET_SUPPORTED_SDK_RANGE}. Your version (${sdkVersion}) doesn't support it yet.`);
217
+ prompts_1.default.log.message(`To use the Feedback Widget, please upgrade your Sentry SDK: npm install ${exports.RN_SDK_PACKAGE}@latest --save`);
218
+ }
190
219
  await (0, telemetry_1.traceStep)('patch-app-js', () => (0, javascript_1.addSentryInit)({
191
220
  dsn: selectedProject.keys[0].dsn.public,
192
221
  enableSessionReplay,
222
+ enableFeedbackWidget,
193
223
  }));
194
224
  await (0, telemetry_1.traceStep)('patch-app-js-wrap', () => (0, javascript_1.wrapRootComponent)());
195
225
  if (isExpo) {
@@ -210,9 +240,7 @@ Or setup using ${chalk_1.default.cyan('https://docs.sentry.io/platforms/react-na
210
240
  Sentry.setTag('patch-android', true);
211
241
  await (0, telemetry_1.traceStep)('patch-android-files', () => patchAndroidFiles(cliConfig));
212
242
  }
213
- await (0, clack_1.runPrettierIfInstalled)({
214
- cwd: undefined,
215
- });
243
+ await (0, clack_1.runPrettierIfInstalled)({ cwd: undefined });
216
244
  const confirmedFirstException = await confirmFirstSentryException(sentryUrl, orgSlug, projectId);
217
245
  Sentry.setTag('user-confirmed-first-error', confirmedFirstException);
218
246
  if (confirmedFirstException) {