@sentry/wizard 3.25.1 → 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.
Files changed (75) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin.ts +10 -2
  3. package/dist/bin.js +12 -3
  4. package/dist/bin.js.map +1 -1
  5. package/dist/lib/Helper/Env.js +1 -0
  6. package/dist/lib/Helper/Env.js.map +1 -1
  7. package/dist/lib/Setup.d.ts +6 -0
  8. package/dist/lib/Setup.js +6 -0
  9. package/dist/lib/Setup.js.map +1 -1
  10. package/dist/lib/Steps/ChooseIntegration.js +0 -29
  11. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  12. package/dist/lib/Steps/OpenSentry.js +1 -1
  13. package/dist/lib/Steps/OpenSentry.js.map +1 -1
  14. package/dist/package.json +2 -1
  15. package/dist/src/nextjs/nextjs-wizard.d.ts +1 -1
  16. package/dist/src/nextjs/nextjs-wizard.js +166 -84
  17. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  18. package/dist/src/nextjs/templates.d.ts +3 -2
  19. package/dist/src/nextjs/templates.js +10 -8
  20. package/dist/src/nextjs/templates.js.map +1 -1
  21. package/dist/src/run.d.ts +16 -0
  22. package/dist/src/run.js +195 -0
  23. package/dist/src/run.js.map +1 -0
  24. package/dist/src/telemetry.js +10 -3
  25. package/dist/src/telemetry.js.map +1 -1
  26. package/dist/src/utils/clack-utils.js +35 -11
  27. package/dist/src/utils/clack-utils.js.map +1 -1
  28. package/dist/src/utils/package-json.d.ts +1 -0
  29. package/dist/src/utils/package-json.js.map +1 -1
  30. package/dist/src/utils/package-manager.d.ts +1 -1
  31. package/dist/src/utils/package-manager.js +5 -52
  32. package/dist/src/utils/package-manager.js.map +1 -1
  33. package/dist/test/nextjs/templates.test.js +14 -0
  34. package/dist/test/nextjs/templates.test.js.map +1 -1
  35. package/lib/Helper/Env.ts +1 -0
  36. package/lib/Setup.ts +6 -0
  37. package/lib/Steps/ChooseIntegration.ts +0 -29
  38. package/lib/Steps/OpenSentry.ts +1 -1
  39. package/package.json +2 -1
  40. package/src/nextjs/nextjs-wizard.ts +188 -99
  41. package/src/nextjs/templates.ts +19 -4
  42. package/src/run.ts +142 -0
  43. package/src/telemetry.ts +7 -1
  44. package/src/utils/clack-utils.ts +44 -7
  45. package/src/utils/package-json.ts +1 -0
  46. package/src/utils/package-manager.ts +5 -9
  47. package/test/nextjs/templates.test.ts +56 -0
  48. package/dist/lib/Steps/Integrations/Android.d.ts +0 -9
  49. package/dist/lib/Steps/Integrations/Android.js +0 -86
  50. package/dist/lib/Steps/Integrations/Android.js.map +0 -1
  51. package/dist/lib/Steps/Integrations/Apple.d.ts +0 -10
  52. package/dist/lib/Steps/Integrations/Apple.js +0 -92
  53. package/dist/lib/Steps/Integrations/Apple.js.map +0 -1
  54. package/dist/lib/Steps/Integrations/NextJsShim.d.ts +0 -13
  55. package/dist/lib/Steps/Integrations/NextJsShim.js +0 -99
  56. package/dist/lib/Steps/Integrations/NextJsShim.js.map +0 -1
  57. package/dist/lib/Steps/Integrations/ReactNative.d.ts +0 -10
  58. package/dist/lib/Steps/Integrations/ReactNative.js +0 -93
  59. package/dist/lib/Steps/Integrations/ReactNative.js.map +0 -1
  60. package/dist/lib/Steps/Integrations/Remix.d.ts +0 -12
  61. package/dist/lib/Steps/Integrations/Remix.js +0 -98
  62. package/dist/lib/Steps/Integrations/Remix.js.map +0 -1
  63. package/dist/lib/Steps/Integrations/SourceMapsShim.d.ts +0 -13
  64. package/dist/lib/Steps/Integrations/SourceMapsShim.js +0 -94
  65. package/dist/lib/Steps/Integrations/SourceMapsShim.js.map +0 -1
  66. package/dist/lib/Steps/Integrations/SvelteKitShim.d.ts +0 -13
  67. package/dist/lib/Steps/Integrations/SvelteKitShim.js +0 -99
  68. package/dist/lib/Steps/Integrations/SvelteKitShim.js.map +0 -1
  69. package/lib/Steps/Integrations/Android.ts +0 -23
  70. package/lib/Steps/Integrations/Apple.ts +0 -27
  71. package/lib/Steps/Integrations/NextJsShim.ts +0 -33
  72. package/lib/Steps/Integrations/ReactNative.ts +0 -28
  73. package/lib/Steps/Integrations/Remix.ts +0 -32
  74. package/lib/Steps/Integrations/SourceMapsShim.ts +0 -28
  75. package/lib/Steps/Integrations/SvelteKitShim.ts +0 -33
@@ -131,16 +131,20 @@ function runNextjsWizardWithTelemetry(options) {
131
131
  case 5:
132
132
  _c.sent();
133
133
  return [4 /*yield*/, (0, telemetry_1.traceStep)('configure-sdk', function () { return __awaiter(_this, void 0, void 0, function () {
134
- var tunnelRoute;
134
+ var tunnelRoute, reactComponentAnnotation;
135
135
  return __generator(this, function (_a) {
136
136
  switch (_a.label) {
137
137
  case 0: return [4 /*yield*/, askShouldSetTunnelRoute()];
138
138
  case 1:
139
139
  tunnelRoute = _a.sent();
140
+ return [4 /*yield*/, askShouldEnableReactComponentAnnotation()];
141
+ case 2:
142
+ reactComponentAnnotation = _a.sent();
140
143
  return [4 /*yield*/, createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, {
141
144
  tunnelRoute: tunnelRoute,
145
+ reactComponentAnnotation: reactComponentAnnotation,
142
146
  })];
143
- case 2:
147
+ case 3:
144
148
  _a.sent();
145
149
  return [2 /*return*/];
146
150
  }
@@ -390,45 +394,69 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
390
394
  _i++;
391
395
  return [3 /*break*/, 1];
392
396
  case 4: return [4 /*yield*/, (0, telemetry_1.traceStep)('setup-instrumentation-hook', function () { return __awaiter(_this, void 0, void 0, function () {
393
- var srcInstrumentationTsExists, srcInstrumentationJsExists, instrumentationTsExists, instrumentationJsExists, instrumentationHookLocation, newInstrumentationFileName, srcFolderExists, instrumentationHookPath, successfullyCreated;
397
+ var hasRootAppDirectory, hasRootPagesDirectory, hasSrcDirectory, instrumentationHookLocation, instrumentationTsExists, instrumentationJsExists, srcInstrumentationTsExists, srcInstrumentationJsExists, newInstrumentationFileName, newInstrumentationHookLocation, newInstrumentationHookPath, successfullyCreated;
394
398
  return __generator(this, function (_a) {
395
399
  switch (_a.label) {
396
400
  case 0:
397
- srcInstrumentationTsExists = fs.existsSync(path.join(process.cwd(), 'src', 'instrumentation.ts'));
398
- srcInstrumentationJsExists = fs.existsSync(path.join(process.cwd(), 'src', 'instrumentation.js'));
401
+ hasRootAppDirectory = hasDirectoryPathFromRoot('app');
402
+ hasRootPagesDirectory = hasDirectoryPathFromRoot('pages');
403
+ hasSrcDirectory = hasDirectoryPathFromRoot('src');
399
404
  instrumentationTsExists = fs.existsSync(path.join(process.cwd(), 'instrumentation.ts'));
400
405
  instrumentationJsExists = fs.existsSync(path.join(process.cwd(), 'instrumentation.js'));
401
- if (srcInstrumentationTsExists || srcInstrumentationJsExists) {
402
- instrumentationHookLocation = 'src';
403
- }
404
- else if (instrumentationTsExists || instrumentationJsExists) {
405
- instrumentationHookLocation = 'root';
406
+ srcInstrumentationTsExists = fs.existsSync(path.join(process.cwd(), 'src', 'instrumentation.ts'));
407
+ srcInstrumentationJsExists = fs.existsSync(path.join(process.cwd(), 'src', 'instrumentation.js'));
408
+ // https://nextjs.org/docs/app/building-your-application/configuring/src-directory
409
+ // https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation
410
+ // The logic for where Next.js picks up the instrumentation file is as follows:
411
+ // - If there is either an `app` folder or a `pages` folder in the root directory of your Next.js app, Next.js looks
412
+ // for an `instrumentation.ts` file in the root of the Next.js app.
413
+ // - Otherwise, if there is neither an `app` folder or a `pages` folder in the rood directory of your Next.js app,
414
+ // AND if there is an `src` folder, Next.js will look for the `instrumentation.ts` file in the `src` folder.
415
+ if (hasRootPagesDirectory || hasRootAppDirectory) {
416
+ if (instrumentationJsExists || instrumentationTsExists) {
417
+ instrumentationHookLocation = 'root';
418
+ }
419
+ else {
420
+ instrumentationHookLocation = 'does-not-exist';
421
+ }
406
422
  }
407
423
  else {
408
- instrumentationHookLocation = 'does-not-exist';
424
+ if (srcInstrumentationTsExists || srcInstrumentationJsExists) {
425
+ instrumentationHookLocation = 'src';
426
+ }
427
+ else {
428
+ instrumentationHookLocation = 'does-not-exist';
429
+ }
409
430
  }
410
- if (!(instrumentationHookLocation === 'does-not-exist')) return [3 /*break*/, 4];
411
431
  newInstrumentationFileName = "instrumentation.".concat(typeScriptDetected ? 'ts' : 'js');
412
- srcFolderExists = fs.existsSync(path.join(process.cwd(), 'src'));
413
- instrumentationHookPath = srcFolderExists
414
- ? path.join(process.cwd(), 'src', newInstrumentationFileName)
415
- : path.join(process.cwd(), newInstrumentationFileName);
416
- return [4 /*yield*/, (0, clack_utils_1.createNewConfigFile)(instrumentationHookPath, (0, templates_1.getInstrumentationHookContent)(srcFolderExists ? 'src' : 'root'))];
432
+ if (!(instrumentationHookLocation === 'does-not-exist')) return [3 /*break*/, 4];
433
+ newInstrumentationHookLocation = void 0;
434
+ if (hasRootPagesDirectory || hasRootAppDirectory) {
435
+ newInstrumentationHookLocation = 'root';
436
+ }
437
+ else if (hasSrcDirectory) {
438
+ newInstrumentationHookLocation = 'src';
439
+ }
440
+ else {
441
+ newInstrumentationHookLocation = 'root';
442
+ }
443
+ newInstrumentationHookPath = newInstrumentationHookLocation === 'root'
444
+ ? path.join(process.cwd(), newInstrumentationFileName)
445
+ : path.join(process.cwd(), 'src', newInstrumentationFileName);
446
+ return [4 /*yield*/, (0, clack_utils_1.createNewConfigFile)(newInstrumentationHookPath, (0, templates_1.getInstrumentationHookContent)(newInstrumentationHookLocation))];
417
447
  case 1:
418
448
  successfullyCreated = _a.sent();
419
449
  if (!!successfullyCreated) return [3 /*break*/, 3];
420
- return [4 /*yield*/, (0, clack_utils_1.showCopyPasteInstructions)(newInstrumentationFileName, (0, templates_1.getInstrumentationHookCopyPasteSnippet)(srcFolderExists ? 'src' : 'root'))];
450
+ return [4 /*yield*/, (0, clack_utils_1.showCopyPasteInstructions)(newInstrumentationFileName, (0, templates_1.getInstrumentationHookCopyPasteSnippet)(newInstrumentationHookLocation))];
421
451
  case 2:
422
452
  _a.sent();
423
453
  _a.label = 3;
424
454
  case 3: return [3 /*break*/, 6];
425
- case 4: return [4 /*yield*/, (0, clack_utils_1.showCopyPasteInstructions)(srcInstrumentationTsExists
455
+ case 4: return [4 /*yield*/, (0, clack_utils_1.showCopyPasteInstructions)(srcInstrumentationTsExists || instrumentationTsExists
426
456
  ? 'instrumentation.ts'
427
- : srcInstrumentationJsExists
457
+ : srcInstrumentationJsExists || instrumentationJsExists
428
458
  ? 'instrumentation.js'
429
- : instrumentationTsExists
430
- ? 'instrumentation.ts'
431
- : 'instrumentation.js', (0, templates_1.getInstrumentationHookCopyPasteSnippet)(instrumentationHookLocation))];
459
+ : newInstrumentationFileName, (0, templates_1.getInstrumentationHookCopyPasteSnippet)(instrumentationHookLocation))];
432
460
  case 5:
433
461
  _a.sent();
434
462
  _a.label = 6;
@@ -439,7 +467,7 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
439
467
  case 5:
440
468
  _a.sent();
441
469
  return [4 /*yield*/, (0, telemetry_1.traceStep)('setup-next-config', function () { return __awaiter(_this, void 0, void 0, function () {
442
- var withSentryConfigOptionsTemplate, nextConfigJs, nextConfigMjs, nextConfigJsExists, nextConfigMjsExists, nextConfigJsContent, probablyIncludesSdk, shouldInject, injectAnyhow, nextConfigMjsContent, probablyIncludesSdk, shouldInject, injectAnyhow, mod, expressionToWrap, newCode, _a, shouldContinue;
470
+ var withSentryConfigOptionsTemplate, nextConfigPossibleFilesMap, foundNextConfigFile, foundNextConfigFileType, foundNextConfigFileFilename, nextConfigCjsContent, probablyIncludesSdk, shouldInject, injectAnyhow, nextConfigMjsContent, probablyIncludesSdk, shouldInject, injectAnyhow, mod, expressionToWrap, newCode, _a, shouldContinue;
443
471
  return __generator(this, function (_b) {
444
472
  switch (_b.label) {
445
473
  case 0:
@@ -449,28 +477,40 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
449
477
  selfHosted: selfHosted,
450
478
  sentryUrl: sentryUrl,
451
479
  tunnelRoute: sdkConfigOptions.tunnelRoute,
480
+ reactComponentAnnotation: sdkConfigOptions.reactComponentAnnotation,
452
481
  });
453
- nextConfigJs = 'next.config.js';
454
- nextConfigMjs = 'next.config.mjs';
455
- nextConfigJsExists = fs.existsSync(path.join(process.cwd(), nextConfigJs));
456
- nextConfigMjsExists = fs.existsSync(path.join(process.cwd(), nextConfigMjs));
457
- if (!(!nextConfigJsExists && !nextConfigMjsExists)) return [3 /*break*/, 2];
482
+ nextConfigPossibleFilesMap = {
483
+ js: 'next.config.js',
484
+ mjs: 'next.config.mjs',
485
+ cjs: 'next.config.cjs',
486
+ ts: 'next.config.ts',
487
+ mts: 'next.config.mts',
488
+ cts: 'next.config.cts',
489
+ };
490
+ foundNextConfigFile = Object.entries(nextConfigPossibleFilesMap).find(function (_a) {
491
+ var fileName = _a[1];
492
+ return fs.existsSync(path.join(process.cwd(), fileName));
493
+ });
494
+ if (!!foundNextConfigFile) return [3 /*break*/, 2];
458
495
  Sentry.setTag('next-config-strategy', 'create');
459
- return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), nextConfigJs), (0, templates_1.getNextjsConfigCjsTemplate)(withSentryConfigOptionsTemplate), { encoding: 'utf8', flag: 'w' })];
496
+ return [4 /*yield*/, fs.promises.writeFile(
497
+ // We are creating a `next.config.js` file by default as it is supported by the most Next.js versions
498
+ path.join(process.cwd(), nextConfigPossibleFilesMap.js), (0, templates_1.getNextjsConfigCjsTemplate)(withSentryConfigOptionsTemplate), { encoding: 'utf8', flag: 'w' })];
460
499
  case 1:
461
500
  _b.sent();
462
501
  prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan('next.config.js'), " with Sentry configuration."));
463
- _b.label = 2;
502
+ return [2 /*return*/];
464
503
  case 2:
465
- if (!nextConfigJsExists) return [3 /*break*/, 7];
504
+ foundNextConfigFileType = foundNextConfigFile[0], foundNextConfigFileFilename = foundNextConfigFile[1];
505
+ if (!(foundNextConfigFileType === 'js' || foundNextConfigFileType === 'cjs')) return [3 /*break*/, 7];
466
506
  Sentry.setTag('next-config-strategy', 'modify');
467
- nextConfigJsContent = fs.readFileSync(path.join(process.cwd(), nextConfigJs), 'utf8');
468
- probablyIncludesSdk = nextConfigJsContent.includes('@sentry/nextjs') &&
469
- nextConfigJsContent.includes('withSentryConfig');
507
+ nextConfigCjsContent = fs.readFileSync(path.join(process.cwd(), foundNextConfigFileFilename), 'utf8');
508
+ probablyIncludesSdk = nextConfigCjsContent.includes('@sentry/nextjs') &&
509
+ nextConfigCjsContent.includes('withSentryConfig');
470
510
  shouldInject = true;
471
511
  if (!probablyIncludesSdk) return [3 /*break*/, 4];
472
512
  return [4 /*yield*/, (0, clack_utils_1.abortIfCancelled)(prompts_1.default.confirm({
473
- message: "".concat(chalk_1.default.cyan(nextConfigJs), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
513
+ message: "".concat(chalk_1.default.cyan(foundNextConfigFileFilename), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
474
514
  }))];
475
515
  case 3:
476
516
  injectAnyhow = _b.sent();
@@ -478,23 +518,26 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
478
518
  _b.label = 4;
479
519
  case 4:
480
520
  if (!shouldInject) return [3 /*break*/, 6];
481
- return [4 /*yield*/, fs.promises.appendFile(path.join(process.cwd(), nextConfigJs), (0, templates_1.getNextjsConfigCjsAppendix)(withSentryConfigOptionsTemplate), 'utf8')];
521
+ return [4 /*yield*/, fs.promises.appendFile(path.join(process.cwd(), foundNextConfigFileFilename), (0, templates_1.getNextjsConfigCjsAppendix)(withSentryConfigOptionsTemplate), 'utf8')];
482
522
  case 5:
483
523
  _b.sent();
484
- prompts_1.default.log.success("Added Sentry configuration to ".concat(chalk_1.default.cyan(nextConfigJs), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
524
+ prompts_1.default.log.success("Added Sentry configuration to ".concat(chalk_1.default.cyan(foundNextConfigFileFilename), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
485
525
  _b.label = 6;
486
526
  case 6:
487
527
  Sentry.setTag('next-config-mod-result', 'success');
488
528
  _b.label = 7;
489
529
  case 7:
490
- if (!nextConfigMjsExists) return [3 /*break*/, 16];
491
- nextConfigMjsContent = fs.readFileSync(path.join(process.cwd(), nextConfigMjs), 'utf8');
530
+ if (!(foundNextConfigFileType === 'mjs' ||
531
+ foundNextConfigFileType === 'mts' ||
532
+ foundNextConfigFileType === 'cts' ||
533
+ foundNextConfigFileType === 'ts')) return [3 /*break*/, 16];
534
+ nextConfigMjsContent = fs.readFileSync(path.join(process.cwd(), foundNextConfigFileFilename), 'utf8');
492
535
  probablyIncludesSdk = nextConfigMjsContent.includes('@sentry/nextjs') &&
493
536
  nextConfigMjsContent.includes('withSentryConfig');
494
537
  shouldInject = true;
495
538
  if (!probablyIncludesSdk) return [3 /*break*/, 9];
496
539
  return [4 /*yield*/, (0, clack_utils_1.abortIfCancelled)(prompts_1.default.confirm({
497
- message: "".concat(chalk_1.default.cyan(nextConfigMjs), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
540
+ message: "".concat(chalk_1.default.cyan(foundNextConfigFileFilename), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
498
541
  }))];
499
542
  case 8:
500
543
  injectAnyhow = _b.sent();
@@ -513,25 +556,25 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
513
556
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
514
557
  mod.exports.default = magicast_1.builders.raw("withSentryConfig(\n ".concat(expressionToWrap, ",\n ").concat(withSentryConfigOptionsTemplate, "\n)"));
515
558
  newCode = mod.generate().code;
516
- return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), nextConfigMjs), newCode, {
559
+ return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), foundNextConfigFileFilename), newCode, {
517
560
  encoding: 'utf8',
518
561
  flag: 'w',
519
562
  })];
520
563
  case 10:
521
564
  _b.sent();
522
- prompts_1.default.log.success("Added Sentry configuration to ".concat(chalk_1.default.cyan(nextConfigMjs), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
565
+ prompts_1.default.log.success("Added Sentry configuration to ".concat(chalk_1.default.cyan(foundNextConfigFileFilename), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
523
566
  Sentry.setTag('next-config-mod-result', 'success');
524
567
  _b.label = 11;
525
568
  case 11: return [3 /*break*/, 16];
526
569
  case 12:
527
570
  _a = _b.sent();
528
571
  Sentry.setTag('next-config-mod-result', 'fail');
529
- prompts_1.default.log.warn(chalk_1.default.yellow("Something went wrong writing to ".concat(chalk_1.default.cyan(nextConfigMjs))));
530
- prompts_1.default.log.info("Please put the following code snippet into ".concat(chalk_1.default.cyan(nextConfigMjs), ": ").concat(chalk_1.default.dim('You probably have to clean it up a bit.'), "\n"));
572
+ prompts_1.default.log.warn(chalk_1.default.yellow("Something went wrong writing to ".concat(chalk_1.default.cyan(foundNextConfigFileFilename), ".")));
573
+ prompts_1.default.log.info("Please put the following code snippet into ".concat(chalk_1.default.cyan(foundNextConfigFileFilename), ": ").concat(chalk_1.default.dim('You probably have to clean it up a bit.'), "\n"));
531
574
  // eslint-disable-next-line no-console
532
575
  console.log((0, templates_1.getNextjsConfigEsmCopyPasteSnippet)(withSentryConfigOptionsTemplate));
533
576
  return [4 /*yield*/, (0, clack_utils_1.abortIfCancelled)(prompts_1.default.confirm({
534
- message: "Are you done putting the snippet above into ".concat(chalk_1.default.cyan(nextConfigMjs), "?"),
577
+ message: "Are you done putting the snippet above into ".concat(chalk_1.default.cyan(foundNextConfigFileFilename), "?"),
535
578
  active: 'Yes',
536
579
  inactive: 'No, get me out of here',
537
580
  }))];
@@ -554,43 +597,45 @@ function createOrMergeNextJsFiles(selectedProject, selfHosted, sentryUrl, sdkCon
554
597
  });
555
598
  });
556
599
  }
600
+ function hasDirectoryPathFromRoot(dirnameOrDirs) {
601
+ var dirPath = Array.isArray(dirnameOrDirs)
602
+ ? path.join.apply(path, __spreadArray([process.cwd()], dirnameOrDirs, false)) : path.join(process.cwd(), dirnameOrDirs);
603
+ return fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
604
+ }
557
605
  function createExamplePage(selfHosted, selectedProject, sentryUrl) {
558
606
  return __awaiter(this, void 0, void 0, function () {
559
- var srcDir, maybePagesDirPath, maybeSrcPagesDirPath, maybeAppDirPath, maybeSrcAppDirPath, typeScriptDetected, pagesLocation, appLocation, examplePageContents, newPageFileName, newRouteFileName, examplePageContents;
607
+ var hasSrcDirectory, hasRootAppDirectory, hasRootPagesDirectory, hasSrcAppDirectory, hasSrcPagesDirectory, typeScriptDetected, appFolderLocation, pagesFolderLocation, newPagesFolderLocation, examplePageContents, newPageFileName, newRouteFileName, examplePageContents;
560
608
  return __generator(this, function (_a) {
561
609
  switch (_a.label) {
562
610
  case 0:
563
- srcDir = path.join(process.cwd(), 'src');
564
- maybePagesDirPath = path.join(process.cwd(), 'pages');
565
- maybeSrcPagesDirPath = path.join(srcDir, 'pages');
566
- maybeAppDirPath = path.join(process.cwd(), 'app');
567
- maybeSrcAppDirPath = path.join(srcDir, 'app');
611
+ hasSrcDirectory = hasDirectoryPathFromRoot('src');
612
+ hasRootAppDirectory = hasDirectoryPathFromRoot('app');
613
+ hasRootPagesDirectory = hasDirectoryPathFromRoot('pages');
614
+ hasSrcAppDirectory = hasDirectoryPathFromRoot(['src', 'app']);
615
+ hasSrcPagesDirectory = hasDirectoryPathFromRoot(['src', 'pages']);
616
+ Sentry.setTag('nextjs-app-dir', hasRootAppDirectory || hasSrcAppDirectory);
568
617
  typeScriptDetected = (0, clack_utils_1.isUsingTypeScript)();
569
- pagesLocation = fs.existsSync(maybePagesDirPath) &&
570
- fs.lstatSync(maybePagesDirPath).isDirectory()
571
- ? ['pages']
572
- : fs.existsSync(maybeSrcPagesDirPath) &&
573
- fs.lstatSync(maybeSrcPagesDirPath).isDirectory()
574
- ? ['src', 'pages']
575
- : undefined;
576
- appLocation = fs.existsSync(maybeAppDirPath) &&
577
- fs.lstatSync(maybeAppDirPath).isDirectory()
618
+ appFolderLocation = hasRootAppDirectory
578
619
  ? ['app']
579
- : fs.existsSync(maybeSrcAppDirPath) &&
580
- fs.lstatSync(maybeSrcAppDirPath).isDirectory()
620
+ : hasSrcAppDirectory
581
621
  ? ['src', 'app']
582
622
  : undefined;
583
- if (!pagesLocation && !appLocation) {
584
- pagesLocation =
585
- fs.existsSync(srcDir) && fs.lstatSync(srcDir).isDirectory()
586
- ? ['src', 'pages']
587
- : ['pages'];
588
- fs.mkdirSync(path.join.apply(path, __spreadArray([process.cwd()], pagesLocation, false)), {
623
+ pagesFolderLocation = hasRootPagesDirectory
624
+ ? ['pages']
625
+ : hasSrcPagesDirectory
626
+ ? ['src', 'pages']
627
+ : undefined;
628
+ // If the user has neither pages nor app directory we create a pages folder for them
629
+ if (!appFolderLocation && !pagesFolderLocation) {
630
+ newPagesFolderLocation = hasSrcDirectory
631
+ ? ['src', 'pages']
632
+ : ['pages'];
633
+ fs.mkdirSync(path.join.apply(path, __spreadArray([process.cwd()], newPagesFolderLocation, false)), {
589
634
  recursive: true,
590
635
  });
636
+ pagesFolderLocation = newPagesFolderLocation;
591
637
  }
592
- Sentry.setTag('nextjs-app-dir', !!appLocation);
593
- if (!appLocation) return [3 /*break*/, 3];
638
+ if (!appFolderLocation) return [3 /*break*/, 3];
594
639
  examplePageContents = (0, templates_1.getSentryExamplePageContents)({
595
640
  selfHosted: selfHosted,
596
641
  orgSlug: selectedProject.organization.slug,
@@ -598,30 +643,31 @@ function createExamplePage(selfHosted, selectedProject, sentryUrl) {
598
643
  sentryUrl: sentryUrl,
599
644
  useClient: true,
600
645
  });
601
- fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appLocation, false), ['sentry-example-page'], false)), {
646
+ fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appFolderLocation, false), ['sentry-example-page'], false)), {
602
647
  recursive: true,
603
648
  });
604
649
  newPageFileName = "page.".concat(typeScriptDetected ? 'tsx' : 'jsx');
605
- return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appLocation, false), ['sentry-example-page',
650
+ return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appFolderLocation, false), ['sentry-example-page',
606
651
  newPageFileName], false)), examplePageContents, { encoding: 'utf8', flag: 'w' })];
607
652
  case 1:
608
653
  _a.sent();
609
- prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], appLocation, false), ['sentry-example-page', newPageFileName], false))), "."));
610
- fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appLocation, false), ['api', 'sentry-example-api'], false)), {
654
+ prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], appFolderLocation, false), ['sentry-example-page', newPageFileName], false))), "."));
655
+ fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appFolderLocation, false), ['api',
656
+ 'sentry-example-api'], false)), {
611
657
  recursive: true,
612
658
  });
613
659
  newRouteFileName = "route.".concat(typeScriptDetected ? 'ts' : 'js');
614
- return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appLocation, false), ['api',
660
+ return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], appFolderLocation, false), ['api',
615
661
  'sentry-example-api',
616
662
  newRouteFileName], false)), (0, templates_1.getSentryExampleAppDirApiRoute)(), { encoding: 'utf8', flag: 'w' })];
617
663
  case 2:
618
664
  _a.sent();
619
- prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], appLocation, false), ['api',
665
+ prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], appFolderLocation, false), ['api',
620
666
  'sentry-example-api',
621
667
  newRouteFileName], false))), "."));
622
668
  return [3 /*break*/, 6];
623
669
  case 3:
624
- if (!pagesLocation) return [3 /*break*/, 6];
670
+ if (!pagesFolderLocation) return [3 /*break*/, 6];
625
671
  examplePageContents = (0, templates_1.getSentryExamplePageContents)({
626
672
  selfHosted: selfHosted,
627
673
  orgSlug: selectedProject.organization.slug,
@@ -629,18 +675,18 @@ function createExamplePage(selfHosted, selectedProject, sentryUrl) {
629
675
  sentryUrl: sentryUrl,
630
676
  useClient: false,
631
677
  });
632
- return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['sentry-example-page.jsx'], false)), examplePageContents, { encoding: 'utf8', flag: 'w' })];
678
+ return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesFolderLocation, false), ['sentry-example-page.jsx'], false)), examplePageContents, { encoding: 'utf8', flag: 'w' })];
633
679
  case 4:
634
680
  _a.sent();
635
- prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], pagesLocation, false), ['sentry-example-page.js'], false))), "."));
636
- fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['api'], false)), {
681
+ prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], pagesFolderLocation, false), ['sentry-example-page.js'], false))), "."));
682
+ fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesFolderLocation, false), ['api'], false)), {
637
683
  recursive: true,
638
684
  });
639
- return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['api',
640
- 'sentry-example-api.js'], false)), (0, templates_1.getSentryExampleApiRoute)(), { encoding: 'utf8', flag: 'w' })];
685
+ return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesFolderLocation, false), ['api',
686
+ 'sentry-example-api.js'], false)), (0, templates_1.getSentryExamplePagesDirApiRoute)(), { encoding: 'utf8', flag: 'w' })];
641
687
  case 5:
642
688
  _a.sent();
643
- prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], pagesLocation, false), ['api', 'sentry-example-api.js'], false))), "."));
689
+ prompts_1.default.log.success("Created ".concat(chalk_1.default.cyan(path.join.apply(path, __spreadArray(__spreadArray([], pagesFolderLocation, false), ['api', 'sentry-example-api.js'], false))), "."));
644
690
  _a.label = 6;
645
691
  case 6: return [2 /*return*/];
646
692
  }
@@ -691,4 +737,40 @@ function askShouldSetTunnelRoute() {
691
737
  });
