@sentry/wizard 3.5.0 → 3.6.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 (104) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/bin.ts +8 -9
  3. package/dist/bin.js +8 -5
  4. package/dist/bin.js.map +1 -1
  5. package/dist/lib/Constants.d.ts +2 -0
  6. package/dist/lib/Constants.js +5 -0
  7. package/dist/lib/Constants.js.map +1 -1
  8. package/dist/lib/Helper/Wizard.js +2 -0
  9. package/dist/lib/Helper/Wizard.js.map +1 -1
  10. package/dist/lib/Helper/__tests__/SentryCli.js +1 -0
  11. package/dist/lib/Helper/__tests__/SentryCli.js.map +1 -1
  12. package/dist/lib/Steps/ChooseIntegration.js +4 -0
  13. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  14. package/dist/lib/Steps/Integrations/Apple.d.ts +10 -0
  15. package/dist/lib/Steps/Integrations/Apple.js +92 -0
  16. package/dist/lib/Steps/Integrations/Apple.js.map +1 -0
  17. package/dist/lib/Steps/Integrations/NextJsShim.js +1 -0
  18. package/dist/lib/Steps/Integrations/NextJsShim.js.map +1 -1
  19. package/dist/lib/Steps/Integrations/SourceMapsShim.js +1 -0
  20. package/dist/lib/Steps/Integrations/SourceMapsShim.js.map +1 -1
  21. package/dist/lib/Steps/Integrations/SvelteKitShim.js +1 -0
  22. package/dist/lib/Steps/Integrations/SvelteKitShim.js.map +1 -1
  23. package/dist/package.json +2 -2
  24. package/dist/src/apple/apple-wizard.d.ts +2 -0
  25. package/dist/src/apple/apple-wizard.js +197 -0
  26. package/dist/src/apple/apple-wizard.js.map +1 -0
  27. package/dist/src/apple/code-tools.d.ts +1 -0
  28. package/dist/src/apple/code-tools.js +100 -0
  29. package/dist/src/apple/code-tools.js.map +1 -0
  30. package/dist/src/apple/templates.d.ts +4 -0
  31. package/dist/src/apple/templates.js +19 -0
  32. package/dist/src/apple/templates.js.map +1 -0
  33. package/dist/src/apple/xcode-manager.d.ts +4 -0
  34. package/dist/src/apple/xcode-manager.js +145 -0
  35. package/dist/src/apple/xcode-manager.js.map +1 -0
  36. package/dist/src/sourcemaps/sourcemaps-wizard.js +143 -71
  37. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  38. package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
  39. package/dist/src/sourcemaps/tools/angular.js +76 -0
  40. package/dist/src/sourcemaps/tools/angular.js.map +1 -0
  41. package/dist/src/sourcemaps/tools/esbuild.js +2 -1
  42. package/dist/src/sourcemaps/tools/esbuild.js.map +1 -1
  43. package/dist/src/sourcemaps/tools/rollup.js +2 -1
  44. package/dist/src/sourcemaps/tools/rollup.js.map +1 -1
  45. package/dist/src/sourcemaps/tools/sentry-cli.js +2 -1
  46. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  47. package/dist/src/sourcemaps/tools/vite.js +2 -1
  48. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  49. package/dist/src/sourcemaps/tools/webpack.js +2 -1
  50. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  51. package/dist/src/sourcemaps/utils/detect-tool.d.ts +3 -0
  52. package/dist/src/sourcemaps/utils/detect-tool.js +73 -0
  53. package/dist/src/sourcemaps/utils/detect-tool.js.map +1 -0
  54. package/dist/src/sourcemaps/utils/other-wizards.d.ts +4 -0
  55. package/dist/src/sourcemaps/utils/other-wizards.js +183 -0
  56. package/dist/src/sourcemaps/utils/other-wizards.js.map +1 -0
  57. package/dist/src/sourcemaps/utils/sdk-version.js +14 -13
  58. package/dist/src/sourcemaps/utils/sdk-version.js.map +1 -1
  59. package/dist/src/sveltekit/sveltekit-wizard.js +2 -1
  60. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  61. package/dist/src/telemetry.d.ts +1 -0
  62. package/dist/src/telemetry.js +7 -1
  63. package/dist/src/telemetry.js.map +1 -1
  64. package/dist/src/utils/bash.d.ts +3 -0
  65. package/dist/src/utils/bash.js +118 -0
  66. package/dist/src/utils/bash.js.map +1 -0
  67. package/dist/src/utils/clack-utils.d.ts +9 -8
  68. package/dist/src/utils/clack-utils.js +54 -21
  69. package/dist/src/utils/clack-utils.js.map +1 -1
  70. package/dist/src/utils/package-json.d.ts +19 -0
  71. package/dist/src/utils/package-json.js +29 -0
  72. package/dist/src/utils/package-json.js.map +1 -0
  73. package/dist/src/utils/types.d.ts +4 -0
  74. package/dist/src/utils/types.js.map +1 -1
  75. package/lib/Constants.ts +6 -0
  76. package/lib/Helper/Wizard.ts +3 -0
  77. package/lib/Helper/__tests__/SentryCli.ts +2 -1
  78. package/lib/Steps/ChooseIntegration.ts +4 -0
  79. package/lib/Steps/Integrations/Apple.ts +27 -0
  80. package/lib/Steps/Integrations/NextJsShim.ts +1 -0
  81. package/lib/Steps/Integrations/SourceMapsShim.ts +1 -0
  82. package/lib/Steps/Integrations/SvelteKitShim.ts +1 -0
  83. package/package-lock.json +8910 -0
  84. package/package.json +2 -2
  85. package/src/apple/apple-wizard.ts +150 -0
  86. package/src/apple/code-tools.ts +81 -0
  87. package/src/apple/templates.ts +39 -0
  88. package/src/apple/xcode-manager.ts +147 -0
  89. package/src/sourcemaps/sourcemaps-wizard.ts +156 -91
  90. package/src/sourcemaps/tools/angular.ts +42 -0
  91. package/src/sourcemaps/tools/esbuild.ts +1 -1
  92. package/src/sourcemaps/tools/rollup.ts +2 -4
  93. package/src/sourcemaps/tools/sentry-cli.ts +1 -1
  94. package/src/sourcemaps/tools/vite.ts +1 -1
  95. package/src/sourcemaps/tools/webpack.ts +1 -1
  96. package/src/sourcemaps/utils/detect-tool.ts +41 -0
  97. package/src/sourcemaps/utils/other-wizards.ts +148 -0
  98. package/src/sourcemaps/utils/sdk-version.ts +9 -16
  99. package/src/sveltekit/sveltekit-wizard.ts +1 -1
  100. package/src/telemetry.ts +8 -0
  101. package/src/utils/bash.ts +44 -0
  102. package/src/utils/clack-utils.ts +44 -37
  103. package/src/utils/package-json.ts +45 -0
  104. package/src/utils/types.ts +5 -0
