@sentry/wizard 3.1.0-beta.0 → 3.2.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 (108) hide show
  1. package/CHANGELOG.md +17 -2
  2. package/bin.ts +5 -1
  3. package/dist/bin.js +6 -1
  4. package/dist/bin.js.map +1 -1
  5. package/dist/lib/Constants.d.ts +2 -1
  6. package/dist/lib/Constants.js +5 -0
  7. package/dist/lib/Constants.js.map +1 -1
  8. package/dist/lib/Helper/File.js +25 -2
  9. package/dist/lib/Helper/File.js.map +1 -1
  10. package/dist/lib/Helper/Git.d.ts +7 -0
  11. package/dist/lib/Helper/Git.js +94 -0
  12. package/dist/lib/Helper/Git.js.map +1 -0
  13. package/dist/lib/Helper/Logging.d.ts +1 -0
  14. package/dist/lib/Helper/Logging.js +9 -2
  15. package/dist/lib/Helper/Logging.js.map +1 -1
  16. package/dist/lib/Helper/MergeConfig.js +24 -1
  17. package/dist/lib/Helper/MergeConfig.js.map +1 -1
  18. package/dist/lib/Helper/Package.d.ts +9 -0
  19. package/dist/lib/Helper/Package.js +39 -2
  20. package/dist/lib/Helper/Package.js.map +1 -1
  21. package/dist/lib/Helper/PackageManager.d.ts +1 -1
  22. package/dist/lib/Helper/PackageManager.js +32 -11
  23. package/dist/lib/Helper/PackageManager.js.map +1 -1
  24. package/dist/lib/Helper/SentryCli.d.ts +11 -0
  25. package/dist/lib/Helper/SentryCli.js +141 -2
  26. package/dist/lib/Helper/SentryCli.js.map +1 -1
  27. package/dist/lib/Helper/Wizard.js +24 -1
  28. package/dist/lib/Helper/Wizard.js.map +1 -1
  29. package/dist/lib/Helper/__tests__/MergeConfig.js +25 -2
  30. package/dist/lib/Helper/__tests__/MergeConfig.js.map +1 -1
  31. package/dist/lib/Setup.js +25 -2
  32. package/dist/lib/Setup.js.map +1 -1
  33. package/dist/lib/Steps/ChooseIntegration.js +28 -1
  34. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  35. package/dist/lib/Steps/Initial.js +25 -2
  36. package/dist/lib/Steps/Initial.js.map +1 -1
  37. package/dist/lib/Steps/Integrations/BaseIntegration.js +24 -1
  38. package/dist/lib/Steps/Integrations/BaseIntegration.js.map +1 -1
  39. package/dist/lib/Steps/Integrations/Cordova.js +25 -2
  40. package/dist/lib/Steps/Integrations/Cordova.js.map +1 -1
  41. package/dist/lib/Steps/Integrations/Electron.js +26 -3
  42. package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
  43. package/dist/lib/Steps/Integrations/MobileProject.js +24 -1
  44. package/dist/lib/Steps/Integrations/MobileProject.js.map +1 -1
  45. package/dist/lib/Steps/Integrations/NextJs.d.ts +5 -11
  46. package/dist/lib/Steps/Integrations/NextJs.js +14 -343
  47. package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
  48. package/dist/lib/Steps/Integrations/ReactNative.d.ts +1 -0
  49. package/dist/lib/Steps/Integrations/ReactNative.js +67 -6
  50. package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
  51. package/dist/lib/Steps/Integrations/SvelteKit.d.ts +13 -0
  52. package/dist/lib/Steps/Integrations/SvelteKit.js +95 -0
  53. package/dist/lib/Steps/Integrations/SvelteKit.js.map +1 -0
  54. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js +28 -5
  55. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js.map +1 -1
  56. package/dist/lib/Steps/PromptForParameters.js +24 -1
  57. package/dist/lib/Steps/PromptForParameters.js.map +1 -1
  58. package/dist/lib/Steps/SentryProjectSelector.js +25 -1
  59. package/dist/lib/Steps/SentryProjectSelector.js.map +1 -1
  60. package/dist/lib/__tests__/Setup.js +24 -1
  61. package/dist/lib/__tests__/Setup.js.map +1 -1
  62. package/dist/src/nextjs/nextjs-wizard.js +326 -0
  63. package/dist/src/nextjs/nextjs-wizard.js.map +1 -0
  64. package/dist/src/sveltekit/sdk-example.d.ts +10 -0
  65. package/dist/src/sveltekit/sdk-example.js +106 -0
  66. package/dist/src/sveltekit/sdk-example.js.map +1 -0
  67. package/dist/src/sveltekit/sdk-setup.d.ts +13 -0
  68. package/dist/src/sveltekit/sdk-setup.js +451 -0
  69. package/dist/src/sveltekit/sdk-setup.js.map +1 -0
  70. package/dist/src/sveltekit/sentry-cli-setup.d.ts +2 -0
  71. package/dist/src/sveltekit/sentry-cli-setup.js +71 -0
  72. package/dist/src/sveltekit/sentry-cli-setup.js.map +1 -0
  73. package/dist/src/sveltekit/sveltekit-wizard.d.ts +5 -0
  74. package/dist/src/sveltekit/sveltekit-wizard.js +147 -0
  75. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -0
  76. package/dist/src/templates/nextjs-templates.d.ts +13 -0
  77. package/dist/src/templates/nextjs-templates.js +54 -0
  78. package/dist/src/templates/nextjs-templates.js.map +1 -0
  79. package/dist/src/templates/sveltekit-templates.d.ts +12 -0
  80. package/dist/src/templates/sveltekit-templates.js +26 -0
  81. package/dist/src/templates/sveltekit-templates.js.map +1 -0
  82. package/dist/src/{clack-utils.d.ts → utils/clack-utils.d.ts} +7 -0
  83. package/dist/src/{clack-utils.js → utils/clack-utils.js} +127 -42
  84. package/dist/src/utils/clack-utils.js.map +1 -0
  85. package/lib/Constants.ts +5 -0
  86. package/lib/Helper/Git.ts +39 -0
  87. package/lib/Helper/Logging.ts +4 -0
  88. package/lib/Helper/Package.ts +17 -0
  89. package/lib/Helper/PackageManager.ts +4 -9
  90. package/lib/Helper/SentryCli.ts +74 -0
  91. package/lib/Steps/ChooseIntegration.ts +4 -0
  92. package/lib/Steps/Integrations/NextJs.ts +7 -397
  93. package/lib/Steps/Integrations/ReactNative.ts +49 -3
  94. package/lib/Steps/Integrations/SvelteKit.ts +29 -0
  95. package/lib/Steps/SentryProjectSelector.ts +1 -0
  96. package/package.json +1 -1
  97. package/src/{nextjs-wizard.ts → nextjs/nextjs-wizard.ts} +45 -273
  98. package/src/sveltekit/sdk-example.ts +56 -0
  99. package/src/sveltekit/sdk-setup.ts +430 -0
  100. package/src/sveltekit/sentry-cli-setup.ts +27 -0
  101. package/src/sveltekit/sveltekit-wizard.ts +116 -0
  102. package/src/templates/nextjs-templates.ts +252 -0
  103. package/src/templates/sveltekit-templates.ts +172 -0
  104. package/src/{clack-utils.ts → utils/clack-utils.ts} +73 -11
  105. package/dist/src/clack-utils.js.map +0 -1
  106. package/dist/src/nextjs-wizard.js +0 -346
  107. package/dist/src/nextjs-wizard.js.map +0 -1
  108. /package/dist/src/{nextjs-wizard.d.ts → nextjs/nextjs-wizard.d.ts} +0 -0