692
738
  });
693
739
  }
740
+ function askShouldEnableReactComponentAnnotation() {
741
+ return __awaiter(this, void 0, void 0, function () {
742
+ var _this = this;
743
+ return __generator(this, function (_a) {
744
+ switch (_a.label) {
745
+ case 0: return [4 /*yield*/, (0, telemetry_1.traceStep)('ask-react-component-annotation-option', function () { return __awaiter(_this, void 0, void 0, function () {
746
+ var shouldEnableReactComponentAnnotation;
747
+ return __generator(this, function (_a) {
748
+ switch (_a.label) {
749
+ case 0: return [4 /*yield*/, (0, clack_utils_1.abortIfCancelled)(prompts_1.default.select({
750
+ message: 'Do you want to enable React component annotations to make breadcrumbs and session replays more readable?',
751
+ options: [
752
+ {
753
+ label: 'Yes',
754
+ value: true,
755
+ hint: 'Annotates React component names (increases bundle size)',
756
+ },
757
+ {
758
+ label: 'No',
759
+ value: false,
760
+ hint: 'Continue without React component annotations',
761
+ },
762
+ ],
763
+ initialValue: false,
764
+ }))];
765
+ case 1:
766
+ shouldEnableReactComponentAnnotation = _a.sent();
767
+ return [2 /*return*/, shouldEnableReactComponentAnnotation];
768
+ }
769
+ });
770
+ }); })];
771
+ case 1: return [2 /*return*/, _a.sent()];
772
+ }
773
+ });
774
+ });
775
+ }
694
776
  //# sourceMappingURL=nextjs-wizard.js.map