@sentry/wizard 3.26.0 → 3.27.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 (36) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/package.json +2 -1
  3. package/dist/src/nextjs/nextjs-wizard.js +30 -17
  4. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  5. package/dist/src/nextjs/templates.d.ts +4 -1
  6. package/dist/src/nextjs/templates.js +18 -7
  7. package/dist/src/nextjs/templates.js.map +1 -1
  8. package/dist/src/run.js +1 -1
  9. package/dist/src/run.js.map +1 -1
  10. package/dist/src/sourcemaps/sourcemaps-wizard.js +1 -1
  11. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  12. package/dist/src/utils/clack-utils.d.ts +4 -1
  13. package/dist/src/utils/clack-utils.js +47 -1
  14. package/dist/src/utils/clack-utils.js.map +1 -1
  15. package/dist/src/utils/package-manager.d.ts +4 -1
  16. package/dist/src/utils/package-manager.js +40 -5
  17. package/dist/src/utils/package-manager.js.map +1 -1
  18. package/dist/src/utils/types.d.ts +6 -0
  19. package/dist/src/utils/types.js.map +1 -1
  20. package/dist/src/utils/url.js +7 -2
  21. package/dist/src/utils/url.js.map +1 -1
  22. package/dist/test/nextjs/templates.test.js +65 -1
  23. package/dist/test/nextjs/templates.test.js.map +1 -1
  24. package/dist/test/sourcemaps/tools/sentry-cli.test.js +2 -1
  25. package/dist/test/sourcemaps/tools/sentry-cli.test.js.map +1 -1
  26. package/package.json +2 -1
  27. package/src/nextjs/nextjs-wizard.ts +23 -4
  28. package/src/nextjs/templates.ts +35 -22
  29. package/src/run.ts +1 -1
  30. package/src/sourcemaps/sourcemaps-wizard.ts +1 -1
  31. package/src/utils/clack-utils.ts +34 -1
  32. package/src/utils/package-manager.ts +38 -4
  33. package/src/utils/types.ts +7 -0
  34. package/src/utils/url.ts +6 -2
  35. package/test/nextjs/templates.test.ts +240 -2
  36. package/test/sourcemaps/tools/sentry-cli.test.ts +2 -1
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.detectPackageManger = exports.packageManagers = exports.NPM = exports.PNPM = exports.YARN = exports.BUN = void 0;
26
+ exports.detectPackageManger = exports.packageManagers = exports.NPM = exports.PNPM = exports.YARN_V2 = exports.YARN_V1 = exports.BUN = void 0;
27
27
  /* eslint-disable @typescript-eslint/typedef */
28
28
  var fs = __importStar(require("fs"));
29
29
  var path = __importStar(require("path"));
@@ -37,15 +37,48 @@ exports.BUN = {
37
37
  buildCommand: 'bun run build',
38
38
  runScriptCommand: 'bun run',
39
39
  flags: '',
40
+ detect: function () { return fs.existsSync(path.join(process.cwd(), exports.BUN.lockFile)); },
40
41
  };
