@sentry/wizard 3.7.1 → 3.8.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 (83) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/lib/Helper/__tests__/MergeConfig.js.map +1 -1
  3. package/dist/lib/Steps/ChooseIntegration.js +12 -26
  4. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  5. package/dist/lib/Steps/Integrations/Cordova.js.map +1 -1
  6. package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
  7. package/dist/lib/Steps/Integrations/MobileProject.js.map +1 -1
  8. package/dist/lib/Steps/Integrations/ReactNative.js +2 -2
  9. package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
  10. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js +5 -6
  11. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js.map +1 -1
  12. package/dist/package.json +3 -3
  13. package/dist/src/apple/apple-wizard.js +31 -2
  14. package/dist/src/apple/apple-wizard.js.map +1 -1
  15. package/dist/src/apple/cocoapod.d.ts +2 -0
  16. package/dist/src/apple/cocoapod.js +122 -0
  17. package/dist/src/apple/cocoapod.js.map +1 -0
  18. package/dist/src/apple/code-tools.js +22 -12
  19. package/dist/src/apple/code-tools.js.map +1 -1
  20. package/dist/src/apple/fastlane.d.ts +2 -0
  21. package/dist/src/apple/fastlane.js +179 -0
  22. package/dist/src/apple/fastlane.js.map +1 -0
  23. package/dist/src/apple/templates.d.ts +1 -0
  24. package/dist/src/apple/templates.js +7 -3
  25. package/dist/src/apple/templates.js.map +1 -1
  26. package/dist/src/apple/xcode-manager.d.ts +1 -1
  27. package/dist/src/apple/xcode-manager.js +35 -28
  28. package/dist/src/apple/xcode-manager.js.map +1 -1
  29. package/dist/src/nextjs/nextjs-wizard.js +71 -81
  30. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  31. package/dist/src/sourcemaps/sourcemaps-wizard.js +61 -46
  32. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  33. package/dist/src/sourcemaps/tools/nextjs.d.ts +3 -0
  34. package/dist/src/sourcemaps/tools/nextjs.js +135 -0
  35. package/dist/src/sourcemaps/tools/nextjs.js.map +1 -0
  36. package/dist/src/sourcemaps/tools/sentry-cli.js +120 -16
  37. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  38. package/dist/src/sourcemaps/utils/detect-tool.d.ts +1 -1
  39. package/dist/src/sourcemaps/utils/detect-tool.js +1 -0
  40. package/dist/src/sourcemaps/utils/detect-tool.js.map +1 -1
  41. package/dist/src/sourcemaps/utils/other-wizards.js +35 -12
  42. package/dist/src/sourcemaps/utils/other-wizards.js.map +1 -1
  43. package/dist/src/sveltekit/sentry-cli-setup.d.ts +1 -1
  44. package/dist/src/sveltekit/sentry-cli-setup.js.map +1 -1
  45. package/dist/src/sveltekit/sveltekit-wizard.js +14 -8
  46. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  47. package/dist/src/utils/bash.d.ts +2 -1
  48. package/dist/src/utils/bash.js +14 -2
  49. package/dist/src/utils/bash.js.map +1 -1
  50. package/dist/src/utils/clack-utils.d.ts +7 -14
  51. package/dist/src/utils/clack-utils.js +46 -2
  52. package/dist/src/utils/clack-utils.js.map +1 -1
  53. package/dist/src/utils/package-json.d.ts +1 -1
  54. package/dist/src/utils/package-json.js.map +1 -1
  55. package/dist/src/utils/types.d.ts +24 -0
  56. package/dist/src/utils/types.js.map +1 -1
  57. package/lib/Helper/__tests__/MergeConfig.ts +9 -4
  58. package/lib/Steps/ChooseIntegration.ts +13 -3
  59. package/lib/Steps/Integrations/Cordova.ts +3 -3
  60. package/lib/Steps/Integrations/Electron.ts +1 -2
  61. package/lib/Steps/Integrations/MobileProject.ts +1 -1
  62. package/lib/Steps/Integrations/ReactNative.ts +16 -14
  63. package/lib/Steps/Integrations/__tests__/ReactNative.ts +24 -15
  64. package/package-lock.json +2 -2
  65. package/package.json +3 -3
  66. package/src/apple/apple-wizard.ts +35 -3
  67. package/src/apple/cocoapod.ts +57 -0
  68. package/src/apple/code-tools.ts +80 -57
  69. package/src/apple/fastlane.ts +160 -0
  70. package/src/apple/templates.ts +26 -10
  71. package/src/apple/xcode-manager.ts +137 -120
  72. package/src/nextjs/nextjs-wizard.ts +4 -13
  73. package/src/sourcemaps/sourcemaps-wizard.ts +40 -28
  74. package/src/sourcemaps/tools/nextjs.ts +114 -0
  75. package/src/sourcemaps/tools/sentry-cli.ts +134 -8
  76. package/src/sourcemaps/utils/detect-tool.ts +3 -1
  77. package/src/sourcemaps/utils/other-wizards.ts +32 -13
  78. package/src/sveltekit/sentry-cli-setup.ts +1 -1
  79. package/src/sveltekit/sveltekit-wizard.ts +3 -0
  80. package/src/utils/bash.ts +43 -30
  81. package/src/utils/clack-utils.ts +42 -14
  82. package/src/utils/package-json.ts +1 -1
  83. package/src/utils/types.ts +22 -0