@@ -9,6 +9,7 @@ import {
9
9
  askForSelfHosted,
10
10
  askForWizardLogin,
11
11
  confirmContinueEvenThoughNoGitRepo,
12
+ detectPackageManager,
12
13
  printWelcome,
13
14
  } from '../utils/clack-utils';
14
15
  import { isUnicodeSupported } from '../utils/vendor/is-unicorn-supported';
@@ -22,18 +23,26 @@ import { configureEsbuildPlugin } from './tools/esbuild';
22
23
  import { WizardOptions } from '../utils/types';
23
24
  import { configureCRASourcemapGenerationFlow } from './tools/create-react-app';
24
25
  import { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version';
25
-
26
- type SupportedTools =
27
- | 'webpack'
28
- | 'vite'
29
- | 'rollup'
30
- | 'esbuild'
31
- | 'tsc'
32
- | 'sentry-cli'
33
- | 'create-react-app';
26
+ import { traceStep, withTelemetry } from '../telemetry';
27
+ import { URL } from 'url';
28
+ import { checkIfMoreSuitableWizardExistsAndAskForRedirect } from './utils/other-wizards';
29
+ import { configureAngularSourcemapGenerationFlow } from './tools/angular';
30
+ import { detectUsedTool, SupportedTools } from './utils/detect-tool';
34
31
 
35
32
  export async function runSourcemapsWizard(
36
33
  options: WizardOptions,
34
+ ): Promise<void> {
35
+ return withTelemetry(
36
+ {
37
+ enabled: options.telemetryEnabled,
38
+ integration: 'sourcemaps',
39
+ },
40
+ () => runSourcemapsWizardWithTelemetry(options),
41
+ );
42
+ }
43
+
44
+ async function runSourcemapsWizardWithTelemetry(
45
+ options: WizardOptions,
37
46
  ): Promise<void> {
38
47
  printWelcome({
39
48
  wizardName: 'Sentry Source Maps Upload Configuration Wizard',
@@ -42,102 +51,75 @@ export async function runSourcemapsWizard(
42
51
  promoCode: options.promoCode,
43
52
  });
44
53
 
45
- await confirmContinueEvenThoughNoGitRepo();
46
-
47
- await ensureMinimumSdkVersionIsInstalled();
48
-
49
- const { url: sentryUrl, selfHosted } = await askForSelfHosted(options.url);
50
-
51
- const { projects, apiKeys } = await askForWizardLogin({
52
- promoCode: options.promoCode,
53
- url: sentryUrl,
54
- });
55
-
56
- const selectedProject = await askForProjectSelection(projects);
57
-
58
- const selectedTool = await askForUsedBundlerTool();
59
-
60
- Sentry.setTag('selected-tool', selectedTool);
61
-
62
- await startToolSetupFlow(selectedTool, {
63
- selfHosted,
64
- orgSlug: selectedProject.organization.slug,
65
- projectSlug: selectedProject.slug,
66
- url: sentryUrl,
67
- authToken: apiKeys.token,
68
- });
69
-
70
- clack.log.step(
71
- 'Add the Sentry authentication token as an environment variable to your CI setup:',
54
+ const moreSuitableWizard = await traceStep(
55
+ 'check-framework-wizard',
56
+ checkIfMoreSuitableWizardExistsAndAskForRedirect,
72
57
  );
58
+ if (moreSuitableWizard) {
59
+ await traceStep('run-framework-wizard', () => moreSuitableWizard(options));
60
+ return;
61
+ }
73
62
 
74
- // Intentially logging directly to console here so that the code can be copied/pasted directly
75
- // eslint-disable-next-line no-console
76
- console.log(
77
- chalk.greenBright(`
78
- SENTRY_AUTH_TOKEN=${apiKeys.token}
79
- `),
80
- );
63
+ await traceStep('detect-git', confirmContinueEvenThoughNoGitRepo);
81
64
 
82
- clack.log.warn(
83
- chalk.yellow('DO NOT commit this auth token to your repository!'),
65
+ await traceStep('check-sdk-version', ensureMinimumSdkVersionIsInstalled);
66
+
67
+ const { url: sentryUrl, selfHosted } = await traceStep(
68
+ 'ask-self-hosted',
69
+ () => askForSelfHosted(options.url),
84
70
  );
85
71
 
86
- const addedEnvVarToCI = await abortIfCancelled(
87
- clack.select({
88
- message: 'Did you configure CI as shown above?',
89
- options: [
90
- { label: 'Yes, continue!', value: true },
91
- {
92
- label: "I'll do it later...",
93
- value: false,
94
- hint: chalk.yellow(
95
- 'You need to set the auth token to upload source maps in CI',
96
- ),
97
- },
98
- ],
99
- initialValue: true,
72
+ const { projects, apiKeys } = await traceStep('login', () =>
73
+ askForWizardLogin({
74
+ promoCode: options.promoCode,
75
+ url: sentryUrl,
100
76
  }),
101
77
  );
102
78
 
103
- Sentry.setTag('added-env-var-to-ci', addedEnvVarToCI);
104
-
105
- if (!addedEnvVarToCI) {
106
- clack.log.info("Don't forget! :)");
107
- }
79
+ const selectedProject = await traceStep('select-project', () =>
80
+ askForProjectSelection(projects),
81
+ );
108
82
 
109
- const arrow = isUnicodeSupported() ? '' : '->';
83
+ const selectedTool = await traceStep('select-tool', askForUsedBundlerTool);
110
84
 
111
- clack.outro(`${chalk.green("That's it - everything is set up!")}
85
+ Sentry.setTag('selected-tool', selectedTool);
112
86
 
113
- ${chalk.cyan(`Validate your setup with the following Steps:
87
+ await traceStep('tool-setup', () =>
88
+ startToolSetupFlow(selectedTool, {
89
+ selfHosted,
90
+ orgSlug: selectedProject.organization.slug,
91
+ projectSlug: selectedProject.slug,
92
+ url: sentryUrl,
93
+ authToken: apiKeys.token,
94
+ }),
95
+ );
114
96
 
115
- 1. Build your application in ${chalk.bold('production mode')}.
116
- ${chalk.gray(
117
- `${arrow} You should see source map upload logs in your console.`,
118
- )}
119
- 2. Run your application and throw a test error.
120
- ${chalk.gray(`${arrow} The error should be visible in Sentry.`)}
121
- 3. Open the error in Sentry and verify that it's source-mapped.
122
- ${chalk.gray(
123
- `${arrow} The stack trace should show your original source code.`,
124
- )}
125
- `)}
126
- ${chalk.dim(
127
- `If you encounter any issues, please refer to the Troubleshooting Guide:
128
- https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js
97
+ await traceStep('ci-setup', () => setupCi(apiKeys.token));
129
98
 
130
- If the guide doesn't help or you encounter a bug, please let us know:
131
- https://github.com/getsentry/sentry-javascript/issues`,
132
- )}
133
- `);
99
+ traceStep('outro', () =>
100
+ printOutro(
101
+ sentryUrl,
102
+ selectedProject.organization.slug,
103
+ selectedProject.id,
104
+ ),
105
+ );
134
106
  }
135
107
 
136
108
  async function askForUsedBundlerTool(): Promise<SupportedTools> {
137
109
  const selectedTool: SupportedTools | symbol = await abortIfCancelled(
138
110
  clack.select({
139
- message: 'Which bundler or build tool are you using?',
111
+ message: 'Which framework, bundler or build tool are you using?',
140
112
  options: [
113
+ {
114
+ label: 'Angular',
115
+ value: 'angular',
116
+ hint: 'Select this option if you are using Angular.',
117
+ },
118
+ {
119
+ label: 'Create React App',
120
+ value: 'create-react-app',
121
+ hint: 'Select this option if you set up your app with Create React App.',
122
+ },
141
123
  {
142
124
  label: 'Webpack',
143
125
  value: 'webpack',
@@ -163,17 +145,13 @@ async function askForUsedBundlerTool(): Promise<SupportedTools> {
163
145
  value: 'tsc',
164
146
  hint: 'Configure source maps when using tsc as build tool',
165
147
  },
166
- {
167
- label: 'Create React App',
168
- value: 'create-react-app',
169
- hint: 'Select this option if you set up your app with Create React App.',
170
- },
171
148
  {
172
149
  label: 'None of the above',
173
150
  value: 'sentry-cli',
174
151
  hint: 'This will configure source maps upload for you using sentry-cli',
175
152
  },
176
153
  ],
154
+ initialValue: await detectUsedTool(),
177
155
  }),
178
156
  );
179
157
 
@@ -203,8 +181,95 @@ async function startToolSetupFlow(
203
181
  case 'create-react-app':
204
182
  await configureSentryCLI(options, configureCRASourcemapGenerationFlow);
205
183
  break;
184
+ case 'angular':
185
+ await configureSentryCLI(
186
+ options,
187
+ configureAngularSourcemapGenerationFlow,
188
+ );
189
+ break;
206
190
  default:
207
191
  await configureSentryCLI(options);
208
192
  break;
209
193
  }
210
194
  }
195
+
196
+ async function setupCi(authToken: string) {
197
+ clack.log.step(
198
+ 'Add the Sentry authentication token as an environment variable to your CI setup:',
199
+ );
200
+
201
+ // Intentially logging directly to console here so that the code can be copied/pasted directly
202
+ // eslint-disable-next-line no-console
203
+ console.log(
204
+ chalk.greenBright(`
205
+ SENTRY_AUTH_TOKEN=${authToken}
206
+ `),
207
+ );
208
+
209
+ clack.log.warn(
210
+ chalk.yellow('DO NOT commit this auth token to your repository!'),
211
+ );
212
+
213
+ const addedEnvVarToCI = await abortIfCancelled(
214
+ clack.select({
215
+ message: 'Did you configure CI as shown above?',
216
+ options: [
217
+ { label: 'Yes, continue!', value: true },
218
+ {
219
+ label: "I'll do it later...",
220
+ value: false,
221
+ hint: chalk.yellow(
222
+ 'You need to set the auth token to upload source maps in CI',
223
+ ),
224
+ },
225
+ ],
226
+ initialValue: true,
227
+ }),
228
+ );
229
+
230
+ Sentry.setTag('added-env-var-to-ci', addedEnvVarToCI);
231
+
232
+ if (!addedEnvVarToCI) {
233
+ clack.log.info("Don't forget! :)");
234
+ }
235
+ }
236
+
237
+ function printOutro(url: string, orgSlug: string, projectId: string) {
238
+ const pacMan = detectPackageManager() || 'npm';
239
+ const buildCommand = `'${pacMan}${pacMan === 'npm' ? ' run' : ''} build'`;
240
+
241
+ const urlObject = new URL(url);
242
+ urlObject.host = `${orgSlug}.${urlObject.host}`;
243
+ urlObject.pathname = '/issues/';
244
+ urlObject.searchParams.set('project', projectId);
245
+
246
+ const issueStreamUrl = urlObject.toString();
247
+
248
+ const arrow = isUnicodeSupported() ? '→' : '->';
249
+
250
+ clack.outro(`${chalk.green("That's it - everything is set up!")}
251
+
252
+ ${chalk.cyan(`Test and validate your setup locally with the following Steps:
253
+
254
+ 1. Build your application in ${chalk.bold('production mode')}.
255
+ ${chalk.gray(`${arrow} For example, run ${chalk.bold(buildCommand)}.`)}
256
+ ${chalk.gray(
257
+ `${arrow} You should see source map upload logs in your console.`,
258
+ )}
259
+ 2. Run your application and throw a test error.
260
+ ${chalk.gray(`${arrow} The error should appear in Sentry:`)}
261
+ ${chalk.gray(`${arrow} ${issueStreamUrl}`)}
262
+ 3. Open the error in Sentry and verify that it's source-mapped.
263
+ ${chalk.gray(
264
+ `${arrow} The stack trace should show your original source code.`,
265
+ )}
266
+ `)}
267
+ ${chalk.dim(
268
+ `If you encounter any issues, please refer to the Troubleshooting Guide:
269
+ https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js
270
+
271
+ If the guide doesn't help or you encounter a bug, please let us know:
272
+ https://github.com/getsentry/sentry-javascript/issues`,
273
+ )}
274
+ `);
275
+ }
@@ -0,0 +1,42 @@
1
+ // @ts-ignore - clack is ESM and TS complains about that. It works though
2
+ import clack from '@clack/prompts';
3
+ import chalk from 'chalk';
4
+ import { abortIfCancelled } from '../../utils/clack-utils';
5
+
6
+ const angularJsonTemplate = chalk.gray(`{
7
+ "projects": {
8
+ "your-project": {
9
+ "architect": {
10
+ "build": {
11
+ "options": {
12
+ ${chalk.greenBright(`"sourceMap": true`)}
13
+ },
14
+ },
15
+ }
16
+ }
17
+ }
18
+ }`);
19
+
20
+ export async function configureAngularSourcemapGenerationFlow(): Promise<void> {
21
+ clack.log.info(
22
+ `Enable generating source maps in your ${chalk.bold('angular.json')} file:`,
23
+ );
24
+
25
+ // Intentially logging directly to console here so that the code can be copied/pasted directly
26
+ // eslint-disable-next-line no-console
27
+ console.log(angularJsonTemplate);
28
+
29
+ await abortIfCancelled(
30
+ clack.select({
31
+ message: `Verify that you are generating source maps when building your Angular app.`,
32
+ options: [
33
+ {
34
+ label: 'I checked!',
35
+ hint: 'My build output folder contains .js.map files after a build.',
36
+ value: true,
37
+ },
38
+ ],
39
+ initialValue: true,
40
+ }),
41
+ );
42
+ }
@@ -5,9 +5,9 @@ import {
5
5
  abortIfCancelled,
6
6
  addDotEnvSentryBuildPluginFile,
7
7
  getPackageDotJson,
8
- hasPackageInstalled,
9
8
  installPackage,
10
9
  } from '../../utils/clack-utils';
10
+ import { hasPackageInstalled } from '../../utils/package-json';
11
11
 
12
12
  import {
13
13
  SourceMapUploadToolConfigurationFunction,
@@ -5,9 +5,9 @@ import {
5
5
  abortIfCancelled,
6
6
  addDotEnvSentryBuildPluginFile,
7
7
  getPackageDotJson,
8
- hasPackageInstalled,
9
8
  installPackage,
10
9
  } from '../../utils/clack-utils';
10
+ import { hasPackageInstalled } from '../../utils/package-json';
11
11
 
12
12
  import {
13
13
  SourceMapUploadToolConfigurationFunction,
@@ -49,9 +49,7 @@ export const configureRollupPlugin: SourceMapUploadToolConfigurationFunction =
49
49
  ),
50
50
  });
51
51
 
52
- clack.log.step(
53
- `Add the following code to your rollup config:`,
54
- );
52
+ clack.log.step(`Add the following code to your rollup config:`);
55
53
 
56
54
  // Intentially logging directly to console here so that the code can be copied/pasted directly
57
55
  // eslint-disable-next-line no-console
@@ -8,11 +8,11 @@ import {
8
8
  abortIfCancelled,
9
9
  addSentryCliRc,
10
10
  getPackageDotJson,
11
- hasPackageInstalled,
12
11
  installPackage,
13
12
  } from '../../utils/clack-utils';
14
13
 
15
14
  import { SourceMapUploadToolConfigurationOptions } from './types';
15
+ import { hasPackageInstalled } from '../../utils/package-json';
16
16
 
17
17
  export async function configureSentryCLI(
18
18
  options: SourceMapUploadToolConfigurationOptions,
@@ -5,9 +5,9 @@ import {
5
5
  abortIfCancelled,
6
6
  addDotEnvSentryBuildPluginFile,
7
7
  getPackageDotJson,
8
- hasPackageInstalled,
9
8
  installPackage,
10
9
  } from '../../utils/clack-utils';
10
+ import { hasPackageInstalled } from '../../utils/package-json';
11
11
 
12
12
  import {
13
13
  SourceMapUploadToolConfigurationFunction,
@@ -5,9 +5,9 @@ import {
5
5
  abortIfCancelled,
6
6
  addDotEnvSentryBuildPluginFile,
7
7
  getPackageDotJson,
8
- hasPackageInstalled,
9
8
  installPackage,
10
9
  } from '../../utils/clack-utils';
10
+ import { hasPackageInstalled } from '../../utils/package-json';
11
11
 
12
12
  import {
13
13
  SourceMapUploadToolConfigurationFunction,
@@ -0,0 +1,41 @@
1
+ import { getPackageDotJson } from '../../utils/clack-utils';
2
+ import { findInstalledPackageFromList } from '../../utils/package-json';
3
+
4
+ export type SupportedTools =
5
+ | 'webpack'
6
+ | 'vite'
7
+ | 'rollup'
8
+ | 'esbuild'
9
+ | 'tsc'
10
+ | 'sentry-cli'
11
+ | 'create-react-app'
12
+ | 'angular';
13
+
14
+ // A map of package names pointing to the tool slug.
15
+ // The order is important, because we want to detect the most specific tool first.
16
+ // For instance, webpack needs to come before tsc because typescript c
17
+ // Similarly
18
+ export const TOOL_PACKAGE_MAP: Record<string, SupportedTools> = {
19
+ '@angular/core': 'angular',
20
+ 'create-react-app': 'create-react-app',
21
+ webpack: 'webpack',
22
+ vite: 'vite',
23
+ esbuild: 'esbuild',
24
+ rollup: 'rollup',
25
+ typescript: 'tsc',
26
+ };
27
+
28
+ export async function detectUsedTool(): Promise<SupportedTools> {
29
+ const packageJson = await getPackageDotJson();
30
+
31
+ const foundToolPackage = findInstalledPackageFromList(
32
+ Object.keys(TOOL_PACKAGE_MAP),
33
+ packageJson,
34
+ );
35
+
36
+ if (foundToolPackage) {
37
+ return TOOL_PACKAGE_MAP[foundToolPackage.name];
38
+ }
39
+
40
+ return 'sentry-cli';
41
+ }
@@ -0,0 +1,148 @@
1
+ // @ts-ignore - clack is ESM and TS complains about that. It works though
2
+ import clack from '@clack/prompts';
3
+ import chalk from 'chalk';
4
+ import { runNextjsWizard } from '../../nextjs/nextjs-wizard';
5
+ import { runSvelteKitWizard } from '../../sveltekit/sveltekit-wizard';
6
+
7
+ import {
8
+ abort,
9
+ abortIfCancelled,
10
+ getPackageDotJson,
11
+ } from '../../utils/clack-utils';
12
+ import {
13
+ findInstalledPackageFromList,
14
+ hasPackageInstalled,
15
+ } from '../../utils/package-json';
16
+
17
+ import * as Sentry from '@sentry/node';
18
+ import { WizardOptions } from '../../utils/types';
19
+
20
+ type WizardFunction = (options: WizardOptions) => Promise<void>;
21
+
22
+ type FrameworkInfo = {
23
+ frameworkName: string;
24
+ frameworkSlug: string;
25
+ frameworkPackage: string;
26
+ sourcemapsDocsLink: string;
27
+ wizard: WizardFunction;
28
+ };
29
+
30
+ const sdkMap: Record<string, FrameworkInfo> = {
31
+ '@sentry/nextjs': {
32
+ frameworkName: 'Next.js',
33
+ frameworkSlug: 'nextjs',
34
+ frameworkPackage: 'next',
35
+ sourcemapsDocsLink:
36
+ 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-source-maps',
37
+ wizard: runNextjsWizard,
38
+ },
39
+ '@sentry/sveltekit': {
40
+ frameworkName: 'SvelteKit',
41
+ frameworkSlug: 'sveltekit',
42
+ frameworkPackage: '@sveltejs/kit',
43
+ sourcemapsDocsLink:
44
+ 'https://docs.sentry.io/platforms/javascript/guides/sveltekit/manual-setup/#configure-source-maps-upload',
45
+ wizard: runSvelteKitWizard,
46
+ },
47
+ };
48
+
49
+ export async function checkIfMoreSuitableWizardExistsAndAskForRedirect(): Promise<
50
+ WizardFunction | undefined
51
+ > {
52
+ const sdkName = await checkIfMoreSuitableWizardExists();
53
+
54
+ if (!sdkName) {
55
+ return undefined;
56
+ }
57
+
58
+ return await askForRedirect(sdkName);
59
+ }
60
+
61
+ async function checkIfMoreSuitableWizardExists(): Promise<string | undefined> {
62
+ Sentry.setTag('using-wrong-wizard', false);
63
+
64
+ const packageJson = await getPackageDotJson();
65
+
66
+ const installedSdkPackage = findInstalledPackageFromList(
67
+ Object.keys(sdkMap),
68
+ packageJson,
69
+ );
70
+
71
+ if (!installedSdkPackage) {
72
+ return undefined;
73
+ }
74
+
75
+ const sdkPackageName = installedSdkPackage.name;
76
+
77
+ const { frameworkPackage } = sdkMap[sdkPackageName];
78
+
79
+ if (!hasPackageInstalled(frameworkPackage, packageJson)) {
80
+ // The user has installed the SDK but not the framework.
81
+ // Maybe it's a false positive and the user is using a different framework.
82
+ // Let's not redirect them to the framework wizard in that case.
83
+ return undefined;
84
+ }
85
+
86
+ Sentry.setTag('using-wrong-wizard', true);
87
+
88
+ return sdkPackageName;
89
+ }
90
+
91
+ async function askForRedirect(
92
+ sdkName: string,
93
+ ): Promise<WizardFunction | undefined> {
94
+ const { frameworkName, sourcemapsDocsLink, frameworkSlug, wizard } =
95
+ sdkMap[sdkName];
96
+
97
+ clack.log.warn(
98
+ `${chalk.yellow(
99
+ `It seems like you're using this wizard in a ${frameworkName} project.`,
100
+ )}
101
+
102
+ We recommend using our dedicated ${frameworkName} wizard instead of this wizard.
103
+ The ${frameworkName} wizard will set up our ${sdkName} SDK and also configure uploading source maps for you.
104
+
105
+ If you already tried the ${frameworkName} wizard and it didn't work for you, check out the following guides:
106
+
107
+ Manual source maps configuration for ${frameworkName}:
108
+ ${sourcemapsDocsLink}
109
+
110
+ Troubleshooting Source Maps:
111
+ https://docs.sentry.io/platforms/javascript/guides/${frameworkSlug}/sourcemaps/troubleshooting_js/
112
+ `,
113
+ );
114
+
115
+ const nextStep: 'redirect' | 'continue' | 'stop' = await abortIfCancelled(
116
+ clack.select({
117
+ message: `Do you want to run the ${frameworkName} wizard now?`,
118
+ options: [
119
+ {
120
+ label: 'Yes',
121
+ value: 'redirect',
122
+ hint: `${chalk.green('Recommended')}`,
123
+ },
124
+ {
125
+ label: 'No, continue with this wizard',
126
+ value: 'continue',
127
+ },
128
+ {
129
+ label: "No, I'll check out the guides ",
130
+ value: 'stop',
131
+ hint: 'Exit this wizard',
132
+ },
133
+ ],
134
+ }),
135
+ );
136
+
137
+ Sentry.setTag('wrong-wizard-decision', nextStep);
138
+
139
+ switch (nextStep) {
140
+ case 'redirect':
141
+ return wizard;
142
+ case 'stop':
143
+ await abort('Exiting Wizard', 0);
144
+ break;
145
+ default:
146
+ return undefined;
147
+ }
148
+ }
@@ -5,11 +5,11 @@ import { minVersion, satisfies } from 'semver';
5
5
  import {
6
6
  abortIfCancelled,
7
7
  getPackageDotJson,
8
- getPackageVersion,
9
8
  installPackage,
10
9
  } from '../../utils/clack-utils';
11
10
 
12
11
  import * as Sentry from '@sentry/node';
12
+ import { findInstalledPackageFromList } from '../../utils/package-json';
13
13
 
14
14
  const MINIMUM_DEBUG_ID_SDK_VERSION = '7.47.0';
15
15
 
@@ -36,12 +36,7 @@ const SENTRY_SDK_PACKAGE_NAMES = [
36
36
  // Base SDKs
37
37
  '@sentry/browser',
38
38
  '@sentry/node',
39
- ] as const;
40
-
41
- type SdkPackage = {
42
- name: (typeof SENTRY_SDK_PACKAGE_NAMES)[number];
43
- version: string;
44
- };
39
+ ];
45
40
 
46
41
  /**
47
42
  * Check for a minimum SDK version and prompt the user to upgrade if necessary.
@@ -57,15 +52,10 @@ type SdkPackage = {
57
52
  * -> We tell users to manually upgrade (migrate between majors)
58
53
  */
59
54
  export async function ensureMinimumSdkVersionIsInstalled(): Promise<void> {
60
- const packageJson = await getPackageDotJson();
61
-
62
- const installedSdkPackages = SENTRY_SDK_PACKAGE_NAMES.map((packageName) => ({
63
- name: packageName,
64
- version: getPackageVersion(packageName, packageJson),
65
- })).filter((sdkPackage): sdkPackage is SdkPackage => !!sdkPackage.version);
66
-
67
- const installedSdkPackage =
68
- installedSdkPackages.length > 0 && installedSdkPackages[0];
55
+ const installedSdkPackage = findInstalledPackageFromList(
56
+ SENTRY_SDK_PACKAGE_NAMES,
57
+ await getPackageDotJson(),
58
+ );
69
59
 
70
60
  // Case 1:
71
61
  if (!installedSdkPackage) {
@@ -75,6 +65,8 @@ export async function ensureMinimumSdkVersionIsInstalled(): Promise<void> {
75
65
  const { name: installedSdkName, version: installedSdkVersionOrRange } =
76
66
  installedSdkPackage;
77
67
 
68
+ Sentry.setTag('installed-sdk', installedSdkName);
69
+
78
70
  const minInstalledVersion = getMinInstalledVersion(
79
71
  installedSdkVersionOrRange,
80
72
  installedSdkName,
@@ -198,6 +190,7 @@ async function handleAutoUpdateSdk(packageName: string) {
198
190
 
199
191
  async function handleNoSdkInstalled(): Promise<void> {
200
192
  Sentry.setTag('initial-sdk-version', 'none');
193
+ Sentry.setTag('installed-sdk', 'none');
201
194
 
202
195
  clack.log.warn(
203
196
  `${chalk.yellowBright(
@@ -9,10 +9,10 @@ import {
9
9
  confirmContinueEvenThoughNoGitRepo,
10
10
  ensurePackageIsInstalled,
11
11
  getPackageDotJson,
12
- hasPackageInstalled,
13
12
  installPackage,
14
13
  printWelcome,
15
14
  } from '../utils/clack-utils';
15
+ import { hasPackageInstalled } from '../utils/package-json';
16
16
  import { WizardOptions } from '../utils/types';
17
17
  import { createExamplePage } from './sdk-example';
18
18
  import { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup';