@sentry/wizard 6.9.0 → 6.10.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 (46) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/dist/e2e-tests/tests/nextjs-14.test.js +6 -6
  3. package/dist/e2e-tests/tests/nextjs-14.test.js.map +1 -1
  4. package/dist/e2e-tests/tests/nextjs-15.test.js +6 -6
  5. package/dist/e2e-tests/tests/nextjs-15.test.js.map +1 -1
  6. package/dist/e2e-tests/tests/nextjs-16.test.d.ts +1 -0
  7. package/dist/e2e-tests/tests/nextjs-16.test.js +120 -0
  8. package/dist/e2e-tests/tests/nextjs-16.test.js.map +1 -0
  9. package/dist/e2e-tests/utils/index.d.ts +6 -0
  10. package/dist/e2e-tests/utils/index.js +16 -1
  11. package/dist/e2e-tests/utils/index.js.map +1 -1
  12. package/dist/src/nextjs/nextjs-wizard.js +46 -8
  13. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  14. package/dist/src/nextjs/templates.d.ts +6 -3
  15. package/dist/src/nextjs/templates.js +144 -93
  16. package/dist/src/nextjs/templates.js.map +1 -1
  17. package/dist/src/react-router/codemods/client.entry.js +4 -1
  18. package/dist/src/react-router/codemods/client.entry.js.map +1 -1
  19. package/dist/src/react-router/sdk-example.js +5 -2
  20. package/dist/src/react-router/sdk-example.js.map +1 -1
  21. package/dist/src/sourcemaps/tools/sentry-cli.js +1 -1
  22. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  23. package/dist/src/sourcemaps/tools/wrangler.js +1 -1
  24. package/dist/src/sourcemaps/tools/wrangler.js.map +1 -1
  25. package/dist/src/sveltekit/sveltekit-wizard.js +2 -2
  26. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  27. package/dist/src/telemetry.d.ts +1 -1
  28. package/dist/src/telemetry.js +52 -31
  29. package/dist/src/telemetry.js.map +1 -1
  30. package/dist/src/utils/clack/index.d.ts +17 -0
  31. package/dist/src/utils/clack/index.js +174 -12
  32. package/dist/src/utils/clack/index.js.map +1 -1
  33. package/dist/src/version.d.ts +1 -1
  34. package/dist/src/version.js +1 -1
  35. package/dist/src/version.js.map +1 -1
  36. package/dist/test/apple/cocoapod.test.js +7 -3
  37. package/dist/test/apple/cocoapod.test.js.map +1 -1
  38. package/dist/test/apple/code-tools.test.js +8 -2
  39. package/dist/test/apple/code-tools.test.js.map +1 -1
  40. package/dist/test/nextjs/templates.test.js +156 -87
  41. package/dist/test/nextjs/templates.test.js.map +1 -1
  42. package/dist/test/nextjs/wizard-double-wrap-prevention.test.js +12 -7
  43. package/dist/test/nextjs/wizard-double-wrap-prevention.test.js.map +1 -1
  44. package/dist/test/utils/clack/index.test.js +37 -29
  45. package/dist/test/utils/clack/index.test.js.map +1 -1
  46. package/package.json +2 -2
@@ -89,6 +89,15 @@ export declare function installPackage({ packageName, alreadyInstalled, askBefor
89
89
  }>;
90
90
  export declare function addSentryCliConfig({ authToken, org, project, url }: CliSetupConfigContent, setupConfig?: CliSetupConfig): Promise<void>;
91
91
  export declare function addDotEnvSentryBuildPluginFile(authToken: string): Promise<void>;
92
+ /**
93
+ * Runs available formatters (Prettier and/or Biome) on the changed or untracked files in the project.
94
+ * This function provides a unified interface for running multiple formatters with a single user prompt.
95
+ *
96
+ * @param _opts The directory of the project. If undefined, the current process working directory will be used.
97
+ */
98
+ export declare function runFormatters(_opts: {
99
+ cwd: string | undefined;
100
+ }): Promise<void>;
92
101
  /**
93
102
  * Runs prettier on the changed or untracked files in the project.
94
103
  *
@@ -97,6 +106,14 @@ export declare function addDotEnvSentryBuildPluginFile(authToken: string): Promi
97
106
  export declare function runPrettierIfInstalled(opts: {
98
107
  cwd: string | undefined;
99
108
  }): Promise<void>;
109
+ /**
110
+ * Runs Biome on the changed or untracked files in the project.
111
+ *
112
+ * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
113
+ */
114
+ export declare function runBiomeIfInstalled(opts: {
115
+ cwd: string | undefined;
116
+ }): Promise<void>;
100
117
  /**
101
118
  * Checks if @param packageId is listed as a dependency in @param packageJson.
102
119
  * If not, it will ask users if they want to continue without the package.
@@ -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.askToRunBuildOrEnterPathOrProceed = exports.artifactsExist = exports.askShouldAddPackageOverride = exports.askShouldInstallPackage = exports.featureSelectionPrompt = exports.askShouldCreateExampleComponent = exports.askShouldCreateExamplePage = exports.createNewConfigFile = exports.makeCodeSnippet = exports.showCopyPasteInstructions = exports.askForToolConfigPath = exports.askForWizardLogin = exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageManager = exports.updatePackageDotJson = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.runPrettierIfInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.confirmContinueIfPackageVersionNotSupported = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueIfNoOrDirtyGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.propertiesCliSetupConfig = exports.rcCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
29
+ exports.askToRunBuildOrEnterPathOrProceed = exports.artifactsExist = exports.askShouldAddPackageOverride = exports.askShouldInstallPackage = exports.featureSelectionPrompt = exports.askShouldCreateExampleComponent = exports.askShouldCreateExamplePage = exports.createNewConfigFile = exports.makeCodeSnippet = exports.showCopyPasteInstructions = exports.askForToolConfigPath = exports.askForWizardLogin = exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageManager = exports.updatePackageDotJson = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.runBiomeIfInstalled = exports.runPrettierIfInstalled = exports.runFormatters = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.confirmContinueIfPackageVersionNotSupported = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueIfNoOrDirtyGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.propertiesCliSetupConfig = exports.rcCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
30
30
  const childProcess = __importStar(require("node:child_process"));
31
31
  const fs = __importStar(require("node:fs"));
32
32
  const node_child_process_1 = require("node:child_process");
@@ -104,17 +104,22 @@ exports.propertiesCliSetupConfig = {
104
104
  */
105
105
  async function abort(message, status) {
106
106
  clack.outro(message ?? 'Wizard setup cancelled.');
107
- const sentryHub = Sentry.getCurrentHub();
108
- const sentryTransaction = sentryHub.getScope().getTransaction();
107
+ const activeSpan = Sentry.getActiveSpan();
108
+ const rootSpan = activeSpan ? Sentry.getRootSpan(activeSpan) : undefined;
109
109
  // 'cancelled' doesn't increase the `failureRate()` shown in the Sentry UI
110
110
  // 'aborted' increases the failure rate
111
111
  // see: https://docs.sentry.io/product/insights/overview/metrics/#failure-rate
112
- sentryTransaction?.setStatus(status === 0 ? 'cancelled' : 'aborted');
113
- sentryTransaction?.finish();
114
- const sentrySession = sentryHub.getScope().getSession();
112
+ if (rootSpan) {
113
+ rootSpan.setStatus({
114
+ code: status === 0 ? 1 : 2,
115
+ message: status === 0 ? 'cancelled' : 'aborted',
116
+ });
117
+ rootSpan.end();
118
+ }
119
+ const sentrySession = Sentry.getCurrentScope().getSession();
115
120
  if (sentrySession) {
116
121
  sentrySession.status = status === 0 ? 'abnormal' : 'crashed';
117
- sentryHub.captureSession(true);
122
+ Sentry.captureSession(true);
118
123
  }
119
124
  await Sentry.flush(3000).catch(() => {
120
125
  // Ignore flush errors during abort
@@ -125,11 +130,13 @@ exports.abort = abort;
125
130
  async function abortIfCancelled(input) {
126
131
  if (clack.isCancel(await input)) {
127
132
  clack.cancel('Wizard setup cancelled.');
128
- const sentryHub = Sentry.getCurrentHub();
129
- const sentryTransaction = sentryHub.getScope().getTransaction();
130
- sentryTransaction?.setStatus('cancelled');
131
- sentryTransaction?.finish();
132
- sentryHub.captureSession(true);
133
+ const activeSpan = Sentry.getActiveSpan();
134
+ const rootSpan = activeSpan ? Sentry.getRootSpan(activeSpan) : undefined;
135
+ if (rootSpan) {
136
+ rootSpan.setStatus({ code: 1, message: 'cancelled' });
137
+ rootSpan.end();
138
+ }
139
+ Sentry.captureSession(true);
133
140
  await Sentry.flush(3000).catch(() => {
134
141
  // Ignore flush errors during abort
135
142
  });
@@ -450,6 +457,99 @@ async function addCliConfigFileToGitIgnore(filename) {
450
457
  clack.log.error(`Failed adding ${chalk_1.default.cyan(filename)} to ${chalk_1.default.cyan('.gitignore')}. Please add it manually!`);
451
458
  }
452
459
  }
460
+ /**
461
+ * Helper function to get the list of changed or untracked files for formatting.
462
+ * @returns Space-separated string of file paths, or null if not in git repo or no files changed.
463
+ */
464
+ function getFormatterTargetFiles() {
465
+ if (!(0, git_1.isInGitRepo)({ cwd: undefined })) {
466
+ return null;
467
+ }
468
+ const changedOrUntrackedFiles = (0, git_1.getUncommittedOrUntrackedFiles)()
469
+ .map((filename) => {
470
+ return filename.startsWith('- ') ? filename.slice(2) : filename;
471
+ })
472
+ .join(' ');
473
+ return changedOrUntrackedFiles.length ? changedOrUntrackedFiles : null;
474
+ }
475
+ /**
476
+ * Runs available formatters (Prettier and/or Biome) on the changed or untracked files in the project.
477
+ * This function provides a unified interface for running multiple formatters with a single user prompt.
478
+ *
479
+ * @param _opts The directory of the project. If undefined, the current process working directory will be used.
480
+ */
481
+ async function runFormatters(_opts) {
482
+ return (0, telemetry_1.traceStep)('run-formatters', async () => {
483
+ const targetFiles = getFormatterTargetFiles();
484
+ if (!targetFiles) {
485
+ return;
486
+ }
487
+ const packageJson = await getPackageDotJson();
488
+ const prettierInstalled = (0, package_json_1.hasPackageInstalled)('prettier', packageJson);
489
+ const biomeInstalled = (0, package_json_1.hasPackageInstalled)('@biomejs/biome', packageJson);
490
+ Sentry.setTag('prettier-installed', prettierInstalled);
491
+ Sentry.setTag('biome-installed', biomeInstalled);
492
+ if (!prettierInstalled && !biomeInstalled) {
493
+ return;
494
+ }
495
+ // Determine prompt message based on what's installed
496
+ const formattersAvailable = [];
497
+ if (prettierInstalled)
498
+ formattersAvailable.push('Prettier');
499
+ if (biomeInstalled)
500
+ formattersAvailable.push('Biome');
501
+ const message = formattersAvailable.length === 1
502
+ ? `Looks like you have ${formattersAvailable[0]} in your project. Do you want to run it on your files?`
503
+ : `Looks like you have ${formattersAvailable.join(' and ')} in your project. Do you want to run them on your files?`;
504
+ const shouldRun = await abortIfCancelled(clack.confirm({ message }));
505
+ if (!shouldRun) {
506
+ return;
507
+ }
508
+ const spinner = clack.spinner();
509
+ spinner.start('Running formatters on your files.');
510
+ try {
511
+ // Run Prettier first if installed (handles general formatting)
512
+ if (prettierInstalled) {
513
+ await new Promise((resolve, reject) => {
514
+ childProcess.exec(`npx prettier --ignore-unknown --write ${targetFiles}`, (err) => {
515
+ if (err) {
516
+ reject(err);
517
+ }
518
+ else {
519
+ resolve();
520
+ }
521
+ });
522
+ });
523
+ }
524
+ // Run Biome if installed (handles linting + additional formatting)
525
+ if (biomeInstalled) {
526
+ // Format first
527
+ await new Promise((resolve) => {
528
+ childProcess.exec(`npx @biomejs/biome format --write ${targetFiles}`, () => {
529
+ // Ignore errors, just continue
530
+ resolve();
531
+ });
532
+ });
533
+ // Then lint with fixes (using --unsafe for auto-fixable issues)
534
+ // See: https://biomejs.dev/linter/#unsafe-fixes
535
+ // The --unsafe flag applies potentially behavior-changing fixes like removing unused imports.
536
+ // This is acceptable for wizard-generated code which may have fixable issues.
537
+ await new Promise((resolve) => {
538
+ childProcess.exec(`npx @biomejs/biome check --write --unsafe ${targetFiles}`, () => {
539
+ // Ignore errors, Biome exits non-zero if there are remaining issues
540
+ resolve();
541
+ });
542
+ });
543
+ }
544
+ spinner.stop('Formatters have processed your files.');
545
+ }
546
+ catch (e) {
547
+ spinner.stop('Formatting encountered an issue.');
548
+ clack.log.warn('Formatting encountered an issue. There may be formatting or linting issues in your updated files.');
549
+ }
550
+ });
551
+ }
552
+ exports.runFormatters = runFormatters;
453
553
  /**
454
554
  * Runs prettier on the changed or untracked files in the project.
455
555
  *
@@ -507,6 +607,68 @@ async function runPrettierIfInstalled(opts) {
507
607
  });
508
608
  }
509
609
  exports.runPrettierIfInstalled = runPrettierIfInstalled;
610
+ /**
611
+ * Runs Biome on the changed or untracked files in the project.
612
+ *
613
+ * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.
614
+ */
615
+ async function runBiomeIfInstalled(opts) {
616
+ return (0, telemetry_1.traceStep)('run-biome', async () => {
617
+ if (!(0, git_1.isInGitRepo)({ cwd: opts.cwd })) {
618
+ // We only run formatting on changed files. If we're not in a git repo, we can't find
619
+ // changed files. So let's early-return without showing any formatting-related messages.
620
+ return;
621
+ }
622
+ const changedOrUntrackedFiles = (0, git_1.getUncommittedOrUntrackedFiles)()
623
+ .map((filename) => {
624
+ return filename.startsWith('- ') ? filename.slice(2) : filename;
625
+ })
626
+ .join(' ');
627
+ if (!changedOrUntrackedFiles.length) {
628
+ // Likewise, if we can't find changed or untracked files, there's no point in running Biome.
629
+ return;
630
+ }
631
+ const packageJson = await getPackageDotJson();
632
+ const biomeInstalled = (0, package_json_1.hasPackageInstalled)('@biomejs/biome', packageJson);
633
+ Sentry.setTag('biome-installed', biomeInstalled);
634
+ if (!biomeInstalled) {
635
+ return;
636
+ }
637
+ // prompt the user if they want to run biome
638
+ const shouldRunBiome = await abortIfCancelled(clack.confirm({
639
+ message: 'Looks like you have Biome in your project. Do you want to run it on your files?',
640
+ }));
641
+ if (!shouldRunBiome) {
642
+ return;
643
+ }
644
+ const biomeSpinner = clack.spinner();
645
+ biomeSpinner.start('Running Biome on your files.');
646
+ try {
647
+ // Use biome format --write for formatting (always succeeds if it can format)
648
+ // Then biome check --write for lint fixes
649
+ // We ignore exit codes because Biome exits non-zero if there are unfixable issues
650
+ await new Promise((resolve) => {
651
+ childProcess.exec(`npx @biomejs/biome format --write ${changedOrUntrackedFiles}`, () => {
652
+ // Ignore errors, just continue
653
+ resolve();
654
+ });
655
+ });
656
+ await new Promise((resolve) => {
657
+ childProcess.exec(`npx @biomejs/biome check --write --unsafe ${changedOrUntrackedFiles}`, () => {
658
+ // Ignore errors, Biome exits non-zero if there are remaining issues
659
+ resolve();
660
+ });
661
+ });
662
+ }
663
+ catch (e) {
664
+ biomeSpinner.stop('Biome encountered an issue.');
665
+ clack.log.warn('Biome encountered an issue. There may be formatting or linting issues in your updated files.');
666
+ return;
667
+ }
668
+ biomeSpinner.stop('Biome has formatted your files.');
669
+ });
670
+ }
671
+ exports.runBiomeIfInstalled = runBiomeIfInstalled;
510
672
  /**
511
673
  * Checks if @param packageId is listed as a dependency in @param packageJson.
512
674
  * If not, it will ask users if they want to continue without the package.