@@ -7,14 +7,18 @@ import * as fs from 'fs';
7
7
  import {
8
8
  abortIfCancelled,
9
9
  addSentryCliRc,
10
+ detectPackageManager,
10
11
  getPackageDotJson,
11
12
  installPackage,
12
13
  } from '../../utils/clack-utils';
13
14
 
14
15
  import { SourceMapUploadToolConfigurationOptions } from './types';
15
16
  import { hasPackageInstalled, PackageDotJson } from '../../utils/package-json';
17
+ import { traceStep } from '../../telemetry';
16
18
 
17
- const NPM_SCRIPT_NAME = 'sentry:sourcemaps';
19
+ const SENTRY_NPM_SCRIPT_NAME = 'sentry:sourcemaps';
20
+
21
+ let addedToBuildCommand = false;
18
22
 
19
23
  export async function configureSentryCLI(
20
24
  options: SourceMapUploadToolConfigurationOptions,
@@ -80,14 +84,32 @@ export async function configureSentryCLI(
80
84
  relativePosixArtifactPath,
81
85
  );
82
86
 
87
+ if (await askShouldAddToBuildCommand()) {
88
+ await traceStep('sentry-cli-add-to-build-cmd', () =>
89
+ addSentryCommandToBuildCommand(packageDotJson),
90
+ );
91
+ } else {
92
+ clack.log.info(
93
+ `No problem, just make sure to run this script ${chalk.bold(
94
+ 'after',
95
+ )} building your application but ${chalk.bold('before')} deploying!`,
96
+ );
97
+ }
98
+
83
99
  await addSentryCliRc(options.authToken);
84
100
  }
85
101
 