@@ -1,103 +1,20 @@
1
- /* eslint-disable max-lines */
2
- import Chalk from 'chalk';
3
- import * as fs from 'fs';
4
1
  import type { Answers } from 'inquirer';
5
- import { prompt } from 'inquirer';
6
- import * as _ from 'lodash';
7
- import * as path from 'path';
2
+ import { runNextjsWizard } from '../../../src/nextjs/nextjs-wizard';
8
3
 
9
4
  import type { Args } from '../../Constants';
10
- import { debug, green, l, nl, red } from '../../Helper/Logging';
11
- import { mergeConfigFile } from '../../Helper/MergeConfig';
12
- import { checkPackageVersion } from '../../Helper/Package';
13
- import { getPackageMangerChoice } from '../../Helper/PackageManager';
14
- import type { SentryCliProps } from '../../Helper/SentryCli';
15
- import { SentryCli } from '../../Helper/SentryCli';
16
5
  import { BaseIntegration } from './BaseIntegration';
17
6
 
18
- const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';
19
- const COMPATIBLE_SDK_VERSIONS = '>=7.3.0';
20
- const PROPERTIES_FILENAME = 'sentry.properties';
21
- const SENTRYCLIRC_FILENAME = '.sentryclirc';
22
- const GITIGNORE_FILENAME = '.gitignore';
23
- const CONFIG_DIR = 'configs/';
24
- const MERGEABLE_CONFIG_INFIX = 'wizardcopy';
25
-
26
- // for those files which can go in more than one place, the list of places they
27
- // could go (the first one which works will be used)
28
- const TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {
29
- '_error.js': ['pages', 'src/pages'],
30
- 'next.config.js': ['.'],
31
- 'sentry.server.config.js': ['.'],
32
- 'sentry.client.config.js': ['.'],
33
- 'sentry.edge.config.js': ['.'],
34
- };
35
-
36
- let appPackage: any = {};
37
-
38
- try {
39
- appPackage = require(path.join(process.cwd(), 'package.json'));
40
- } catch {
41
- // We don't need to have this
42
- }
43
-
7
+ /**
8
+ * This class just redirects to the new `nextjs-wizard.ts` flow
9
+ * for anyone calling the wizard without the '-i nextjs' flag.
10
+ */
44
11
  export class NextJs extends BaseIntegration {
45
- protected _sentryCli: SentryCli;
46
-
47
12
  public constructor(protected _argv: Args) {
48
13
  super(_argv);
49
- this._sentryCli = new SentryCli(this._argv);
50
14
  }
51
15
 
52
- public async emit(answers: Answers): Promise<Answers> {
53
- const dsn = _.get(answers, ['config', 'dsn', 'public'], null);
54
- nl();
55
-
56
- const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);
57
- await this._createSentryCliConfig(sentryCliProps);
58
-
59
- const templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');
60
- const configDirectory = path.join(templateDirectory, CONFIG_DIR);
61
-
62
- if (fs.existsSync(configDirectory)) {
63
- await this._createNextConfig(configDirectory, dsn);
64
- } else {
65
- debug(
66
- `Couldn't find ${configDirectory}, probably because you ran this from inside of \`/lib\` rather than \`/dist\``,
67
- );
68
- nl();
69
- }
70
-
71
- const selectedProjectSlug: string | null = answers.config?.project?.slug;
72
- if (selectedProjectSlug) {
73
- const hasFirstEvent = answers.wizard?.projects?.find?.(
74
- (p: { slug: string }) => p.slug === selectedProjectSlug,
75
- )?.firstEvent;
76
- if (!hasFirstEvent) {
77
- await this._setTemplate(
78
- templateDirectory,
79
- 'sentry_sample_error.js',
80
- ['pages', 'src/pages'],
81
- dsn,
82
- );
83
- l(
84
- Chalk.bgYellowBright(`
85
- |------------------------------------------------------------------------|
86
- | Installation Complete |
87
- | To verify your installation and finish onboarding, launch your Next.js |
88
- | application, navigate to http://localhost:3000/sentry_sample_error |
89
- | and send us a sample error. |
90
- |------------------------------------------------------------------------|
91
- `),
92
- );
93
- }
94
- }
95
-
96
- l(
97
- 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',
98
- );
99
- nl();
100
-
16
+ public async emit(_answers: Answers): Promise<Answers> {
17
+ await runNextjsWizard({ promoCode: this._argv.promoCode });
101
18
  return {};
102
19
  }
103
20
 
@@ -106,314 +23,7 @@ export class NextJs extends BaseIntegration {
106
23
  if (this._shouldConfigure) {
107
24
  return this._shouldConfigure;
108
25
  }
109
-
110
- nl();
111
-
112
- let userAnswers: Answers = { continue: true };
113
- const hasCompatibleNextjsVersion = checkPackageVersion(
114
- appPackage,
115
- 'next',
116
- COMPATIBLE_NEXTJS_VERSIONS,
117
- true,
118
- );
119
-
120
- const packageManager = getPackageMangerChoice();
121
- const hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');
122
-
123
- let hasCompatibleSdkVersion = false;
124
- // if no package but we have nextjs, let's add it if we can
125
- if (!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion) {
126
- await packageManager.installPackage('@sentry/nextjs');
127
- // can assume it's compatible since we just installed it
128
- hasCompatibleSdkVersion = true;
129
- } else {
130
- // otherwise, let's check the version and spit out the appropriate error
131
- hasCompatibleSdkVersion = checkPackageVersion(
132
- appPackage,
133
- '@sentry/nextjs',
134
- COMPATIBLE_SDK_VERSIONS,
135
- true,
136
- );
137
- }
138
- const hasAllPackagesCompatible =
139
- hasCompatibleNextjsVersion && hasCompatibleSdkVersion;
140
-
141
- if (!hasAllPackagesCompatible && !this._argv.quiet) {
142
- userAnswers = await prompt({
143
- message:
144
- 'There were errors during your project checkup, do you still want to continue?',
145
- name: 'continue',
146
- default: false,
147
- type: 'confirm',
148
- });
149
- }
150
-
151
- nl();
152
-
153
- if (!userAnswers['continue']) {
154
- throw new Error('Please install the required dependencies to continue.');
155
- }
156
-
157
- this._shouldConfigure = Promise.resolve({ nextjs: true });
158
26
  // eslint-disable-next-line @typescript-eslint/unbound-method
159
27
  return this.shouldConfigure;
160
28
  }
161
-
162
- private async _createSentryCliConfig(
163
- cliProps: SentryCliProps,
164
- ): Promise<void> {
165
- const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;
166
-
167
- /**
168
- * To not commit the auth token to the VCS, instead of adding it to the
169
- * properties file (like the rest of props), it's added to the Sentry CLI
170
- * config, which is added to the gitignore. This way makes the properties
171
- * file safe to commit without exposing any auth tokens.
172
- */
173
- if (authToken) {
174
- try {
175
- await fs.promises.appendFile(
176
- SENTRYCLIRC_FILENAME,
177
- this._sentryCli.dumpConfig({ auth: { token: authToken } }),
178
- );
179
- green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);
180
- } catch {
181
- red(
182
- `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +
183
- `please add it to identify your user account:\n${authToken}`,
184
- );
185
- nl();
186
- }
187
- } else {
188
- red(
189
- `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,
190
- );
191
- l(
192
- 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',
193
- );
194
- l(
195
- 'To learn how to configure Sentry CLI, visit ' +
196
- 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',
197
- );
198
- }
199
-
200
- await this._addToGitignore(
201
- SENTRYCLIRC_FILENAME,
202
- `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +
203
- 'please add it to not commit your auth key.',
204
- );
205
-
206
- try {
207
- await fs.promises.writeFile(
208
- `./${PROPERTIES_FILENAME}`,
209
- this._sentryCli.dumpProperties(cliPropsToWrite),
210
- );
211
- green('✓ Successfully created sentry.properties');
212
- } catch {
213
- red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);
214
- l(
215
- 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',
216
- );
217
- }
218
- nl();
219
- }
220
-
221
- private async _addToGitignore(
222
- filepath: string,
223
- errorMsg: string,
224
- ): Promise<void> {
225
- /**
226
- * Don't check whether the given file is ignored because:
227
- * 1. It's tricky to check it without git.
228
- * 2. Git might not be installed or accessible.
229
- * 3. It's convenient to use a module to interact with git, but it would
230
- * increase the size x2 approximately. Docs say to run the Wizard without
231
- * installing it, and duplicating the size would slow the set-up down.
232
- * 4. The Wizard is meant to be run once.
233
- * 5. A message is logged informing users it's been added to the gitignore.
234
- * 6. It will be added to the gitignore as many times as it runs - not a big
235
- * deal.
236
- * 7. It's straightforward to remove it from the gitignore.
237
- */
238
- try {
239
- await fs.promises.appendFile(
240
- GITIGNORE_FILENAME,
241
- `\n# Sentry\n${filepath}\n`,
242
- );
243
- green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);
244
- } catch {
245
- red(errorMsg);
246
- }
247
- }
248
-
249
- private async _createNextConfig(
250
- configDirectory: string,
251
- dsn: any,
252
- ): Promise<void> {
253
- const templates = fs.readdirSync(configDirectory);
254
- // next.config.template.js used for merging next.config.js , not its own template,
255
- // so it shouldn't have a setTemplate call
256
- const filteredTemplates = templates.filter(
257
- (template) => template !== 'next.config.template.js',
258
- );
259
- for (const template of filteredTemplates) {
260
- await this._setTemplate(
261
- configDirectory,
262
- template,
263
- TEMPLATE_DESTINATIONS[template],
264
- dsn,
265
- );
266
- }
267
- red(
268
- '⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
269
- ' Learn more in https://docs.sentry.io/product/performance/',
270
- );
271
- nl();
272
- }
273
-
274
- private async _setTemplate(
275
- configDirectory: string,
276
- templateFile: string,
277
- destinationOptions: string[],
278
- dsn: string,
279
- ): Promise<void> {
280
- const templatePath = path.join(configDirectory, templateFile);
281
-
282
- for (const destinationDir of destinationOptions) {
283
- if (!fs.existsSync(destinationDir)) {
284
- continue;
285
- }
286
- const destinationPath = path.join(destinationDir, templateFile);
287
- // in case the file in question already exists, we'll make a copy with
288
- // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
289
- // to overwrite the existing file
290
- const mergeableFilePath = path.join(
291
- destinationDir,
292
- this._spliceInPlace(
293
- templateFile.split('.'),
294
- -1,
295
- 0,
296
- MERGEABLE_CONFIG_INFIX,
297
- ).join('.'),
298
- );
299
-
300
- if (templateFile === 'next.config.js') {
301
- await this._mergeNextConfig(
302
- destinationPath,
303
- templatePath,
304
- destinationDir,
305
- templateFile,
306
- configDirectory,
307
- mergeableFilePath,
308
- );
309
- return;
310
- } else {
311
- if (!fs.existsSync(destinationPath)) {
312
- this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
313
- } else if (!fs.existsSync(mergeableFilePath)) {
314
- this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
315
- red(
316
- `File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
317
- 'Please merge those files.',
318
- );
319
- nl();
320
- } else {
321
- red(
322
- `Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
323
- 'Please merge those files.',
324
- );
325
- nl();
326
- }
327
- return;
328
- }
329
- }
330
-
331
- red(
332
- `Could not find appropriate destination for \`${templateFile}\`. Tried: ${destinationOptions}.`,
333
- );
334
- nl();
335
- }
336
-
337
- private _fillAndCopyTemplate(
338
- sourcePath: string,
339
- targetPath: string,
340
- dsn: string,
341
- ): void {
342
- const templateContent = fs.readFileSync(sourcePath).toString();
343
- const filledTemplate = templateContent.replace('___DSN___', dsn);
344
- fs.writeFileSync(targetPath, filledTemplate);
345
- }
346
-
347
- private _hasPackageInstalled(packageName: string): boolean {
348
- const depsVersion = _.get(appPackage, ['dependencies', packageName]);
349
- const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
350
- return !!depsVersion || !!devDepsVersion;
351
- }
352
-
353
- private _spliceInPlace(
354
- arr: Array<any>,
355
- start: number,
356
- deleteCount: number,
357
- ...inserts: any[]
358
- ): Array<any> {
359
- arr.splice(start, deleteCount, ...inserts);
360
- return arr;
361
- }
362
-
363
- private async _mergeNextConfig(
364
- destinationPath: string,
365
- templatePath: string,
366
- destinationDir: string,
367
- templateFile: string,
368
- configDirectory: string,
369
- mergeableFilePath: string,
370
- ): Promise<void> {
371
- // if no next.config.js exists, we'll create one
372
- if (!fs.existsSync(destinationPath)) {
373
- fs.copyFileSync(templatePath, destinationPath);
374
- green('Created File `next.config.js`');
375
- nl();
376
- } else {
377
- // creates a file name for the copy of the original next.config.js file
378
- // with the name `next.config.original.js`
379
- const originalFileName = this._spliceInPlace(
380
- templateFile.split('.'),
381
- -1,
382
- 0,
383
- 'original',
384
- ).join('.');
385
- const originalFilePath = path.join(destinationDir, originalFileName);
386
- // makes copy of original next.config.js
387
- fs.writeFileSync(originalFilePath, fs.readFileSync(destinationPath));
388
- await this._addToGitignore(
389
- originalFilePath,
390
- 'Unable to add next.config.original.js to gitignore',
391
- );
392
-
393
- const mergedTemplatePath = path.join(
394
- configDirectory,
395
- 'next.config.template.js',
396
- );
397
- // attempts to merge with existing next.config.js, if true -> success
398
- if (mergeConfigFile(destinationPath, mergedTemplatePath)) {
399
- green(
400
- `Updated \`${templateFile}\` with Sentry. The original ${templateFile} was saved as \`next.config.original.js\`.\n` +
401
- 'Information on the changes made to the Next.js configuration file an be found at https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/',
402
- );
403
- nl();
404
- } else {
405
- // if merge fails, we'll create a copy of the `next.config.js` template and ask them to merge
406
- fs.copyFileSync(templatePath, mergeableFilePath);
407
- await this._addToGitignore(
408
- mergeableFilePath,
409
- 'Unable to add next.config.wizard.js template to gitignore',
410
- );
411
- red(
412
- `Unable to merge \`${templateFile}\`, so created \`${mergeableFilePath}\`.\n` +
413
- 'Please integrate next.config.wizardcopy.js into your next.config.js or next.config.ts file',
414
- );
415
- nl();
416
- }
417
- }
418
- }
419
29
  }