41
- exports.YARN = {
42
+ exports.YARN_V1 = {
42
43
  name: 'yarn',
43
- label: 'Yarn',
44
+ label: 'Yarn V1',
44
45
  lockFile: 'yarn.lock',
45
46
  installCommand: 'yarn add',
46
47
  buildCommand: 'yarn build',
47
48
  runScriptCommand: 'yarn',
48
49
  flags: '--ignore-workspace-root-check',
50
+ detect: function () {
51
+ try {
52
+ return fs
53
+ .readFileSync(path.join(process.cwd(), exports.YARN_V1.lockFile), 'utf-8')
54
+ .slice(0, 500)
55
+ .includes('yarn lockfile v1');
56
+ }
57
+ catch (e) {
58
+ return false;
59
+ }
60
+ },
61
+ };
62
+ /** YARN V2/3/4 */
63
+ exports.YARN_V2 = {
64
+ name: 'yarn',
65
+ label: 'Yarn V2/3/4',
66
+ lockFile: 'yarn.lock',
67
+ installCommand: 'yarn add',
68
+ buildCommand: 'yarn build',
69
+ runScriptCommand: 'yarn',
70
+ flags: '',
71
+ detect: function () {
72
+ try {
73
+ return fs
74
+ .readFileSync(path.join(process.cwd(), exports.YARN_V2.lockFile), 'utf-8')
75
+ .slice(0, 500)
76
+ .includes('__metadata');
77
+ }
78
+ catch (e) {
79
+ return false;
80
+ }
81
+ },
49
82
  };
50
83
  exports.PNPM = {
51
84
  name: 'pnpm',
@@ -55,6 +88,7 @@ exports.PNPM = {
55
88
  buildCommand: 'pnpm build',
56
89
  runScriptCommand: 'pnpm',
57
90
  flags: '--ignore-workspace-root-check',
91
+ detect: function () { return fs.existsSync(path.join(process.cwd(), exports.PNPM.lockFile)); },
58
92
  };
59
93
  exports.NPM = {
60
94
  name: 'npm',
@@ -64,13 +98,14 @@ exports.NPM = {
64
98
  buildCommand: 'npm run build',
65
99
  runScriptCommand: 'npm run',
66
100
  flags: '',
101
+ detect: function () { return fs.existsSync(path.join(process.cwd(), exports.NPM.lockFile)); },
67
102
  };
68
- exports.packageManagers = [exports.BUN, exports.YARN, exports.PNPM, exports.NPM];
103
+ exports.packageManagers = [exports.BUN, exports.YARN_V1, exports.YARN_V2, exports.PNPM, exports.NPM];
69
104
  function detectPackageManger() {
70
105
  return (0, telemetry_1.traceStep)('detect-package-manager', function () {
71
106
  for (var _i = 0, packageManagers_1 = exports.packageManagers; _i < packageManagers_1.length; _i++) {
72
107
  var packageManager = packageManagers_1[_i];
73
- if (fs.existsSync(path.join(process.cwd(), packageManager.lockFile))) {
108
+ if (packageManager.detect()) {
74
109
  Sentry.setTag('package-manager', packageManager.name);
75
110
  return packageManager;
76
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../../src/utils/package-manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA+C;AAC/C,qCAAyB;AACzB,yCAA6B;AAE7B,mDAAuC;AACvC,0CAAyC;AAa5B,QAAA,GAAG,GAAmB;IACjC,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,WAAW;IACrB,cAAc,EAAE,SAAS;IACzB,YAAY,EAAE,eAAe;IAC7B,gBAAgB,EAAE,SAAS;IAC3B,KAAK,EAAE,EAAE;CACV,CAAC;AACW,QAAA,IAAI,GAAmB;IAClC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,WAAW;IACrB,cAAc,EAAE,UAAU;IAC1B,YAAY,EAAE,YAAY;IAC1B,gBAAgB,EAAE,MAAM;IACxB,KAAK,EAAE,+BAA+B;CACvC,CAAC;AACW,QAAA,IAAI,GAAmB;IAClC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,gBAAgB;IAC1B,cAAc,EAAE,UAAU;IAC1B,YAAY,EAAE,YAAY;IAC1B,gBAAgB,EAAE,MAAM;IACxB,KAAK,EAAE,+BAA+B;CACvC,CAAC;AACW,QAAA,GAAG,GAAmB;IACjC,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,mBAAmB;IAC7B,cAAc,EAAE,SAAS;IACzB,YAAY,EAAE,eAAe;IAC7B,gBAAgB,EAAE,SAAS;IAC3B,KAAK,EAAE,EAAE;CACV,CAAC;AAEW,QAAA,eAAe,GAAG,CAAC,WAAG,EAAE,YAAI,EAAE,YAAI,EAAE,WAAG,CAAC,CAAC;AAEtD,SAAgB,mBAAmB;IACjC,OAAO,IAAA,qBAAS,EAAC,wBAAwB,EAAE;QACzC,KAA6B,UAAe,EAAf,oBAAA,uBAAe,EAAf,6BAAe,EAAf,IAAe,EAAE;YAAzC,IAAM,cAAc,wBAAA;YACvB,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAE;gBACpE,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;gBACtD,OAAO,cAAc,CAAC;aACvB;SACF;QACD,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAXD,kDAWC","sourcesContent":["/* eslint-disable @typescript-eslint/typedef */\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport * as Sentry from '@sentry/node';\nimport { traceStep } from '../telemetry';\n\nexport interface PackageManager {\n name: string;\n label: string;\n lockFile: string;\n installCommand: string;\n buildCommand: string;\n /* The command that the package manager uses to run a script from package.json */\n runScriptCommand: string;\n flags: string;\n}\n\nexport const BUN: PackageManager = {\n name: 'bun',\n label: 'Bun',\n lockFile: 'bun.lockb',\n installCommand: 'bun add',\n buildCommand: 'bun run build',\n runScriptCommand: 'bun run',\n flags: '',\n};\nexport const YARN: PackageManager = {\n name: 'yarn',\n label: 'Yarn',\n lockFile: 'yarn.lock',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '--ignore-workspace-root-check',\n};\nexport const PNPM: PackageManager = {\n name: 'pnpm',\n label: 'PNPM',\n lockFile: 'pnpm-lock.yaml',\n installCommand: 'pnpm add',\n buildCommand: 'pnpm build',\n runScriptCommand: 'pnpm',\n flags: '--ignore-workspace-root-check',\n};\nexport const NPM: PackageManager = {\n name: 'npm',\n label: 'NPM',\n lockFile: 'package-lock.json',\n installCommand: 'npm add',\n buildCommand: 'npm run build',\n runScriptCommand: 'npm run',\n flags: '',\n};\n\nexport const packageManagers = [BUN, YARN, PNPM, NPM];\n\nexport function detectPackageManger(): PackageManager | null {\n return traceStep('detect-package-manager', () => {\n for (const packageManager of packageManagers) {\n if (fs.existsSync(path.join(process.cwd(), packageManager.lockFile))) {\n Sentry.setTag('package-manager', packageManager.name);\n return packageManager;\n }\n }\n Sentry.setTag('package-manager', 'not-detected');\n return null;\n });\n}\n"]}
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../../src/utils/package-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/typedef */\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport * as Sentry from '@sentry/node';\nimport { traceStep } from '../telemetry';\n\nexport interface PackageManager {\n name: string;\n label: string;\n lockFile: string;\n installCommand: string;\n buildCommand: string;\n /* The command that the package manager uses to run a script from package.json */\n runScriptCommand: string;\n flags: string;\n detect: () => boolean;\n}\n\nexport const BUN: PackageManager = {\n name: 'bun',\n label: 'Bun',\n lockFile: 'bun.lockb',\n installCommand: 'bun add',\n buildCommand: 'bun run build',\n runScriptCommand: 'bun run',\n flags: '',\n detect: () => fs.existsSync(path.join(process.cwd(), BUN.lockFile)),\n};\nexport const YARN_V1: PackageManager = {\n name: 'yarn',\n label: 'Yarn V1',\n lockFile: 'yarn.lock',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '--ignore-workspace-root-check',\n detect: () => {\n try {\n return fs\n .readFileSync(path.join(process.cwd(), YARN_V1.lockFile), 'utf-8')\n .slice(0, 500)\n .includes('yarn lockfile v1');\n } catch (e) {\n return false;\n }\n },\n};\n/** YARN V2/3/4 */\nexport const YARN_V2: PackageManager = {\n name: 'yarn',\n label: 'Yarn V2/3/4',\n lockFile: 'yarn.lock',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '',\n detect: () => {\n try {\n return fs\n .readFileSync(path.join(process.cwd(), YARN_V2.lockFile), 'utf-8')\n .slice(0, 500)\n .includes('__metadata');\n } catch (e) {\n return false;\n }\n },\n};\nexport const PNPM: PackageManager = {\n name: 'pnpm',\n label: 'PNPM',\n lockFile: 'pnpm-lock.yaml',\n installCommand: 'pnpm add',\n buildCommand: 'pnpm build',\n runScriptCommand: 'pnpm',\n flags: '--ignore-workspace-root-check',\n detect: () => fs.existsSync(path.join(process.cwd(), PNPM.lockFile)),\n};\nexport const NPM: PackageManager = {\n name: 'npm',\n label: 'NPM',\n lockFile: 'package-lock.json',\n installCommand: 'npm add',\n buildCommand: 'npm run build',\n runScriptCommand: 'npm run',\n flags: '',\n detect: () => fs.existsSync(path.join(process.cwd(), NPM.lockFile)),\n};\n\nexport const packageManagers = [BUN, YARN_V1, YARN_V2, PNPM, NPM];\n\nexport function detectPackageManger(): PackageManager | null {\n return traceStep('detect-package-manager', () => {\n for (const packageManager of packageManagers) {\n if (packageManager.detect()) {\n Sentry.setTag('package-manager', packageManager.name);\n return packageManager;\n }\n }\n Sentry.setTag('package-manager', 'not-detected');\n return null;\n });\n}\n"]}
@@ -45,3 +45,9 @@ export type WizardOptions = {
45
45
  selfHosted: boolean;
46
46
  };
47
47
  };
48
+ export interface Feature {
49
+ id: string;
50
+ prompt: string;
51
+ enabledHint?: string;
52
+ disabledHint?: string;
53
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface SentryProjectData {\n id: string;\n slug: string;\n status: string;\n organization: {\n id: string;\n name: string;\n slug: string;\n region: string;\n status: {\n id: string;\n name: string;\n };\n };\n keys: [{ dsn: { public: string }; isActive: boolean }];\n}\n\nexport type WizardOptions = {\n /**\n * Controls whether the wizard should send telemetry data to Sentry.\n */\n telemetryEnabled: boolean;\n\n /**\n * The promo code to use while signing up for Sentry.\n * This can be passed via the --promo-code arg.\n */\n promoCode?: string;\n\n /**\n * The url of the Sentry instance to use.\n * This can be passed via the `-u` or `--url` arg.\n */\n url?: string;\n\n /**\n * If this is set, the wizard will skip the login and project selection step.\n * (This can not yet be set externally but for example when redirecting from\n * one wizard to another when the project was already selected)\n */\n preSelectedProject?: {\n project: SentryProjectData;\n authToken: string;\n selfHosted: boolean;\n };\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface SentryProjectData {\n id: string;\n slug: string;\n status: string;\n organization: {\n id: string;\n name: string;\n slug: string;\n region: string;\n status: {\n id: string;\n name: string;\n };\n };\n keys: [{ dsn: { public: string }; isActive: boolean }];\n}\n\nexport type WizardOptions = {\n /**\n * Controls whether the wizard should send telemetry data to Sentry.\n */\n telemetryEnabled: boolean;\n\n /**\n * The promo code to use while signing up for Sentry.\n * This can be passed via the --promo-code arg.\n */\n promoCode?: string;\n\n /**\n * The url of the Sentry instance to use.\n * This can be passed via the `-u` or `--url` arg.\n */\n url?: string;\n\n /**\n * If this is set, the wizard will skip the login and project selection step.\n * (This can not yet be set externally but for example when redirecting from\n * one wizard to another when the project was already selected)\n */\n preSelectedProject?: {\n project: SentryProjectData;\n authToken: string;\n selfHosted: boolean;\n };\n};\n\nexport interface Feature {\n id: string;\n prompt: string;\n enabledHint?: string;\n disabledHint?: string;\n}\n"]}
@@ -10,8 +10,13 @@ var url_1 = require("url");
10
10
  function getIssueStreamUrl(_a) {
11
11
  var url = _a.url, orgSlug = _a.orgSlug, projectId = _a.projectId;
12
12
  var urlObject = new url_1.URL(url);
13
- urlObject.host = "".concat(orgSlug, ".").concat(urlObject.host);
14
- urlObject.pathname = '/issues/';
13
+ if (urlObject.host === 'sentry.io') {
14
+ urlObject.host = "".concat(orgSlug, ".").concat(urlObject.host);
15
+ urlObject.pathname = '/issues/';
16
+ }
17
+ else {
18
+ urlObject.pathname = "/organizations/".concat(orgSlug, "/issues/");
19
+ }
15
20
  urlObject.searchParams.set('project', projectId);
16
21
  return urlObject.toString();
17
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/utils/url.ts"],"names":[],"mappings":";;;AAAA,2BAA0B;AAE1B;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,EAQjC;QAPC,GAAG,SAAA,EACH,OAAO,aAAA,EACP,SAAS,eAAA;IAMT,IAAM,SAAS,GAAG,IAAI,SAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,SAAS,CAAC,IAAI,GAAG,UAAG,OAAO,cAAI,SAAS,CAAC,IAAI,CAAE,CAAC;IAChD,SAAS,CAAC,QAAQ,GAAG,UAAU,CAAC;IAChC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEjD,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAfD,8CAeC","sourcesContent":["import { URL } from 'url';\n\n/**\n * Returns the url to the Sentry project stream.\n *\n * Example: https://org-slug.sentry.io/issues/?project=1234567\n */\nexport function getIssueStreamUrl({\n url,\n orgSlug,\n projectId,\n}: {\n url: string;\n orgSlug: string;\n projectId: string;\n}): string {\n const urlObject = new URL(url);\n urlObject.host = `${orgSlug}.${urlObject.host}`;\n urlObject.pathname = '/issues/';\n urlObject.searchParams.set('project', projectId);\n\n return urlObject.toString();\n}\n"]}
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/utils/url.ts"],"names":[],"mappings":";;;AAAA,2BAA0B;AAE1B;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,EAQjC;QAPC,GAAG,SAAA,EACH,OAAO,aAAA,EACP,SAAS,eAAA;IAMT,IAAM,SAAS,GAAG,IAAI,SAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,EAAE;QAClC,SAAS,CAAC,IAAI,GAAG,UAAG,OAAO,cAAI,SAAS,CAAC,IAAI,CAAE,CAAC;QAChD,SAAS,CAAC,QAAQ,GAAG,UAAU,CAAC;KACjC;SAAM;QACL,SAAS,CAAC,QAAQ,GAAG,yBAAkB,OAAO,aAAU,CAAC;KAC1D;IACD,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEjD,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAnBD,8CAmBC","sourcesContent":["import { URL } from 'url';\n\n/**\n * Returns the url to the Sentry project stream.\n *\n * Example: https://org-slug.sentry.io/issues/?project=1234567\n */\nexport function getIssueStreamUrl({\n url,\n orgSlug,\n projectId,\n}: {\n url: string;\n orgSlug: string;\n projectId: string;\n}): string {\n const urlObject = new URL(url);\n if (urlObject.host === 'sentry.io') {\n urlObject.host = `${orgSlug}.${urlObject.host}`;\n urlObject.pathname = '/issues/';\n } else {\n urlObject.pathname = `/organizations/${orgSlug}/issues/`;\n }\n urlObject.searchParams.set('project', projectId);\n\n return urlObject.toString();\n}\n"]}
@@ -1,7 +1,71 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var templates_1 = require("../../src/nextjs/templates");
4
- describe('NextJS code templates', function () {
4
+ describe('Next.js code templates', function () {
5
+ describe('getSentryConfigContents', function () {
6
+ describe('client-side', function () {
7
+ it('generates client-side Sentry config with all features enabled', function () {
8
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'client', {
9
+ performance: true,
10
+ replay: true,
11
+ });
12
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
13
+ });
14
+ it('generates client-side Sentry config with performance monitoring disabled', function () {
15
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'client', {
16
+ performance: false,
17
+ replay: true,
18
+ });
19
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
20
+ });
21
+ it('generates client-side Sentry config with session replay disabled', function () {
22
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'client', {
23
+ performance: true,
24
+ replay: false,
25
+ });
26
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
27
+ });
28
+ });
29
+ describe('server-side', function () {
30
+ it('generates server-side Sentry config with all features enabled', function () {
31
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'server', {
32
+ performance: true,
33
+ replay: true,
34
+ });
35
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
36
+ });
37
+ it('generates server-side Sentry config with performance monitoring disabled', function () {
38
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'server', {
39
+ performance: false,
40
+ replay: true,
41
+ });
42
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
43
+ });
44
+ it('generates server-side Sentry config with spotlight disabled', function () {
45
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'server', {
46
+ performance: true,
47
+ replay: true,
48
+ });
49
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
50
+ });
51
+ });
52
+ describe('edge', function () {
53
+ it('generates edge Sentry config with all features enabled', function () {
54
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'edge', {
55
+ performance: true,
56
+ replay: true,
57
+ });
58
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
59
+ });
60
+ it('generates edge Sentry config with performance monitoring disabled', function () {
61
+ var template = (0, templates_1.getSentryConfigContents)('my-dsn', 'edge', {
62
+ performance: false,
63
+ replay: true,
64
+ });
65
+ expect(template).toMatchInlineSnapshot("\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n ");
66
+ });
67
+ });
68
+ });
5
69
  describe('getWithSentryConfigOptionsTemplate', function () {
6
70
  it('generates options for SaaS', function () {
7
71
  var template = (0, templates_1.getWithSentryConfigOptionsTemplate)({
@@ -1 +1 @@
1
- {"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/nextjs/templates.test.ts"],"names":[],"mappings":";;AAAA,wDAAgF;AAEhF,QAAQ,CAAC,uBAAuB,EAAE;IAChC,QAAQ,CAAC,oCAAoC,EAAE;QAC7C,EAAE,CAAC,4BAA4B,EAAE;YAC/B,IAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,+BAA+B;gBAC1C,WAAW,EAAE,IAAI;gBACjB,wBAAwB,EAAE,KAAK;aAChC,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,oiDAmCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE;YACtC,IAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,IAAI;gBAChB,SAAS,EAAE,uBAAuB;gBAClC,WAAW,EAAE,IAAI;gBACjB,wBAAwB,EAAE,KAAK;aAChC,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,ulDAoCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE;YACjE,IAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,+BAA+B;gBAC1C,WAAW,EAAE,KAAK;gBAClB,wBAAwB,EAAE,KAAK;aAChC,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,ojDAmCtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mFAAmF,EAAE;YACtF,IAAM,QAAQ,GAAG,IAAA,8CAAkC,EAAC;gBAClD,OAAO,EAAE,QAAQ;gBACjB,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,KAAK;gBACjB,SAAS,EAAE,+BAA+B;gBAC1C,WAAW,EAAE,IAAI;gBACjB,wBAAwB,EAAE,IAAI;aAC/B,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,qvDAwChC,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { getWithSentryConfigOptionsTemplate } from '../../src/nextjs/templates';\n\ndescribe('NextJS code templates', () => {\n describe('getWithSentryConfigOptionsTemplate', () => {\n it('generates options for SaaS', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('generates options for self-hosted', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: true,\n sentryUrl: 'https://my-sentry.com',\n tunnelRoute: true,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n sentryUrl: \"https://my-sentry.com\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('comments out tunnelRoute if `tunnelRoute` option is disabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: false,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('adds `reactComponentAnnotations` option if `reactComponentAnnotations` is enabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n reactComponentAnnotation: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Automatically annotate React components to show their full name in breadcrumbs and session replay\n reactComponentAnnotation: {\n enabled: true,\n },\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"templates.test.js","sourceRoot":"","sources":["../../../test/nextjs/templates.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getSentryConfigContents,\n getWithSentryConfigOptionsTemplate,\n} from '../../src/nextjs/templates';\n\ndescribe('Next.js code templates', () => {\n describe('getSentryConfigContents', () => {\n describe('client-side', () => {\n it('generates client-side Sentry config with all features enabled', () => {\n const template = getSentryConfigContents('my-dsn', 'client', {\n performance: true,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n\n it('generates client-side Sentry config with performance monitoring disabled', () => {\n const template = getSentryConfigContents('my-dsn', 'client', {\n performance: false,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Add optional integrations for additional features\n integrations: [\n Sentry.replayIntegration(),\n ],\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n\n it('generates client-side Sentry config with session replay disabled', () => {\n const template = getSentryConfigContents('my-dsn', 'client', {\n performance: true,\n replay: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the client.\n // The config you add here will be used whenever a users loads a page in their browser.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n });\n\n describe('server-side', () => {\n it('generates server-side Sentry config with all features enabled', () => {\n const template = getSentryConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with performance monitoring disabled', () => {\n const template = getSentryConfigContents('my-dsn', 'server', {\n performance: false,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n\n it('generates server-side Sentry config with spotlight disabled', () => {\n const template = getSentryConfigContents('my-dsn', 'server', {\n performance: true,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry on the server.\n // The config you add here will be used whenever the server handles a request.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n });\n\n describe('edge', () => {\n it('generates edge Sentry config with all features enabled', () => {\n const template = getSentryConfigContents('my-dsn', 'edge', {\n performance: true,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n\n it('generates edge Sentry config with performance monitoring disabled', () => {\n const template = getSentryConfigContents('my-dsn', 'edge', {\n performance: false,\n replay: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n // The config you add here will be used whenever one of the edge features is loaded.\n // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\n import * as Sentry from \"@sentry/nextjs\";\n\n Sentry.init({\n dsn: \"my-dsn\",\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n });\n \"\n `);\n });\n });\n });\n\n describe('getWithSentryConfigOptionsTemplate', () => {\n it('generates options for SaaS', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('generates options for self-hosted', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: true,\n sentryUrl: 'https://my-sentry.com',\n tunnelRoute: true,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n sentryUrl: \"https://my-sentry.com\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('comments out tunnelRoute if `tunnelRoute` option is disabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: false,\n reactComponentAnnotation: false,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n // tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n\n it('adds `reactComponentAnnotations` option if `reactComponentAnnotations` is enabled', () => {\n const template = getWithSentryConfigOptionsTemplate({\n orgSlug: 'my-org',\n projectSlug: 'my-project',\n selfHosted: false,\n sentryUrl: 'https://dont-use-this-url.com',\n tunnelRoute: true,\n reactComponentAnnotation: true,\n });\n\n expect(template).toMatchInlineSnapshot(`\n \"{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n org: \"my-org\",\n project: \"my-project\",\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Automatically annotate React components to show their full name in breadcrumbs and session replay\n reactComponentAnnotation: {\n enabled: true,\n },\n\n // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n }\"\n `);\n });\n });\n});\n"]}
@@ -101,7 +101,8 @@ describe('addSentryCommandToBuildCommand', function () {
101
101
  [
102
102
  packageManagerHelpers.NPM,
103
103
  packageManagerHelpers.PNPM,
104
- packageManagerHelpers.YARN,
104
+ packageManagerHelpers.YARN_V1,
105
+ packageManagerHelpers.YARN_V2,
105
106
  packageManagerHelpers.BUN,
106
107
  ],
107
108
  ])('adds the cli command to the script command (%s)', function (_, pacMan) { return __awaiter(void 0, void 0, void 0, function () {
@@ -1 +1 @@
1
- {"version":3,"file":"sentry-cli.test.js","sourceRoot":"","sources":["../../../../test/sourcemaps/tools/sentry-cli.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAyB;AAEzB,uEAA0F;AAE1F,wFAA4E;AAE5E,IAAM,YAAY,GAAG,IAAI;KACtB,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;KAC/B,kBAAkB,CAAC,cAAM,OAAA,OAAO,CAAC,OAAO,EAAE,EAAjB,CAAiB,CAAC,CAAC;AAE/C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;IAC1B,OAAO;QACL,GAAG,EAAE;YACH,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;SACnB;QACD,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC1C,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;KAC3C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,cAAM,OAAA,uBAC7C,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,KACvD,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;QAC7C,OAAO,EAAE;YACP,KAAK,EAAE,KAAK;SACb;QACD,OAAO,EAAE,OAAO;KACjB,CAAC,IACF,EARgD,CAQhD,CAAC,CAAC;AAEJ,QAAQ,CAAC,gCAAgC,EAAE;IACzC,SAAS,CAAC;QACR,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC;QACN;YACE,qBAAqB,CAAC,GAAG;YACzB,qBAAqB,CAAC,IAAI;YAC1B,qBAAqB,CAAC,IAAI;YAC1B,qBAAqB,CAAC,GAAG;SAC1B;KACF,CAAC,CAAC,iDAAiD,EAAE,UAAO,CAAC,EAAE,MAAM;;;;oBACpE,IAAI;yBACD,KAAK,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;yBACnD,eAAe,CAAC,MAAM,CAAC,CAAC;oBAC3B,qBAAM,IAAA,2CAA8B,GAAE,EAAA;;oBAAtC,SAAsC,CAAC;oBACvC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CACvC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,MAAM,CAAC,gBAAgB,CACrB,iBAAU,MAAM,CAAC,gBAAgB,uBAAoB,CACtD,CACF,CAAC;;;;SACH,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as fs from 'fs';\n\nimport { addSentryCommandToBuildCommand } from '../../../src/sourcemaps/tools/sentry-cli';\n\nimport * as packageManagerHelpers from '../../../src/utils/package-manager';\n\nconst writeFileSpy = jest\n .spyOn(fs.promises, 'writeFile')\n .mockImplementation(() => Promise.resolve());\n\njest.mock('@clack/prompts', () => {\n return {\n log: {\n info: jest.fn(),\n success: jest.fn(),\n },\n confirm: jest.fn().mockResolvedValue(true),\n isCancel: jest.fn().mockReturnValue(false),\n };\n});\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-return\njest.mock('../../../src/utils/clack-utils', () => ({\n ...jest.requireActual('../../../src/utils/clack-utils'),\n getPackageDotJson: jest.fn().mockResolvedValue({\n scripts: {\n build: 'tsc',\n },\n version: '1.0.0',\n }),\n}));\n\ndescribe('addSentryCommandToBuildCommand', () => {\n afterEach(() => {\n jest.clearAllMocks();\n });\n it.each([\n [\n packageManagerHelpers.NPM,\n packageManagerHelpers.PNPM,\n packageManagerHelpers.YARN,\n packageManagerHelpers.BUN,\n ],\n ])('adds the cli command to the script command (%s)', async (_, pacMan) => {\n jest\n .spyOn(packageManagerHelpers, 'detectPackageManger')\n .mockReturnValue(pacMan);\n await addSentryCommandToBuildCommand();\n expect(writeFileSpy).toHaveBeenCalledWith(\n expect.stringContaining('package.json'),\n expect.stringContaining(\n `tsc && ${pacMan.runScriptCommand} sentry:sourcemaps`,\n ),\n );\n });\n});\n"]}
1
+ {"version":3,"file":"sentry-cli.test.js","sourceRoot":"","sources":["../../../../test/sourcemaps/tools/sentry-cli.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAyB;AAEzB,uEAA0F;AAE1F,wFAA4E;AAE5E,IAAM,YAAY,GAAG,IAAI;KACtB,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;KAC/B,kBAAkB,CAAC,cAAM,OAAA,OAAO,CAAC,OAAO,EAAE,EAAjB,CAAiB,CAAC,CAAC;AAE/C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;IAC1B,OAAO;QACL,GAAG,EAAE;YACH,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;SACnB;QACD,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC1C,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;KAC3C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,cAAM,OAAA,uBAC7C,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,KACvD,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;QAC7C,OAAO,EAAE;YACP,KAAK,EAAE,KAAK;SACb;QACD,OAAO,EAAE,OAAO;KACjB,CAAC,IACF,EARgD,CAQhD,CAAC,CAAC;AAEJ,QAAQ,CAAC,gCAAgC,EAAE;IACzC,SAAS,CAAC;QACR,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC;QACN;YACE,qBAAqB,CAAC,GAAG;YACzB,qBAAqB,CAAC,IAAI;YAC1B,qBAAqB,CAAC,OAAO;YAC7B,qBAAqB,CAAC,OAAO;YAC7B,qBAAqB,CAAC,GAAG;SAC1B;KACF,CAAC,CAAC,iDAAiD,EAAE,UAAO,CAAC,EAAE,MAAM;;;;oBACpE,IAAI;yBACD,KAAK,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;yBACnD,eAAe,CAAC,MAAM,CAAC,CAAC;oBAC3B,qBAAM,IAAA,2CAA8B,GAAE,EAAA;;oBAAtC,SAAsC,CAAC;oBACvC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CACvC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,EACvC,MAAM,CAAC,gBAAgB,CACrB,iBAAU,MAAM,CAAC,gBAAgB,uBAAoB,CACtD,CACF,CAAC;;;;SACH,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as fs from 'fs';\n\nimport { addSentryCommandToBuildCommand } from '../../../src/sourcemaps/tools/sentry-cli';\n\nimport * as packageManagerHelpers from '../../../src/utils/package-manager';\n\nconst writeFileSpy = jest\n .spyOn(fs.promises, 'writeFile')\n .mockImplementation(() => Promise.resolve());\n\njest.mock('@clack/prompts', () => {\n return {\n log: {\n info: jest.fn(),\n success: jest.fn(),\n },\n confirm: jest.fn().mockResolvedValue(true),\n isCancel: jest.fn().mockReturnValue(false),\n };\n});\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-return\njest.mock('../../../src/utils/clack-utils', () => ({\n ...jest.requireActual('../../../src/utils/clack-utils'),\n getPackageDotJson: jest.fn().mockResolvedValue({\n scripts: {\n build: 'tsc',\n },\n version: '1.0.0',\n }),\n}));\n\ndescribe('addSentryCommandToBuildCommand', () => {\n afterEach(() => {\n jest.clearAllMocks();\n });\n it.each([\n [\n packageManagerHelpers.NPM,\n packageManagerHelpers.PNPM,\n packageManagerHelpers.YARN_V1,\n packageManagerHelpers.YARN_V2,\n packageManagerHelpers.BUN,\n ],\n ])('adds the cli command to the script command (%s)', async (_, pacMan) => {\n jest\n .spyOn(packageManagerHelpers, 'detectPackageManger')\n .mockReturnValue(pacMan);\n await addSentryCommandToBuildCommand();\n expect(writeFileSpy).toHaveBeenCalledWith(\n expect.stringContaining('package.json'),\n expect.stringContaining(\n `tsc && ${pacMan.runScriptCommand} sentry:sourcemaps`,\n ),\n );\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wizard",
3
- "version": "3.26.0",
3
+ "version": "3.27.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",
@@ -36,6 +36,7 @@
36
36
  "opn": "^5.4.0",
37
37
  "r2": "^2.0.1",
38
38
  "read-env": "^1.3.0",
39
+ "recast": "^0.23.3",
39
40
  "semver": "^7.5.3",
40
41
  "xcode": "3.0.1",
41
42
  "xml-js": "^1.6.11",
@@ -17,6 +17,7 @@ import {
17
17
  confirmContinueIfNoOrDirtyGitRepo,
18
18
  createNewConfigFile,
19
19
  ensurePackageIsInstalled,
20
+ featureSelectionPrompt,
20
21
  getOrAskForProjectData,
21
22
  getPackageDotJson,
22
23
  installPackage,
@@ -333,6 +334,23 @@ async function createOrMergeNextJsFiles(
333
334
  sentryUrl: string,
334
335
  sdkConfigOptions: SDKConfigOptions,
335
336
  ) {
337
+ const selectedFeatures = await featureSelectionPrompt([
338
+ {
339
+ id: 'performance',
340
+ prompt: `Do you want to enable ${chalk.bold(
341
+ 'Tracing',
342
+ )} to track the performance of your application?`,
343
+ enabledHint: 'recommended',
344
+ },
345
+ {
346
+ id: 'replay',
347
+ prompt: `Do you want to enable ${chalk.bold(
348
+ 'Sentry Session Replay',
349
+ )} to get reproduction of frontend errors via user sessions?`,
350
+ enabledHint: 'recommended, but increases bundle size',
351
+ },
352
+ ] as const);
353
+
336
354
  const typeScriptDetected = isUsingTypeScript();
337
355
 
338
356
  const configVariants = ['server', 'client', 'edge'] as const;
@@ -390,6 +408,7 @@ async function createOrMergeNextJsFiles(
390
408
  getSentryConfigContents(
391
409
  selectedProject.keys[0].dsn.public,
392
410
  configVariant,
411
+ selectedFeatures,
393
412
  ),
394
413
  { encoding: 'utf8', flag: 'w' },
395
414
  );
@@ -854,7 +873,7 @@ async function askShouldSetTunnelRoute() {
854
873
  const shouldSetTunnelRoute = await abortIfCancelled(
855
874
  clack.select({
856
875
  message:
857
- 'Do you want to route Sentry requests in the browser through your NextJS server to avoid ad blockers?',
876
+ 'Do you want to route Sentry requests in the browser through your Next.js server to avoid ad blockers?',
858
877
  options: [
859
878
  {
860
879
  label: 'Yes',
@@ -867,7 +886,7 @@ async function askShouldSetTunnelRoute() {
867
886
  hint: 'Browser errors and events might be blocked by ad blockers before being sent to Sentry',
868
887
  },
869
888
  ],
870
- initialValue: false,
889
+ initialValue: true,
871
890
  }),
872
891
  );
873
892
 
@@ -891,7 +910,7 @@ async function askShouldEnableReactComponentAnnotation() {
891
910
  {
892
911
  label: 'Yes',
893
912
  value: true,
894
- hint: 'Annotates React component names (increases bundle size)',
913
+ hint: 'Annotates React component names - increases bundle size',
895
914
  },
896
915
  {
897
916
  label: 'No',
@@ -899,7 +918,7 @@ async function askShouldEnableReactComponentAnnotation() {
899
918
  hint: 'Continue without React component annotations',
900
919
  },
901
920
  ],
902
- initialValue: false,
921
+ initialValue: true,
903
922
  }),
904
923
  );
905
924
 
@@ -112,9 +112,26 @@ export default withSentryConfig(
112
112
  `;
113
113
  }
114
114
 
115
+ function getClientIntegrationsSnippet(features: { replay: boolean }) {
116
+ if (features.replay) {
117
+ return `
118
+
119
+ // Add optional integrations for additional features
120
+ integrations: [
121
+ Sentry.replayIntegration(),
122
+ ],`;
123
+ }
124
+
125
+ return '';
126
+ }
127
+
115
128
  export function getSentryConfigContents(
116
129
  dsn: string,
117
130
  config: 'server' | 'client' | 'edge',
131
+ selectedFeaturesMap: {
132
+ replay: boolean;
133
+ performance: boolean;
134
+ },
118
135
  ): string {
119
136
  let primer;
120
137
  if (config === 'server') {
@@ -132,32 +149,31 @@ export function getSentryConfigContents(
132
149
  // https://docs.sentry.io/platforms/javascript/guides/nextjs/`;
133
150
  }
134
151
 
135
- let additionalOptions = '';
152
+ const integrationsOptions = getClientIntegrationsSnippet({
153
+ replay: config === 'client' && selectedFeaturesMap.replay,
154
+ });
155
+
156
+ let replayOptions = '';
136
157
  if (config === 'client') {
137
- additionalOptions = `
138
- replaysOnErrorSampleRate: 1.0,
158
+ if (selectedFeaturesMap.replay) {
159
+ replayOptions += `
139
160
 
161
+ // Define how likely Replay events are sampled.
140
162
  // This sets the sample rate to be 10%. You may want this to be 100% while
141
163
  // in development and sample at a lower rate in production
142
164
  replaysSessionSampleRate: 0.1,
143
165
 
144
- // You can remove this option if you're not planning to use the Sentry Session Replay feature:
145
- integrations: [
146
- Sentry.replayIntegration({
147
- // Additional Replay configuration goes in here, for example:
148
- maskAllText: true,
149
- blockAllMedia: true,
150
- }),
151
- ],`;
166
+ // Define how likely Replay events are sampled when an error occurs.
167
+ replaysOnErrorSampleRate: 1.0,`;
168
+ }
152
169
  }
153
170
 
154
- let spotlightOption = '';
155
- if (config === 'server') {
156
- spotlightOption = `
171
+ let performanceOptions = '';
172
+ if (selectedFeaturesMap.performance) {
173
+ performanceOptions += `
157
174
 
158
- // Uncomment the line below to enable Spotlight (https://spotlightjs.com)
159
- // spotlight: process.env.NODE_ENV === 'development',
160
- `;
175
+ // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
176
+ tracesSampleRate: 1,`;
161
177
  }
162
178
 
163
179
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
@@ -166,13 +182,10 @@ export function getSentryConfigContents(
166
182
  import * as Sentry from "@sentry/nextjs";
167
183
 
168
184
  Sentry.init({
169
- dsn: "${dsn}",
170
-
171
- // Adjust this value in production, or use tracesSampler for greater control
172
- tracesSampleRate: 1,
185
+ dsn: "${dsn}",${integrationsOptions}${performanceOptions}${replayOptions}
173
186
 
174
187
  // Setting this option to true will print useful information to the console while you're setting up Sentry.
175
- debug: false,${additionalOptions}${spotlightOption}
188
+ debug: false,
176
189
  });
177
190
  `;
178
191
  }
package/src/run.ts CHANGED
@@ -60,7 +60,7 @@ export async function run(argv: Args) {
60
60
  { value: 'android', label: 'Android' },
61
61
  { value: 'cordova', label: 'Cordova' },
62
62
  { value: 'electron', label: 'Electron' },
63
- { value: 'nextjs', label: 'NextJS' },
63
+ { value: 'nextjs', label: 'Next.js' },
64
64
  { value: 'remix', label: 'Remix' },
65
65
  { value: 'sveltekit', label: 'SvelteKit' },
66
66
  { value: 'sourcemaps', label: 'Configure Source Maps Upload' },
@@ -141,7 +141,7 @@ async function askForUsedBundlerTool(): Promise<SupportedTools> {
141
141
  {
142
142
  label: 'Next.js',
143
143
  value: 'nextjs',
144
- hint: 'Select this option if you want to set up source maps in a NextJS project.',
144
+ hint: 'Select this option if you want to set up source maps in a Next.js project.',
145
145
  },
146
146
  {
147
147
  label: 'Remix',
@@ -10,7 +10,7 @@ import { setInterval } from 'timers';
10
10
  import { URL } from 'url';
11
11
  import * as Sentry from '@sentry/node';
12
12
  import { hasPackageInstalled, PackageDotJson } from './package-json';
13
- import { SentryProjectData, WizardOptions } from './types';
13
+ import { Feature, SentryProjectData, WizardOptions } from './types';
14
14
  import { traceStep } from '../telemetry';
15
15
  import {
16
16
  detectPackageManger,
@@ -1277,3 +1277,36 @@ export async function askShouldCreateExamplePage(
1277
1277
  ),
1278
1278
  );
1279
1279
  }
1280
+
1281
+ export async function featureSelectionPrompt<F extends ReadonlyArray<Feature>>(
1282
+ features: F,
1283
+ ): Promise<{ [key in F[number]['id']]: boolean }> {
1284
+ return traceStep('feature-selection', async () => {
1285
+ const selectedFeatures: Record<string, boolean> = {};
1286
+
1287
+ for (const feature of features) {
1288
+ const selected = await abortIfCancelled(
1289
+ clack.select({
1290
+ message: feature.prompt,
1291
+ initialValue: true,
1292
+ options: [
1293
+ {
1294
+ value: true,
1295
+ label: 'Yes',
1296
+ hint: feature.enabledHint,
1297
+ },
1298
+ {
1299
+ value: false,
1300
+ label: 'No',
1301
+ hint: feature.disabledHint,
1302
+ },
1303
+ ],
1304
+ }),
1305
+ );
1306
+
1307
+ selectedFeatures[feature.id] = selected;
1308
+ }
1309
+
1310
+ return selectedFeatures as { [key in F[number]['id']]: boolean };
1311
+ });
1312
+ }