86
102
  export async function setupNpmScriptInCI(): Promise<void> {
103
+ if (addedToBuildCommand) {
104
+ // No need to tell users to add it manually to their CI
105
+ // if the script is already added to the build command
106
+ return;
107
+ }
108
+
87
109
  const addedToCI = await abortIfCancelled(
88
110
  clack.select({
89
111
  message: `Add a step to your CI pipeline that runs the ${chalk.cyan(
90
- NPM_SCRIPT_NAME,
112
+ SENTRY_NPM_SCRIPT_NAME,
91
113
  )} script ${chalk.bold('right after')} building your application.`,
92
114
  options: [
93
115
  { label: 'I did, continue!', value: true },
@@ -95,7 +117,9 @@ export async function setupNpmScriptInCI(): Promise<void> {
95
117
  label: "I'll do it later...",
96
118
  value: false,
97
119
  hint: chalk.yellow(
98
- 'You need to run the command after each build for source maps to work properly.',
120
+ `You need to run ${chalk.cyan(
121
+ SENTRY_NPM_SCRIPT_NAME,
122
+ )} after each build for source maps to work properly.`,
99
123
  ),
100
124
  },
101
125
  ],
@@ -126,7 +150,7 @@ async function createAndAddNpmScript(
126
150
  } ${relativePosixArtifactPath}`;
127
151
 
128
152
  packageDotJson.scripts = packageDotJson.scripts || {};
129
- packageDotJson.scripts[NPM_SCRIPT_NAME] = sentryCliNpmScript;
153
+ packageDotJson.scripts[SENTRY_NPM_SCRIPT_NAME] = sentryCliNpmScript;
130
154
 
131
155
  await fs.promises.writeFile(
132
156
  path.join(process.cwd(), 'package.json'),
@@ -134,11 +158,113 @@ async function createAndAddNpmScript(
134
158
  );
135
159
 
136
160
  clack.log.info(
137
- `Added a ${chalk.cyan(NPM_SCRIPT_NAME)} script to your ${chalk.cyan(
161
+ `Added a ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(
138
162
  'package.json',
139
- )}. Make sure to run this script ${chalk.bold(
140
- 'after',
141
- )} building your application but ${chalk.bold('before')} deploying!`,
163
+ )}.`,
164
+ );
165
+ }
166
+
167
+ async function askShouldAddToBuildCommand(): Promise<boolean> {
168
+ const shouldAddToBuildCommand = await abortIfCancelled(
169
+ clack.select({
170
+ message: `Do you want to automatically run the ${chalk.cyan(
171
+ SENTRY_NPM_SCRIPT_NAME,
172
+ )} script after each production build?`,
173
+ options: [
174
+ {
175
+ label: 'Yes',
176
+ value: true,
177
+ hint: 'This will modify your prod build comamnd',
178
+ },
179
+ { label: 'No', value: false },
180
+ ],
181
+ initialValue: true,
182
+ }),
183
+ );
184
+
185
+ Sentry.setTag('modify-build-command', shouldAddToBuildCommand);
186
+
187
+ return shouldAddToBuildCommand;
188
+ }
189
+
190
+ /**
191
+ * Add the sentry:sourcemaps command to the prod build command in the package.json
192
+ * - Detect the user's build command
193
+ * - Append the sentry:sourcemaps command to it
194
+ *
195
+ * @param packageDotJson The package.json which will be modified.
196
+ */
197
+ async function addSentryCommandToBuildCommand(
198
+ packageDotJson: PackageDotJson,
199
+ ): Promise<void> {
200
+ // This usually shouldn't happen because earlier we added the
201
+ // SENTRY_NPM_SCRIPT_NAME script but just to be sure
202
+ packageDotJson.scripts = packageDotJson.scripts || {};
203
+
204
+ const allNpmScripts = Object.keys(packageDotJson.scripts).filter(
205
+ (s) => s !== SENTRY_NPM_SCRIPT_NAME,
206
+ );
207
+
208
+ const pacMan = detectPackageManager() || 'npm';
209
+
210
+ // Heuristic to pre-select the build command:
211
+ // Often, 'build' is the prod build command, so we favour it.
212
+ // If it's not there, commands that include 'build' might be the prod build command.
213
+ let buildCommand =
214
+ packageDotJson.scripts.build ||
215
+ allNpmScripts.find((s) => s.toLocaleLowerCase().includes('build'));
216
+
217
+ const isProdBuildCommand =
218
+ !!buildCommand &&
219
+ (await abortIfCancelled(
220
+ clack.confirm({
221
+ message: `Is ${chalk.cyan(
222
+ `${pacMan} run ${buildCommand}`,
223
+ )} your production build command?`,
224
+ }),
225
+ ));
226
+
227
+ if (allNpmScripts.length && (!buildCommand || !isProdBuildCommand)) {
228
+ buildCommand = await abortIfCancelled(
229
+ clack.select({
230
+ message: `Which ${pacMan} command in your ${chalk.cyan(
231
+ 'package.json',
232
+ )} builds your application for production?`,
233
+ options: allNpmScripts
234
+ .map((script) => ({
235
+ label: script,
236
+ value: script,
237
+ }))
238
+ .concat({ label: 'None of the above', value: 'none' }),
239
+ }),
240
+ );
241
+ }
242
+
243
+ if (!buildCommand || buildCommand === 'none') {
244
+ clack.log.warn(
245
+ `We can only add the ${chalk.cyan(
246
+ SENTRY_NPM_SCRIPT_NAME,
247
+ )} script to another \`script\` in your ${chalk.cyan('package.json')}.
248
+ Please add it manually to your prod build command.`,
249
+ );
250
+ return;
251
+ }
252
+
253
+ packageDotJson.scripts[
254
+ buildCommand
255
+ ] = `${buildCommand} && ${pacMan} run ${SENTRY_NPM_SCRIPT_NAME}`;
256
+
257
+ await fs.promises.writeFile(
258
+ path.join(process.cwd(), 'package.json'),
259
+ JSON.stringify(packageDotJson, null, 2),
260
+ );
261
+
262
+ addedToBuildCommand = true;
263
+
264
+ clack.log.info(
265
+ `Added ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(
266
+ buildCommand,
267
+ )} command.`,
142
268
  );
143
269
  }
144
270
 
@@ -9,7 +9,8 @@ export type SupportedTools =
9
9
  | 'tsc'
10
10
  | 'sentry-cli'
11
11
  | 'create-react-app'
12
- | 'angular';
12
+ | 'angular'
13
+ | 'nextjs';
13
14
 
14
15
  // A map of package names pointing to the tool slug.
15
16
  // The order is important, because we want to detect the most specific tool first.
@@ -18,6 +19,7 @@ export type SupportedTools =
18
19
  export const TOOL_PACKAGE_MAP: Record<string, SupportedTools> = {
19
20
  '@angular/core': 'angular',
20
21
  'create-react-app': 'create-react-app',
22
+ next: 'nextjs',
21
23
  webpack: 'webpack',
22
24
  vite: 'vite',
23
25
  esbuild: 'esbuild',
@@ -1,7 +1,6 @@
1
1
  // @ts-ignore - clack is ESM and TS complains about that. It works though
2
2
  import clack from '@clack/prompts';
3
3
  import chalk from 'chalk';
4
- import { runNextjsWizard } from '../../nextjs/nextjs-wizard';
5
4
  import { runSvelteKitWizard } from '../../sveltekit/sveltekit-wizard';
6
5
 
7
6
  import {
@@ -17,33 +16,37 @@ import {
17
16
  import * as Sentry from '@sentry/node';
18
17
  import { WizardOptions } from '../../utils/types';
19
18
 
19
+ import * as childProcess from 'child_process';
20
+
20
21
  type WizardFunction = (options: WizardOptions) => Promise<void>;
21
22
 
22
23
  type FrameworkInfo = {
23
24
  frameworkName: string;
24
- frameworkSlug: string;
25
25
  frameworkPackage: string;
26
+ troubleshootingDocsLink: string;
26
27
  sourcemapsDocsLink: string;
27
28
  wizard: WizardFunction;
28
29
  };
29
30
 
30
31
  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
32
  '@sentry/sveltekit': {
40
33
  frameworkName: 'SvelteKit',
41
- frameworkSlug: 'sveltekit',
42
34
  frameworkPackage: '@sveltejs/kit',
43
35
  sourcemapsDocsLink:
44
36
  'https://docs.sentry.io/platforms/javascript/guides/sveltekit/manual-setup/#configure-source-maps-upload',
37
+ troubleshootingDocsLink:
38
+ 'https://docs.sentry.io/platforms/javascript/guides/sveltekit/sourcemaps/troubleshooting_js/',
45
39
  wizard: runSvelteKitWizard,
46
40
  },
41
+ '@sentry/react-native': {
42
+ frameworkName: 'React Native',
43
+ frameworkPackage: 'react-native',
44
+ sourcemapsDocsLink:
45
+ 'https://docs.sentry.io/platforms/react-native/sourcemaps/',
46
+ troubleshootingDocsLink:
47
+ 'https://docs.sentry.io/platforms/react-native/troubleshooting/#source-maps',
48
+ wizard: runReactNativeWizard,
49
+ },
47
50
  };
48
51
 
49
52
  export async function checkIfMoreSuitableWizardExistsAndAskForRedirect(): Promise<
@@ -91,7 +94,7 @@ async function checkIfMoreSuitableWizardExists(): Promise<string | undefined> {
91
94
  async function askForRedirect(
92
95
  sdkName: string,
93
96
  ): Promise<WizardFunction | undefined> {
94
- const { frameworkName, sourcemapsDocsLink, frameworkSlug, wizard } =
97
+ const { frameworkName, sourcemapsDocsLink, troubleshootingDocsLink, wizard } =
95
98
  sdkMap[sdkName];
96
99
 
97
100
  clack.log.warn(
@@ -108,7 +111,7 @@ Manual source maps configuration for ${frameworkName}:
108
111
  ${sourcemapsDocsLink}
109
112
 
110
113
  Troubleshooting Source Maps:
111
- https://docs.sentry.io/platforms/javascript/guides/${frameworkSlug}/sourcemaps/troubleshooting_js/
114
+ ${troubleshootingDocsLink}
112
115
  `,
113
116
  );
114
117
 
@@ -146,3 +149,19 @@ https://docs.sentry.io/platforms/javascript/guides/${frameworkSlug}/sourcemaps/t
146
149
  return undefined;
147
150
  }
148
151
  }
152
+
153
+ function runReactNativeWizard(): Promise<void> {
154
+ const [runner, ...wizardArgs] = [...process.argv];
155
+ wizardArgs.push('--integration', 'reactNative');
156
+
157
+ try {
158
+ childProcess.spawnSync(runner, wizardArgs, {
159
+ cwd: process.cwd(),
160
+ stdio: 'inherit',
161
+ });
162
+ } catch {
163
+ return Promise.reject();
164
+ }
165
+
166
+ return Promise.resolve();
167
+ }
@@ -1,6 +1,6 @@
1
1
  import { Args } from '../../lib/Constants';
2
2
  import { SentryCli } from '../../lib/Helper/SentryCli';
3
- import { SentryProjectData } from '../utils/clack-utils';
3
+ import { SentryProjectData } from '../utils/types';
4
4
 
5
5
  export async function setupCLIConfig(
6
6
  authToken: string,
@@ -3,6 +3,7 @@ import clack from '@clack/prompts';
3
3
  import chalk from 'chalk';
4
4
 
5
5
  import {
6
+ abort,
6
7
  askForProjectSelection,
7
8
  askForSelfHosted,
8
9
  askForWizardLogin,
@@ -66,6 +67,7 @@ export async function runSvelteKitWizard(
66
67
  : 'Unknown error',
67
68
  ),
68
69
  );
70
+ await abort('Exiting Wizard');
69
71
  return;
70
72
  }
71
73
 
@@ -87,6 +89,7 @@ export async function runSvelteKitWizard(
87
89
  : 'Unknown error',
88
90
  ),
89
91
  );
92
+ await abort('Exiting Wizard');
90
93
  return;
91
94
  }
92
95
 
package/src/utils/bash.ts CHANGED
@@ -3,42 +3,55 @@ import * as https from 'https';
3
3
  import * as fs from 'fs';
4
4
 
5
5
  export function hasSentryCLI(): boolean {
6
- try {
7
- child_process.execSync('sentry-cli --version');
8
- return true;
9
- } catch (e) {
10
- return false;
11
- }
6
+ try {
7
+ child_process.execSync('sentry-cli --version');
8
+ return true;
9
+ } catch (e) {
10
+ return false;
11
+ }
12
12
  }
13
13
 
14
14
  export async function installSentryCLI(): Promise<void> {
15
- const httpAsync = new Promise((resolve, reject) => {
16
- const file = fs.createWriteStream('installcli.sh');
17
- https.get('https://sentry.io/get-cli/', (response) => {
18
- response.pipe(file);
19
- file.on('finish', () => {
20
- file.close();
21
- try {
22
- child_process.execSync('bash ./installcli.sh');
23
- } catch (e) {
24
- reject(e);
25
- return
26
- }
27
- fs.unlinkSync('installcli.sh');
28
- resolve(null);
29
- });
15
+ const httpAsync = new Promise((resolve, reject) => {
16
+ const file = fs.createWriteStream('installcli.sh');
17
+ https.get('https://sentry.io/get-cli/', (response) => {
18
+ response.pipe(file);
19
+ file.on('finish', () => {
20
+ file.close();
21
+ try {
22
+ child_process.execSync('bash ./installcli.sh');
23
+ } catch (e) {
24
+ reject(e);
25
+ return;
26
+ }
27
+ fs.unlinkSync('installcli.sh');
28
+ resolve(null);
29
+ });
30
30
 
31
- file.on('error', (err) => {
32
- fs.unlinkSync('installcli.sh');
33
- reject(err);
34
- });
35
- });
31
+ file.on('error', (err) => {
32
+ fs.unlinkSync('installcli.sh');
33
+ reject(err);
34
+ });
36
35
  });
36
+ });
37
37
 
38
- await httpAsync;
38
+ await httpAsync;
39
39
  }
40
40
 
41
- export function execute(command: string): string {
42
- const output = child_process.execSync(command);
43
- return output.toString();
41
+ export function executeSync(command: string): string {
42
+ const output = child_process.execSync(command);
43
+ return output.toString();
44
+ }
45
+
46
+ export function execute(command: string): Promise<string> {
47
+ return new Promise((resolve, reject) => {
48
+ child_process.exec(command, (error, stdout, _) => {
49
+ if (error) {
50
+ reject(error);
51
+ return;
52
+ }
53
+
54
+ resolve(stdout);
55
+ });
56
+ });
44
57
  }
@@ -11,6 +11,8 @@ import { promisify } from 'util';
11
11
  import * as Sentry from '@sentry/node';
12
12
  import { windowedSelect } from './vendor/clack-custom-select';
13
13
  import { hasPackageInstalled, PackageDotJson } from './package-json';
14
+ import { SentryProjectData, WizardOptions } from './types';
15
+ import { traceStep } from '../telemetry';
14
16
 
15
17
  const opn = require('opn') as (
16
18
  url: string,
@@ -28,17 +30,6 @@ interface WizardProjectData {
28
30
  projects: SentryProjectData[];
29
31
  }
30
32
 
31
- export interface SentryProjectData {
32
- id: string;
33
- slug: string;
34
- name: string;
35
- platform: string;
36
- organization: {
37
- slug: string;
38
- };
39
- keys: [{ dsn: { public: string } }];
40
- }
41
-
42
33
  export async function abort(message?: string, status?: number): Promise<never> {
43
34
  clack.outro(message ?? 'Wizard setup cancelled.');
44
35
  const sentryHub = Sentry.getCurrentHub();
@@ -206,9 +197,7 @@ export async function askForWizardLogin(options: {
206
197
 
207
198
  const loginSpinner = clack.spinner();
208
199
 
209
- loginSpinner.start(
210
- "Waiting for you to log in using the link above. Once you're logged in, return to this wizard.",
211
- );
200
+ loginSpinner.start('Waiting for you to log in using the link above');
212
201
 
213
202
  const data = await new Promise<WizardProjectData>((resolve) => {
214
203
  const pollingInterval = setInterval(() => {
@@ -661,3 +650,42 @@ export function isUsingTypeScript() {
661
650
  return false;
662
651
  }
663
652
  }
653
+
654
+ export async function getOrAskForProjectData(options: WizardOptions): Promise<{
655
+ sentryUrl: string;
656
+ selfHosted: boolean;
657
+ selectedProject: SentryProjectData;
658
+ authToken: string;
659
+ }> {
660
+ if (options.preSelectedProject) {
661
+ return {
662
+ selfHosted: options.preSelectedProject.selfHosted,
663
+ sentryUrl: options.url ?? SAAS_URL,
664
+ authToken: options.preSelectedProject.authToken,
665
+ selectedProject: options.preSelectedProject.project,
666
+ };
667
+ }
668
+ const { url: sentryUrl, selfHosted } = await traceStep(
669
+ 'ask-self-hosted',
670
+ () => askForSelfHosted(options.url),
671
+ );
672
+
673
+ const { projects, apiKeys } = await traceStep('login', () =>
674
+ askForWizardLogin({
675
+ promoCode: options.promoCode,
676
+ url: sentryUrl,
677
+ platform: 'javascript-nextjs',
678
+ }),
679
+ );
680
+
681
+ const selectedProject = await traceStep('select-project', () =>
682
+ askForProjectSelection(projects),
683
+ );
684
+
685
+ return {
686
+ sentryUrl,
687
+ selfHosted,
688
+ authToken: apiKeys.token,
689
+ selectedProject,
690
+ };
691
+ }
@@ -1,5 +1,5 @@
1
1
  export type PackageDotJson = {
2
- scripts?: Record<string, string>;
2
+ scripts?: Record<string, string | undefined>;
3
3
  dependencies?: Record<string, string>;
4
4
  devDependencies?: Record<string, string>;
5
5
  };
@@ -1,3 +1,14 @@
1
+ export interface SentryProjectData {
2
+ id: string;
3
+ slug: string;
4
+ name: string;
5
+ platform: string;
6
+ organization: {
7
+ slug: string;
8
+ };
9
+ keys: [{ dsn: { public: string } }];
10
+ }
11
+
1
12
  export type WizardOptions = {
2
13
  /**
3
14
  * Controls whether the wizard should send telemetry data to Sentry.
@@ -15,4 +26,15 @@ export type WizardOptions = {
15
26
  * This can be passed via the `-u` or `--url` arg.
16
27
  */
17
28
  url?: string;
29
+
30
+ /**
31
+ * If this is set, the wizard will skip the login and project selection step.
32
+ * (This can not yet be set externally but for example when redirecting from
33
+ * one wizard to another when the project was already selected)
34
+ */
35
+ preSelectedProject?: {
36
+ project: SentryProjectData;
37
+ authToken: string;
38
+ selfHosted: boolean;
39
+ };
18
40
  };