@@ -14,11 +14,13 @@ import {
14
14
  matchFiles,
15
15
  patchMatchingFile,
16
16
  } from '../../Helper/File';
17
- import { dim, green, nl, red } from '../../Helper/Logging';
17
+ import { dim, green, l, nl, red } from '../../Helper/Logging';
18
18
  import { checkPackageVersion } from '../../Helper/Package';
19
- import { getPackageMangerChoice } from '../../Helper/PackageManager';
19
+ import { getPackageManagerChoice } from '../../Helper/PackageManager';
20
20
  import { SentryCli } from '../../Helper/SentryCli';
21
21
  import { MobileProject } from './MobileProject';
22
+ import { BottomBar } from '../../Helper/BottomBar';
23
+ import { URL } from 'url';
22
24
 
23
25
  const xcode = require('xcode');
24
26
 
@@ -37,11 +39,15 @@ export class ReactNative extends MobileProject {
37
39
  */
38
40
  private static _buildGradleAndroidSectionBeginning = /^android {/m;
39
41
 
42
+ private url: string | undefined;
43
+
40
44
  protected _answers: Answers;
41
45
  protected _sentryCli: SentryCli;
42
46
 
47
+
43
48
  public constructor(protected _argv: Args) {
44
49
  super(_argv);
50
+ this.url = _argv.url;
45
51
  this._sentryCli = new SentryCli(this._argv);
46
52
  }
47
53
 
@@ -55,7 +61,7 @@ export class ReactNative extends MobileProject {
55
61
  nl();
56
62
 
57
63
  let userAnswers: Answers = { continue: true };
58
- const packageManager = getPackageMangerChoice();
64
+ const packageManager = getPackageManagerChoice();
59
65
 
60
66
  const hasCompatibleReactNativeVersion = checkPackageVersion(
61
67
  this._readAppPackage(),
@@ -79,7 +85,10 @@ export class ReactNative extends MobileProject {
79
85
  }
80
86
 
81
87
  if (packageManager) {
88
+ BottomBar.show(`Adding ${SENTRY_REACT_NATIVE_PACKAGE}...`);
82
89
  await packageManager.installPackage(SENTRY_REACT_NATIVE_PACKAGE);
90
+ BottomBar.hide();
91
+ green(`✓ Added \`${SENTRY_REACT_NATIVE_PACKAGE}\``);
83
92
  }
84
93
  const hasCompatibleSentryReactNativeVersion = checkPackageVersion(
85
94
  this._readAppPackage(),
@@ -115,7 +124,9 @@ export class ReactNative extends MobileProject {
115
124
  this._patchXcodeProj.bind(this),
116
125
  );
117
126
  green('✓ Patched build script in Xcode project.');
127
+ BottomBar.show('Adding Sentry pods...');
118
128
  await this._podInstall();
129
+ BottomBar.hide();
119
130
  green('✓ Pods installed.');
120
131
  } else {
121
132
  await patchMatchingFile(
@@ -135,6 +146,41 @@ export class ReactNative extends MobileProject {
135
146
 
136
147
  await Promise.all(promises);
137
148
 
149
+ let host: string | null = null
150
+ try {
151
+ host = (new URL(this.url || '')).host;
152
+ } catch (_error) {
153
+ // ignore
154
+ }
155
+ const orgSlug = _.get(answers, 'config.organization.slug', null);
156
+ const projectId = _.get(answers, 'config.project.id', null);
157
+ const projectIssuesUrl = host && orgSlug && projectId
158
+ ? `https://${orgSlug}.${host}/issues/?project=${projectId}`
159
+ : null;
160
+
161
+ l(`
162
+ To make sure everything is set up correctly, put the following code snippet into your application.
163
+ The snippet will create a button that, when tapped, sends a test event to Sentry.
164
+ `);
165
+
166
+ if (projectIssuesUrl) {
167
+ l(`After that check your project issues:`);
168
+ l(projectIssuesUrl);
169
+ nl();
170
+ }
171
+
172
+ l(`<Button title='Try!' onPress={ () => { Sentry.captureException(new Error('First error')) }}/>`);
173
+ nl();
174
+
175
+ if (!this._argv.quiet) {
176
+ await prompt({
177
+ message: 'Have you successfully sent a test event?',
178
+ name: 'snippet',
179
+ default: true,
180
+ type: 'confirm',
181
+ });
182
+ }
183
+
138
184
  return answers;
139
185
  }
140
186
 
@@ -0,0 +1,29 @@
1
+ import type { Answers } from 'inquirer';
2
+ import { runSvelteKitWizard } from '../../../src/sveltekit/sveltekit-wizard';
3
+
4
+ import type { Args } from '../../Constants';
5
+ import { BaseIntegration } from './BaseIntegration';
6
+
7
+ /**
8
+ * This class just redirects to the new `sveltekit-wizard.ts` flow
9
+ * for anyone calling the wizard without the '-i sveltekit' flag.
10
+ */
11
+ export class SvelteKit extends BaseIntegration {
12
+ public constructor(protected _argv: Args) {
13
+ super(_argv);
14
+ }
15
+
16
+ public async emit(_answers: Answers): Promise<Answers> {
17
+ await runSvelteKitWizard({ promoCode: this._argv.promoCode });
18
+ return {};
19
+ }
20
+
21
+ public async shouldConfigure(_answers: Answers): Promise<Answers> {
22
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
23
+ if (this._shouldConfigure) {
24
+ return this._shouldConfigure;
25
+ }
26
+ // eslint-disable-next-line @typescript-eslint/unbound-method
27
+ return this.shouldConfigure;
28
+ }
29
+ }
@@ -71,6 +71,7 @@ export class SentryProjectSelector extends BaseStep {
71
71
  ),
72
72
  },
73
73
  project: {
74
+ id: _.get(selectedProject, 'selectedProject.id', null),
74
75
  slug: _.get(selectedProject, 'selectedProject.slug', null),
75
76
  },
76
77
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wizard",
3
- "version": "3.1.0-beta.0",
3
+ "version": "3.2.0",
4
4
  "homepage": "https://github.com/getsentry/sentry-wizard",
5
5
  "repository": "https://github.com/getsentry/sentry-wizard",
6
6
  "description": "Sentry wizard helping you to configure your project",