@sentry/wizard 3.25.2 → 3.26.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.
@@ -15,7 +15,6 @@ import { traceStep } from '../telemetry';
15
15
  import {
16
16
  detectPackageManger,
17
17
  PackageManager,
18
- installPackageWithPackageManager,
19
18
  packageManagers,
20
19
  } from './package-manager';
21
20
  import { debug } from './debug';
@@ -23,6 +22,9 @@ import { fulfillsVersionRange } from './semver';
23
22
 
24
23
  const opn = require('opn') as (
25
24
  url: string,
25
+ options?: {
26
+ wait?: boolean;
27
+ },
26
28
  ) => Promise<childProcess.ChildProcess>;
27
29
 
28
30
  export const SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';
@@ -383,7 +385,31 @@ export async function installPackage({
383
385
  );
384
386
 
385
387
  try {
386
- await installPackageWithPackageManager(packageManager, packageName);
388
+ await new Promise<void>((resolve, reject) => {
389
+ childProcess.exec(
390
+ `${packageManager.installCommand} ${packageName} ${packageManager.flags}`,
391
+ (err, stdout, stderr) => {
392
+ if (err) {
393
+ // Write a log file so we can better troubleshoot issues
394
+ fs.writeFileSync(
395
+ path.join(
396
+ process.cwd(),
397
+ `sentry-wizard-installation-error-${Date.now()}.log`,
398
+ ),
399
+ JSON.stringify({
400
+ stdout,
401
+ stderr,
402
+ }),
403
+ { encoding: 'utf8' },
404
+ );
405
+
406
+ reject(err);
407
+ } else {
408
+ resolve();
409
+ }
410
+ },
411
+ );
412
+ });
387
413
  } catch (e) {
388
414
  sdkInstallSpinner.stop('Installation failed.');
389
415
  clack.log.error(
@@ -391,7 +417,7 @@ export async function installPackage({
391
417
  'Encountered the following error during installation:',
392
418
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
393
419
  )}\n\n${e}\n\n${chalk.dim(
394
- 'If you think this issue is caused by the Sentry wizard, let us know here:\nhttps://github.com/getsentry/sentry-wizard/issues',
420
+ "The wizard has created a `sentry-wizard-installation-error-*.log` file. If you think this issue is caused by the Sentry wizard, create an issue on GitHub and include the log file's content:\nhttps://github.com/getsentry/sentry-wizard/issues",
395
421
  )}`,
396
422
  );
397
423
  await abort();
@@ -614,10 +640,21 @@ SENTRY_AUTH_TOKEN=${authToken}
614
640
  }
615
641
 
616
642
  async function addCliConfigFileToGitIgnore(filename: string): Promise<void> {
617
- //TODO: Add a check to see if the file is already ignored in .gitignore
643
+ const gitignorePath = path.join(process.cwd(), '.gitignore');
644
+
618
645
  try {
646
+ const gitignoreContent = await fs.promises.readFile(gitignorePath, 'utf8');
647
+ if (gitignoreContent.split(/\r?\n/).includes(filename)) {
648
+ clack.log.info(
649
+ `${chalk.bold('.gitignore')} already has ${chalk.bold(
650
+ filename,
651
+ )}. Will not add it again.`,
652
+ );
653
+ return;
654
+ }
655
+
619
656
  await fs.promises.appendFile(
620
- path.join(process.cwd(), '.gitignore'),
657
+ gitignorePath,
621
658
  `\n# Sentry Config File\n${filename}\n`,
622
659
  { encoding: 'utf8' },
623
660
  );
@@ -958,7 +995,7 @@ async function askForWizardLogin(options: {
958
995
  )}\n\n${chalk.cyan(urlToOpen)}`,
959
996
  );
960
997
 
961
- opn(urlToOpen).catch(() => {
998
+ opn(urlToOpen, { wait: false }).catch(() => {
962
999
  // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here
963
1000
  });
964
1001
 
@@ -1,8 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/typedef */
2
- import { exec } from 'child_process';
3
2
  import * as fs from 'fs';
4
3
  import * as path from 'path';
5
- import { promisify } from 'util';
6
4
 
7
5
  import * as Sentry from '@sentry/node';
8
6
  import { traceStep } from '../telemetry';
@@ -15,6 +13,7 @@ export interface PackageManager {
15
13
  buildCommand: string;
16
14
  /* The command that the package manager uses to run a script from package.json */
17
15
  runScriptCommand: string;
16
+ flags: string;
18
17
  }
19
18
 
20
19
  export const BUN: PackageManager = {
@@ -24,6 +23,7 @@ export const BUN: PackageManager = {
24
23
  installCommand: 'bun add',
25
24
  buildCommand: 'bun run build',
26
25
  runScriptCommand: 'bun run',
26
+ flags: '',
27
27
  };
28
28
  export const YARN: PackageManager = {
29
29
  name: 'yarn',
@@ -32,6 +32,7 @@ export const YARN: PackageManager = {
32
32
  installCommand: 'yarn add',
33
33
  buildCommand: 'yarn build',
34
34
  runScriptCommand: 'yarn',
35
+ flags: '--ignore-workspace-root-check',
35
36
  };
36
37
  export const PNPM: PackageManager = {
37
38
  name: 'pnpm',
@@ -40,6 +41,7 @@ export const PNPM: PackageManager = {
40
41
  installCommand: 'pnpm add',
41
42
  buildCommand: 'pnpm build',
42
43
  runScriptCommand: 'pnpm',
44
+ flags: '--ignore-workspace-root-check',
43
45
  };
44
46
  export const NPM: PackageManager = {
45
47
  name: 'npm',
@@ -48,6 +50,7 @@ export const NPM: PackageManager = {
48
50
  installCommand: 'npm add',
49
51
  buildCommand: 'npm run build',
50
52
  runScriptCommand: 'npm run',
53
+ flags: '',
51
54
  };
52
55
 
53
56
  export const packageManagers = [BUN, YARN, PNPM, NPM];
@@ -64,10 +67,3 @@ export function detectPackageManger(): PackageManager | null {
64
67
  return null;
65
68
  });
66
69
  }
67
-
68
- export async function installPackageWithPackageManager(
69
- packageManager: PackageManager,
70
- packageName: string,
71
- ): Promise<void> {
72
- await promisify(exec)(`${packageManager.installCommand} ${packageName}`);
73
- }
@@ -9,6 +9,7 @@ describe('NextJS code templates', () => {
9
9
  selfHosted: false,
10
10
  sentryUrl: 'https://dont-use-this-url.com',
11
11
  tunnelRoute: true,
12
+ reactComponentAnnotation: false,
12
13
  });
13
14
 
14
15
  expect(template).toMatchInlineSnapshot(`
@@ -56,6 +57,7 @@ describe('NextJS code templates', () => {
56
57
  selfHosted: true,
57
58
  sentryUrl: 'https://my-sentry.com',
58
59
  tunnelRoute: true,
60
+ reactComponentAnnotation: false,
59
61
  });
60
62
 
61
63
  expect(template).toMatchInlineSnapshot(`
@@ -104,6 +106,7 @@ describe('NextJS code templates', () => {
104
106
  selfHosted: false,
105
107
  sentryUrl: 'https://dont-use-this-url.com',
106
108
  tunnelRoute: false,
109
+ reactComponentAnnotation: false,
107
110
  });
108
111
 
109
112
  expect(template).toMatchInlineSnapshot(`
@@ -143,5 +146,58 @@ describe('NextJS code templates', () => {
143
146
  }"
144
147
  `);
145
148
  });
149
+
150
+ it('adds `reactComponentAnnotations` option if `reactComponentAnnotations` is enabled', () => {
151
+ const template = getWithSentryConfigOptionsTemplate({
152
+ orgSlug: 'my-org',
153
+ projectSlug: 'my-project',
154
+ selfHosted: false,
155
+ sentryUrl: 'https://dont-use-this-url.com',
156
+ tunnelRoute: true,
157
+ reactComponentAnnotation: true,
158
+ });
159
+
160
+ expect(template).toMatchInlineSnapshot(`
161
+ "{
162
+ // For all available options, see:
163
+ // https://github.com/getsentry/sentry-webpack-plugin#options
164
+
165
+ org: "my-org",
166
+ project: "my-project",
167
+
168
+ // Only print logs for uploading source maps in CI
169
+ silent: !process.env.CI,
170
+
171
+ // For all available options, see:
172
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
173
+
174
+ // Upload a larger set of source maps for prettier stack traces (increases build time)
175
+ widenClientFileUpload: true,
176
+
177
+ // Automatically annotate React components to show their full name in breadcrumbs and session replay
178
+ reactComponentAnnotation: {
179
+ enabled: true,
180
+ },
181
+
182
+ // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
183
+ // This can increase your server load as well as your hosting bill.
184
+ // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
185
+ // side errors will fail.
186
+ tunnelRoute: "/monitoring",
187
+
188
+ // Hides source maps from generated client bundles
189
+ hideSourceMaps: true,
190
+
191
+ // Automatically tree-shake Sentry logger statements to reduce bundle size
192
+ disableLogger: true,
193
+
194
+ // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
195
+ // See the following for more information:
196
+ // https://docs.sentry.io/product/crons/
197
+ // https://vercel.com/docs/cron-jobs
198
+ automaticVercelMonitors: true,
199
+ }"
200
+ `);
201
+ });
146
202
  });
147
203
  });