@sentry/wizard 5.3.0 → 5.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.4.0
4
+
5
+ - feat: Introduce run build command and prompts in sourcemaps wizard ([#1024](https://github.com/getsentry/sentry-wizard/pull/1024))
6
+ - feat: Add a default build path for create-react-app in soucemaps wizard ([#1025](https://github.com/getsentry/sentry-wizard/pull/1025))
7
+
3
8
  ## 5.3.0
4
9
 
5
10
  - fix(react-native): Avoid importing `isPlainObject` from `@sentry/utils` ([#1023](https://github.com/getsentry/sentry-wizard/pull/1023))
@@ -96,7 +96,7 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
96
96
  });
97
97
  const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
98
98
  const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
99
- const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
99
+ const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find build artifacts at", {
100
100
  optional: true,
101
101
  timeout: 5000,
102
102
  });
@@ -104,6 +104,12 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
104
104
  wizardInstance.sendStdin(utils_1.KEYS.ENTER);
105
105
  const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
106
106
  if (optionalArtifactsNotFoundPrompted) {
107
+ // The wizard now presents options when artifacts aren't found:
108
+ // - "Let the wizard run the build command"
109
+ // - "Enter a different path manually"
110
+ // - "Proceed anyway — I believe the path is correct"
111
+ // We want to select "Proceed anyway" (third option)
112
+ wizardInstance.sendStdin(utils_1.KEYS.DOWN);
107
113
  wizardInstance.sendStdin(utils_1.KEYS.DOWN);
108
114
  wizardInstance.sendStdin(utils_1.KEYS.ENTER);
109
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"angular-17.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-17.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-17', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn v1` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000, // installing the sdk can take a while\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for tracing\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for replay\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n timeout: 240_000, // installing Sentry CLI can take a while\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provide: APP_INITIALIZER,\n useFactory: () => () => {},\n deps: [Sentry.TraceService],\n multi: true`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
1
+ {"version":3,"file":"angular-17.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-17.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-17', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn v1` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000, // installing the sdk can take a while\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for tracing\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for replay\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n timeout: 240_000, // installing Sentry CLI can take a while\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find build artifacts at\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n // The wizard now presents options when artifacts aren't found:\n // - \"Let the wizard run the build command\"\n // - \"Enter a different path manually\"\n // - \"Proceed anyway — I believe the path is correct\"\n // We want to select \"Proceed anyway\" (third option)\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provide: APP_INITIALIZER,\n useFactory: () => () => {},\n deps: [Sentry.TraceService],\n multi: true`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
@@ -95,7 +95,7 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
95
95
  });
96
96
  const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
97
97
  const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
98
- const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
98
+ const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find build artifacts at", {
99
99
  optional: true,
100
100
  timeout: 5000,
101
101
  });
@@ -103,6 +103,12 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
103
103
  wizardInstance.sendStdin(utils_1.KEYS.ENTER);
104
104
  const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
105
105
  if (optionalArtifactsNotFoundPrompted) {
106
+ // The wizard now presents options when artifacts aren't found:
107
+ // - "Let the wizard run the build command"
108
+ // - "Enter a different path manually"
109
+ // - "Proceed anyway — I believe the path is correct"
110
+ // We want to select "Proceed anyway" (third option)
111
+ wizardInstance.sendStdin(utils_1.KEYS.DOWN);
106
112
  wizardInstance.sendStdin(utils_1.KEYS.DOWN);
107
113
  wizardInstance.sendStdin(utils_1.KEYS.ENTER);
108
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"angular-19.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-19.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-19', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // The first choice here is Angular\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provideAppInitializer(() => {\n inject(Sentry.TraceService);\n })`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
1
+ {"version":3,"file":"angular-19.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-19.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-19', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // The first choice here is Angular\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find build artifacts at\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n // The wizard now presents options when artifacts aren't found:\n // - \"Let the wizard run the build command\"\n // - \"Enter a different path manually\"\n // - \"Proceed anyway — I believe the path is correct\"\n // We want to select \"Proceed anyway\" (third option)\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provideAppInitializer(() => {\n inject(Sentry.TraceService);\n })`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
@@ -193,7 +193,7 @@ async function startToolSetupFlow(selectedTool, options, wizardOptions, preSelec
193
193
  await (0, sentry_cli_1.configureSentryCLI)(options, tsc_1.configureTscSourcemapGenerationFlow);
194
194
  break;
195
195
  case 'create-react-app':
196
- await (0, sentry_cli_1.configureSentryCLI)(options, create_react_app_1.configureCRASourcemapGenerationFlow);
196
+ await (0, sentry_cli_1.configureSentryCLI)({ ...options, defaultArtifactPath: `.${path_1.sep}build` }, create_react_app_1.configureCRASourcemapGenerationFlow);
197
197
  break;
198
198
  case 'wrangler':
199
199
  await (0, wrangler_1.configureWrangler)(options);
@@ -1 +1 @@
1
- {"version":3,"file":"sourcemaps-wizard.js","sourceRoot":"","sources":["../../../src/sourcemaps/sourcemaps-wizard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+EAA+E;AAC/E,6DAAmC;AACnC,qDAAuC;AACvC,kDAA0B;AAE1B,4CAAwD;AACxD,0CAUwB;AACxB,8DAA+C;AAE/C,sCAAiD;AACjD,+EAA0E;AAC1E,6CAA0E;AAC1E,+DAA+E;AAC/E,6CAAyD;AACzD,2CAAuD;AACvD,mDAA4E;AAC5E,qCAAkE;AAElE,uCAAmD;AACnD,6CAAyD;AAEzD,qDAAqD;AACrD,yDAAyF;AACzF,qDAAyE;AACzE,+BAA2B;AAC3B,+CAAqD;AAE9C,KAAK,UAAU,mBAAmB,CACvC,OAAsB,EACtB,eAAgC;IAEhC,OAAO,IAAA,yBAAa,EAClB;QACE,OAAO,EAAE,OAAO,CAAC,gBAAgB;QACjC,WAAW,EAAE,YAAY;QACzB,aAAa,EAAE,OAAO;KACvB,EACD,GAAG,EAAE,CAAC,gCAAgC,CAAC,OAAO,EAAE,eAAe,CAAC,CACjE,CAAC;AACJ,CAAC;AAZD,kDAYC;AAED,KAAK,UAAU,gCAAgC,CAC7C,OAAsB,EACtB,eAAgC;IAEhC,IAAI,CAAC,eAAe,EAAE;QACpB,IAAA,oBAAY,EAAC;YACX,UAAU,EAAE,gDAAgD;YAC5D,OAAO,EAAE;+BAEP,OAAO,CAAC,gBAAgB;gBACtB,CAAC,CAAC;;;kFAGsE;gBACxE,CAAC,CAAC,EACN,EAAE;YACF,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;KACJ;IAED,MAAM,kBAAkB,GAAG,MAAM,IAAA,qBAAS,EACxC,wBAAwB,EACxB,gEAAgD,CACjD,CAAC;IACF,IAAI,kBAAkB,EAAE;QACtB,MAAM,IAAA,qBAAS,EAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3E,OAAO;KACR;IAED,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,IAAA,yCAAiC,EAAC;YACtC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;KACJ;IAED,MAAM,IAAA,qBAAS,EAAC,mBAAmB,EAAE,gDAAkC,CAAC,CAAC;IAEzE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,GACzD,MAAM,IAAA,8BAAsB,EAAC,OAAO,CAAC,CAAC;IAExC,MAAM,mCAAmC,GAAG;QAC1C,GAAG,OAAO;QACV,kBAAkB,EAAE;YAClB,OAAO,EAAE,eAAe;YACxB,SAAS;YACT,UAAU;SACX;KACF,CAAC;IAEF,MAAM,YAAY,GAChB,eAAe,IAAI,CAAC,MAAM,IAAA,qBAAS,EAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAE7E,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAE7C,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,+DAA+D,CAChE,CAAC;QACF,MAAM,IAAA,aAAK,EAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC;QAC7C,OAAO;KACR;IAED,MAAM,IAAA,qBAAS,EAAC,YAAY,EAAE,GAAG,EAAE,CACjC,kBAAkB,CAChB,YAAY,EACZ;QACE,OAAO,EAAE,eAAe,CAAC,YAAY,CAAC,IAAI;QAC1C,WAAW,EAAE,eAAe,CAAC,IAAI;QACjC,UAAU;QACV,GAAG,EAAE,SAAS;QACd,SAAS;KACV,EACD,mCAAmC,EACnC,eAAe,CAChB,CACF,CAAC;IAEF,MAAM,IAAA,qBAAS,EAAC,UAAU,EAAE,GAAG,EAAE,CAC/B,OAAO,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CACrD,CAAC;IAEF,IAAI,CAAC,eAAe,EAAE;QACpB,gFAAgF;QAChF,6DAA6D;QAC7D,MAAM,IAAA,8BAAsB,EAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;KACtD;IAED,IAAI,CAAC,eAAe,EAAE;QACpB,MAAM,IAAA,qBAAS,EAAC,OAAO,EAAE,GAAG,EAAE,CAC5B,UAAU,CACR,SAAS,EACT,eAAe,CAAC,YAAY,CAAC,IAAI,EACjC,eAAe,CAAC,EAAE,CACnB,CACF,CAAC;KACH;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB;IAClC,MAAM,YAAY,GAAG,MAAM,IAAA,wBAAgB,EACzC,iBAAK,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,uDAAuD;QAChE,OAAO,EAAE;YACP;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,8CAA8C;aACrD;YACD;gBACE,KAAK,EAAE,kBAAkB;gBACzB,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,kEAAkE;aACzE;YACD;gBACE,KAAK,EAAE,qBAAqB;gBAC5B,KAAK,EAAE,UAAU;gBACjB,IAAI,EAAE,4EAA4E;aACnF;YACD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,kFAAkF;aACzF;YACD;gBACE,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,4EAA4E;aACnF;YACD;gBACE,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,kFAAkF;aACzF;YACD;gBACE,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,QAAQ;gBACf,IAAI,EAAE,gFAAgF;aACvF;YACD;gBACE,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,oDAAoD;aAC3D;YACD;gBACE,KAAK,EAAE,oBAAoB;gBAC3B,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,iEAAiE;aACxE;YACD;gBACE,KAAK,EAAE,6CAA6C;gBACpD,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,2BAA2B;aAClC;SACF;QACD,YAAY,EAAE,MAAM,IAAA,4BAAc,GAAE;KACrC,CAAC,CACH,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,YAA4B,EAC5B,OAAgD,EAChD,aAA4B,EAC5B,eAAgC;IAEhC,QAAQ,YAAY,EAAE;QACpB,KAAK,SAAS;YACZ,MAAM,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;YACtC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;YACtC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;YACrC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAA,+BAAkB,EAAC,OAAO,EAAE,yCAAmC,CAAC,CAAC;YACvE,MAAM;QACR,KAAK,kBAAkB;YACrB,MAAM,IAAA,+BAAkB,EAAC,OAAO,EAAE,sDAAmC,CAAC,CAAC;YACvE,MAAM;QACR,KAAK,UAAU;YACb,MAAM,IAAA,4BAAiB,EAAC,OAAO,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,IAAA,+BAAkB,EACtB,EAAE,GAAG,OAAO,EAAE,mBAAmB,EAAE,IAAI,UAAG,MAAM,EAAE,EAClD,iDAAuC,EACvC,eAAe,KAAK,SAAS,CAC9B,CAAC;YACF,MAAM;QACR;YACE,MAAM,IAAA,+BAAkB,EAAC,OAAO,CAAC,CAAC;YAClC,MAAM;KACT;AACH,CAAC;AACM,KAAK,UAAU,OAAO,CAC3B,YAA4B,EAC5B,SAAiB,EACjB,UAAuC;IAEvC,IAAI,UAAU,KAAK,QAAQ,EAAE;QAC3B,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,qEAAqE,CACtE,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;KACjC;SAAM;QACL,MAAM,IAAA,qBAAS,EAAC,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;KAC7E;AACH,CAAC;AAbD,0BAaC;AAEM,KAAK,UAAU,WAAW,CAC/B,YAA4B,EAC5B,SAAiB;IAEjB,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAgB,EACtC,iBAAK,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,kEAAkE;QAC3E,OAAO,EAAE;YACP;gBACE,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,oFAAoF;gBAC1F,KAAK,EAAE,IAAI;aACZ;YACD;gBACE,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,4CAA4C;gBAClD,KAAK,EAAE,KAAK;aACb;SACF;QACD,YAAY,EAAE,IAAI;KACnB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAErC,MAAM,kBAAkB,GAAG;QACzB,YAAY;QACZ,KAAK;QACL,SAAS;QACT,kBAAkB;KACnB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEzB,MAAM,aAAa,GAAG,kBAAkB;QACtC,CAAC,CAAC,0BAAkB;QACpB,CAAC,CAAC,2BAAmB,CAAC;IAExB,IAAI,CAAC,SAAS,EAAE;QACd,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,8DAA8D,eAAK,CAAC,IAAI,CACtE,aAAa,CACd,uDAAuD,CACzD,CAAC;QACF,OAAO;KACR;IAED,IAAI,kBAAkB,EAAE;QACtB,MAAM,IAAA,qBAAS,EAAC,qBAAqB,EAAE,+BAAkB,CAAC,CAAC;KAC5D;IAED,MAAM,IAAA,qBAAS,EAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9E,CAAC;AAlDD,kCAkDC;AAED,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACjD,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,kFAAkF,CACnF,CAAC;IAEF,8FAA8F;IAC9F,sCAAsC;IACtC,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,WAAW,CAAC;oBACF,SAAS;CAC5B,CAAC,CACC,CAAC;IAEF,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,eAAK,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAClE,CAAC;IAEF,MAAM,eAAe,GAAG,MAAM,IAAA,wBAAgB,EAC5C,iBAAK,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,sCAAsC;QAC/C,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE;YACxC;gBACE,KAAK,EAAE,qBAAqB;gBAC5B,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,eAAK,CAAC,MAAM,CAChB,4DAA4D,CAC7D;aACF;SACF;QACD,YAAY,EAAE,IAAI;KACnB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC;IAEtD,IAAI,CAAC,eAAe,EAAE;QACpB,iBAAK,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;KACpC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,GAAW,EACX,OAAe,EACf,SAAiB;IAEjB,MAAM,cAAc,GAAG,MAAM,IAAA,yBAAiB,EAAC,qBAAG,CAAC,CAAC;IAEpD,MAAM,cAAc,GAAG,IAAA,uBAAiB,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAEtE,MAAM,KAAK,GAAG,IAAA,yCAAkB,GAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhD,iBAAK,CAAC,KAAK,CAAC,GAAG,eAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC;;KAE5D,eAAK,CAAC,IAAI,CAAC;;kCAEkB,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;QACvD,eAAK,CAAC,IAAI,CACV,GAAG,KAAK,qBAAqB,eAAK,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,CACxE;QACC,eAAK,CAAC,IAAI,CACV,GAAG,KAAK,yDAAyD,CAClE;;QAEC,eAAK,CAAC,IAAI,CAAC,GAAG,KAAK,qCAAqC,CAAC;QACzD,eAAK,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,cAAc,EAAE,CAAC;;QAExC,eAAK,CAAC,IAAI,CACV,GAAG,KAAK,yDAAyD,CAClE;IACH,CAAC;KACA,eAAK,CAAC,GAAG,CACT;;;;yDAIoD,CACrD;CACH,CAAC,CAAC;AACH,CAAC","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport chalk from 'chalk';\n\nimport { traceStep, withTelemetry } from '../telemetry';\nimport {\n abort,\n abortIfCancelled,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n getPackageManager,\n printWelcome,\n runPrettierIfInstalled,\n SENTRY_CLI_RC_FILE,\n SENTRY_DOT_ENV_FILE,\n} from '../utils/clack';\nimport { NPM } from '../utils/package-manager';\nimport type { WizardOptions } from '../utils/types';\nimport { getIssueStreamUrl } from '../utils/url';\nimport { isUnicodeSupported } from '../utils/vendor/is-unicorn-supported';\nimport { configureAngularSourcemapGenerationFlow } from './tools/angular';\nimport { configureCRASourcemapGenerationFlow } from './tools/create-react-app';\nimport { configureEsbuildPlugin } from './tools/esbuild';\nimport { configureRollupPlugin } from './tools/rollup';\nimport { configureSentryCLI, setupNpmScriptInCI } from './tools/sentry-cli';\nimport { configureTscSourcemapGenerationFlow } from './tools/tsc';\nimport type { SourceMapUploadToolConfigurationOptions } from './tools/types';\nimport { configureVitePlugin } from './tools/vite';\nimport { configureWebPackPlugin } from './tools/webpack';\nimport type { SupportedTools } from './utils/detect-tool';\nimport { detectUsedTool } from './utils/detect-tool';\nimport { checkIfMoreSuitableWizardExistsAndAskForRedirect } from './utils/other-wizards';\nimport { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version';\nimport { sep } from 'path';\nimport { configureWrangler } from './tools/wrangler';\n\nexport async function runSourcemapsWizard(\n options: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'sourcemaps',\n wizardOptions: options,\n },\n () => runSourcemapsWizardWithTelemetry(options, preSelectedTool),\n );\n}\n\nasync function runSourcemapsWizardWithTelemetry(\n options: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n if (!preSelectedTool) {\n printWelcome({\n wizardName: 'Sentry Source Maps Upload Configuration Wizard',\n message: `This wizard will help you upload source maps to Sentry as part of your build.\nThank you for using Sentry :)${\n options.telemetryEnabled\n ? `\n\n(This setup wizard sends telemetry data and crash reports to Sentry.\nYou can turn this off by running the wizard with the '--disable-telemetry' flag.)`\n : ''\n }`,\n promoCode: options.promoCode,\n });\n }\n\n const moreSuitableWizard = await traceStep(\n 'check-framework-wizard',\n checkIfMoreSuitableWizardExistsAndAskForRedirect,\n );\n if (moreSuitableWizard) {\n await traceStep('run-framework-wizard', () => moreSuitableWizard(options));\n return;\n }\n\n if (!preSelectedTool) {\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n }\n\n await traceStep('check-sdk-version', ensureMinimumSdkVersionIsInstalled);\n\n const { selfHosted, selectedProject, sentryUrl, authToken } =\n await getOrAskForProjectData(options);\n\n const wizardOptionsWithPreSelectedProject = {\n ...options,\n preSelectedProject: {\n project: selectedProject,\n authToken,\n selfHosted,\n },\n };\n\n const selectedTool =\n preSelectedTool || (await traceStep('select-tool', askForUsedBundlerTool));\n\n Sentry.setTag('selected-tool', selectedTool);\n\n if (selectedTool === 'no-tool') {\n clack.log.info(\n \"No Problem! But in this case, there's nothing to configure :)\",\n );\n await abort('Exiting, have a great day!', 0);\n return;\n }\n\n await traceStep('tool-setup', () =>\n startToolSetupFlow(\n selectedTool,\n {\n orgSlug: selectedProject.organization.slug,\n projectSlug: selectedProject.slug,\n selfHosted,\n url: sentryUrl,\n authToken,\n },\n wizardOptionsWithPreSelectedProject,\n preSelectedTool,\n ),\n );\n\n await traceStep('ci-setup', () =>\n setupCI(selectedTool, authToken, options.comingFrom),\n );\n\n if (!preSelectedTool) {\n // running prettier is only necessary if the source maps wizard is the main flow\n // skip it, if it's called from another wizard (e.g. angular)\n await runPrettierIfInstalled({ cwd: process.cwd() });\n }\n\n if (!preSelectedTool) {\n await traceStep('outro', () =>\n printOutro(\n sentryUrl,\n selectedProject.organization.slug,\n selectedProject.id,\n ),\n );\n }\n}\n\nasync function askForUsedBundlerTool(): Promise<SupportedTools> {\n const selectedTool = await abortIfCancelled(\n clack.select({\n message: 'Which framework, bundler or build tool are you using?',\n options: [\n {\n label: 'Angular',\n value: 'angular',\n hint: 'Select this option if you are using Angular.',\n },\n {\n label: 'Create React App',\n value: 'create-react-app',\n hint: 'Select this option if you set up your app with Create React App.',\n },\n {\n label: 'Cloudflare Wrangler',\n value: 'wrangler',\n hint: \"You're using `wrangler deploy` to build and deploy your Cloudflare Worker.\",\n },\n {\n label: 'Webpack',\n value: 'webpack',\n hint: 'Select this if you are using Webpack and you have access to your Webpack config.',\n },\n {\n label: 'Vite',\n value: 'vite',\n hint: 'Select this if you are using Vite and you have access to your Vite config.',\n },\n {\n label: 'esbuild',\n value: 'esbuild',\n hint: 'Select this if you are using esbuild and you have access to your esbuild config.',\n },\n {\n label: 'Rollup',\n value: 'rollup',\n hint: 'Select this if you are using Rollup and you have access to your Rollup config.',\n },\n {\n label: 'tsc',\n value: 'tsc',\n hint: 'Configure source maps when using tsc as build tool',\n },\n {\n label: 'I use another tool',\n value: 'sentry-cli',\n hint: 'This will configure source maps upload for you using sentry-cli',\n },\n {\n label: \"I don't minify, transpile or bundle my code\",\n value: 'no-tool',\n hint: 'This will exit the wizard',\n },\n ],\n initialValue: await detectUsedTool(),\n }),\n );\n\n return selectedTool;\n}\n\nasync function startToolSetupFlow(\n selectedTool: SupportedTools,\n options: SourceMapUploadToolConfigurationOptions,\n wizardOptions: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n switch (selectedTool) {\n case 'webpack':\n await configureWebPackPlugin(options);\n break;\n case 'vite':\n await configureVitePlugin(options);\n break;\n case 'esbuild':\n await configureEsbuildPlugin(options);\n break;\n case 'rollup':\n await configureRollupPlugin(options);\n break;\n case 'tsc':\n await configureSentryCLI(options, configureTscSourcemapGenerationFlow);\n break;\n case 'create-react-app':\n await configureSentryCLI(options, configureCRASourcemapGenerationFlow);\n break;\n case 'wrangler':\n await configureWrangler(options);\n break;\n case 'angular':\n await configureSentryCLI(\n { ...options, defaultArtifactPath: `.${sep}dist` },\n configureAngularSourcemapGenerationFlow,\n preSelectedTool === 'angular',\n );\n break;\n default:\n await configureSentryCLI(options);\n break;\n }\n}\nexport async function setupCI(\n selectedTool: SupportedTools,\n authToken: string,\n comingFrom: WizardOptions['comingFrom'],\n) {\n if (comingFrom === 'vercel') {\n clack.log.info(\n 'Sentry Vercel integration is already configured. Skipping CI setup.',\n );\n Sentry.setTag('using-ci', true);\n } else {\n await traceStep('configure-ci', () => configureCI(selectedTool, authToken));\n }\n}\n\nexport async function configureCI(\n selectedTool: SupportedTools,\n authToken: string,\n): Promise<void> {\n const isUsingCI = await abortIfCancelled(\n clack.select({\n message: `Are you using a CI/CD tool to build and deploy your application?`,\n options: [\n {\n label: 'Yes',\n hint: 'I use a tool like GitHub Actions, GitLab, CircleCI, TravisCI, Jenkins, Vercel, ...',\n value: true,\n },\n {\n label: 'No',\n hint: 'I build and deploy my application manually',\n value: false,\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('using-ci', isUsingCI);\n\n const isCliBasedFlowTool = [\n 'sentry-cli',\n 'tsc',\n 'angular',\n 'create-react-app',\n ].includes(selectedTool);\n\n const authTokenFile = isCliBasedFlowTool\n ? SENTRY_CLI_RC_FILE\n : SENTRY_DOT_ENV_FILE;\n\n if (!isUsingCI) {\n clack.log.info(\n `No Problem! Just make sure that the Sentry auth token from ${chalk.cyan(\n authTokenFile,\n )} is available whenever you build and deploy your app.`,\n );\n return;\n }\n\n if (isCliBasedFlowTool) {\n await traceStep('ci-npm-script-setup', setupNpmScriptInCI);\n }\n\n await traceStep('ci-auth-token-setup', () => setupAuthTokenInCI(authToken));\n}\n\nasync function setupAuthTokenInCI(authToken: string) {\n clack.log.step(\n 'Add the Sentry authentication token as an environment variable to your CI setup:',\n );\n\n // Intentially logging directly to console here so that the code can be copied/pasted directly\n // eslint-disable-next-line no-console\n console.log(\n chalk.greenBright(`\nSENTRY_AUTH_TOKEN=${authToken}\n`),\n );\n\n clack.log.warn(\n chalk.yellow('DO NOT commit this auth token to your repository!'),\n );\n\n const addedEnvVarToCI = await abortIfCancelled(\n clack.select({\n message: 'Did you configure CI as shown above?',\n options: [\n { label: 'Yes, continue!', value: true },\n {\n label: \"I'll do it later...\",\n value: false,\n hint: chalk.yellow(\n 'You need to set the auth token to upload source maps in CI',\n ),\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('added-env-var-to-ci', addedEnvVarToCI);\n\n if (!addedEnvVarToCI) {\n clack.log.info(\"Don't forget! :)\");\n }\n}\n\nasync function printOutro(\n url: string,\n orgSlug: string,\n projectId: string,\n): Promise<void> {\n const packageManager = await getPackageManager(NPM);\n\n const issueStreamUrl = getIssueStreamUrl({ url, orgSlug, projectId });\n\n const arrow = isUnicodeSupported() ? '→' : '->';\n\n clack.outro(`${chalk.green(\"That's it - everything is set up!\")}\n\n ${chalk.cyan(`Test and validate your setup locally with the following Steps:\n\n 1. Build your application in ${chalk.bold('production mode')}.\n ${chalk.gray(\n `${arrow} For example, run ${chalk.bold(packageManager.buildCommand)}.`,\n )}\n ${chalk.gray(\n `${arrow} You should see source map upload logs in your console.`,\n )}\n 2. Run your application and throw a test error.\n ${chalk.gray(`${arrow} The error should appear in Sentry:`)}\n ${chalk.gray(`${arrow} ${issueStreamUrl}`)}\n 3. Open the error in Sentry and verify that it's source-mapped.\n ${chalk.gray(\n `${arrow} The stack trace should show your original source code.`,\n )}\n `)}\n ${chalk.dim(\n `If you encounter any issues, please refer to the Troubleshooting Guide:\n https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js\n\n If the guide doesn't help or you encounter a bug, please let us know:\n https://github.com/getsentry/sentry-javascript/issues`,\n )}\n`);\n}\n"]}
1
+ {"version":3,"file":"sourcemaps-wizard.js","sourceRoot":"","sources":["../../../src/sourcemaps/sourcemaps-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport chalk from 'chalk';\n\nimport { traceStep, withTelemetry } from '../telemetry';\nimport {\n abort,\n abortIfCancelled,\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n getPackageManager,\n printWelcome,\n runPrettierIfInstalled,\n SENTRY_CLI_RC_FILE,\n SENTRY_DOT_ENV_FILE,\n} from '../utils/clack';\nimport { NPM } from '../utils/package-manager';\nimport type { WizardOptions } from '../utils/types';\nimport { getIssueStreamUrl } from '../utils/url';\nimport { isUnicodeSupported } from '../utils/vendor/is-unicorn-supported';\nimport { configureAngularSourcemapGenerationFlow } from './tools/angular';\nimport { configureCRASourcemapGenerationFlow } from './tools/create-react-app';\nimport { configureEsbuildPlugin } from './tools/esbuild';\nimport { configureRollupPlugin } from './tools/rollup';\nimport { configureSentryCLI, setupNpmScriptInCI } from './tools/sentry-cli';\nimport { configureTscSourcemapGenerationFlow } from './tools/tsc';\nimport type { SourceMapUploadToolConfigurationOptions } from './tools/types';\nimport { configureVitePlugin } from './tools/vite';\nimport { configureWebPackPlugin } from './tools/webpack';\nimport type { SupportedTools } from './utils/detect-tool';\nimport { detectUsedTool } from './utils/detect-tool';\nimport { checkIfMoreSuitableWizardExistsAndAskForRedirect } from './utils/other-wizards';\nimport { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version';\nimport { sep } from 'path';\nimport { configureWrangler } from './tools/wrangler';\n\nexport async function runSourcemapsWizard(\n options: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'sourcemaps',\n wizardOptions: options,\n },\n () => runSourcemapsWizardWithTelemetry(options, preSelectedTool),\n );\n}\n\nasync function runSourcemapsWizardWithTelemetry(\n options: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n if (!preSelectedTool) {\n printWelcome({\n wizardName: 'Sentry Source Maps Upload Configuration Wizard',\n message: `This wizard will help you upload source maps to Sentry as part of your build.\nThank you for using Sentry :)${\n options.telemetryEnabled\n ? `\n\n(This setup wizard sends telemetry data and crash reports to Sentry.\nYou can turn this off by running the wizard with the '--disable-telemetry' flag.)`\n : ''\n }`,\n promoCode: options.promoCode,\n });\n }\n\n const moreSuitableWizard = await traceStep(\n 'check-framework-wizard',\n checkIfMoreSuitableWizardExistsAndAskForRedirect,\n );\n if (moreSuitableWizard) {\n await traceStep('run-framework-wizard', () => moreSuitableWizard(options));\n return;\n }\n\n if (!preSelectedTool) {\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n }\n\n await traceStep('check-sdk-version', ensureMinimumSdkVersionIsInstalled);\n\n const { selfHosted, selectedProject, sentryUrl, authToken } =\n await getOrAskForProjectData(options);\n\n const wizardOptionsWithPreSelectedProject = {\n ...options,\n preSelectedProject: {\n project: selectedProject,\n authToken,\n selfHosted,\n },\n };\n\n const selectedTool =\n preSelectedTool || (await traceStep('select-tool', askForUsedBundlerTool));\n\n Sentry.setTag('selected-tool', selectedTool);\n\n if (selectedTool === 'no-tool') {\n clack.log.info(\n \"No Problem! But in this case, there's nothing to configure :)\",\n );\n await abort('Exiting, have a great day!', 0);\n return;\n }\n\n await traceStep('tool-setup', () =>\n startToolSetupFlow(\n selectedTool,\n {\n orgSlug: selectedProject.organization.slug,\n projectSlug: selectedProject.slug,\n selfHosted,\n url: sentryUrl,\n authToken,\n },\n wizardOptionsWithPreSelectedProject,\n preSelectedTool,\n ),\n );\n\n await traceStep('ci-setup', () =>\n setupCI(selectedTool, authToken, options.comingFrom),\n );\n\n if (!preSelectedTool) {\n // running prettier is only necessary if the source maps wizard is the main flow\n // skip it, if it's called from another wizard (e.g. angular)\n await runPrettierIfInstalled({ cwd: process.cwd() });\n }\n\n if (!preSelectedTool) {\n await traceStep('outro', () =>\n printOutro(\n sentryUrl,\n selectedProject.organization.slug,\n selectedProject.id,\n ),\n );\n }\n}\n\nasync function askForUsedBundlerTool(): Promise<SupportedTools> {\n const selectedTool = await abortIfCancelled(\n clack.select({\n message: 'Which framework, bundler or build tool are you using?',\n options: [\n {\n label: 'Angular',\n value: 'angular',\n hint: 'Select this option if you are using Angular.',\n },\n {\n label: 'Create React App',\n value: 'create-react-app',\n hint: 'Select this option if you set up your app with Create React App.',\n },\n {\n label: 'Cloudflare Wrangler',\n value: 'wrangler',\n hint: \"You're using `wrangler deploy` to build and deploy your Cloudflare Worker.\",\n },\n {\n label: 'Webpack',\n value: 'webpack',\n hint: 'Select this if you are using Webpack and you have access to your Webpack config.',\n },\n {\n label: 'Vite',\n value: 'vite',\n hint: 'Select this if you are using Vite and you have access to your Vite config.',\n },\n {\n label: 'esbuild',\n value: 'esbuild',\n hint: 'Select this if you are using esbuild and you have access to your esbuild config.',\n },\n {\n label: 'Rollup',\n value: 'rollup',\n hint: 'Select this if you are using Rollup and you have access to your Rollup config.',\n },\n {\n label: 'tsc',\n value: 'tsc',\n hint: 'Configure source maps when using tsc as build tool',\n },\n {\n label: 'I use another tool',\n value: 'sentry-cli',\n hint: 'This will configure source maps upload for you using sentry-cli',\n },\n {\n label: \"I don't minify, transpile or bundle my code\",\n value: 'no-tool',\n hint: 'This will exit the wizard',\n },\n ],\n initialValue: await detectUsedTool(),\n }),\n );\n\n return selectedTool;\n}\n\nasync function startToolSetupFlow(\n selectedTool: SupportedTools,\n options: SourceMapUploadToolConfigurationOptions,\n wizardOptions: WizardOptions,\n preSelectedTool?: SupportedTools,\n): Promise<void> {\n switch (selectedTool) {\n case 'webpack':\n await configureWebPackPlugin(options);\n break;\n case 'vite':\n await configureVitePlugin(options);\n break;\n case 'esbuild':\n await configureEsbuildPlugin(options);\n break;\n case 'rollup':\n await configureRollupPlugin(options);\n break;\n case 'tsc':\n await configureSentryCLI(options, configureTscSourcemapGenerationFlow);\n break;\n case 'create-react-app':\n await configureSentryCLI(\n { ...options, defaultArtifactPath: `.${sep}build` },\n configureCRASourcemapGenerationFlow,\n );\n break;\n case 'wrangler':\n await configureWrangler(options);\n break;\n case 'angular':\n await configureSentryCLI(\n { ...options, defaultArtifactPath: `.${sep}dist` },\n configureAngularSourcemapGenerationFlow,\n preSelectedTool === 'angular',\n );\n break;\n default:\n await configureSentryCLI(options);\n break;\n }\n}\nexport async function setupCI(\n selectedTool: SupportedTools,\n authToken: string,\n comingFrom: WizardOptions['comingFrom'],\n) {\n if (comingFrom === 'vercel') {\n clack.log.info(\n 'Sentry Vercel integration is already configured. Skipping CI setup.',\n );\n Sentry.setTag('using-ci', true);\n } else {\n await traceStep('configure-ci', () => configureCI(selectedTool, authToken));\n }\n}\n\nexport async function configureCI(\n selectedTool: SupportedTools,\n authToken: string,\n): Promise<void> {\n const isUsingCI = await abortIfCancelled(\n clack.select({\n message: `Are you using a CI/CD tool to build and deploy your application?`,\n options: [\n {\n label: 'Yes',\n hint: 'I use a tool like GitHub Actions, GitLab, CircleCI, TravisCI, Jenkins, Vercel, ...',\n value: true,\n },\n {\n label: 'No',\n hint: 'I build and deploy my application manually',\n value: false,\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('using-ci', isUsingCI);\n\n const isCliBasedFlowTool = [\n 'sentry-cli',\n 'tsc',\n 'angular',\n 'create-react-app',\n ].includes(selectedTool);\n\n const authTokenFile = isCliBasedFlowTool\n ? SENTRY_CLI_RC_FILE\n : SENTRY_DOT_ENV_FILE;\n\n if (!isUsingCI) {\n clack.log.info(\n `No Problem! Just make sure that the Sentry auth token from ${chalk.cyan(\n authTokenFile,\n )} is available whenever you build and deploy your app.`,\n );\n return;\n }\n\n if (isCliBasedFlowTool) {\n await traceStep('ci-npm-script-setup', setupNpmScriptInCI);\n }\n\n await traceStep('ci-auth-token-setup', () => setupAuthTokenInCI(authToken));\n}\n\nasync function setupAuthTokenInCI(authToken: string) {\n clack.log.step(\n 'Add the Sentry authentication token as an environment variable to your CI setup:',\n );\n\n // Intentially logging directly to console here so that the code can be copied/pasted directly\n // eslint-disable-next-line no-console\n console.log(\n chalk.greenBright(`\nSENTRY_AUTH_TOKEN=${authToken}\n`),\n );\n\n clack.log.warn(\n chalk.yellow('DO NOT commit this auth token to your repository!'),\n );\n\n const addedEnvVarToCI = await abortIfCancelled(\n clack.select({\n message: 'Did you configure CI as shown above?',\n options: [\n { label: 'Yes, continue!', value: true },\n {\n label: \"I'll do it later...\",\n value: false,\n hint: chalk.yellow(\n 'You need to set the auth token to upload source maps in CI',\n ),\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('added-env-var-to-ci', addedEnvVarToCI);\n\n if (!addedEnvVarToCI) {\n clack.log.info(\"Don't forget! :)\");\n }\n}\n\nasync function printOutro(\n url: string,\n orgSlug: string,\n projectId: string,\n): Promise<void> {\n const packageManager = await getPackageManager(NPM);\n\n const issueStreamUrl = getIssueStreamUrl({ url, orgSlug, projectId });\n\n const arrow = isUnicodeSupported() ? '→' : '->';\n\n clack.outro(`${chalk.green(\"That's it - everything is set up!\")}\n\n ${chalk.cyan(`Test and validate your setup locally with the following Steps:\n\n 1. Build your application in ${chalk.bold('production mode')}.\n ${chalk.gray(\n `${arrow} For example, run ${chalk.bold(packageManager.buildCommand)}.`,\n )}\n ${chalk.gray(\n `${arrow} You should see source map upload logs in your console.`,\n )}\n 2. Run your application and throw a test error.\n ${chalk.gray(`${arrow} The error should appear in Sentry:`)}\n ${chalk.gray(`${arrow} ${issueStreamUrl}`)}\n 3. Open the error in Sentry and verify that it's source-mapped.\n ${chalk.gray(\n `${arrow} The stack trace should show your original source code.`,\n )}\n `)}\n ${chalk.dim(\n `If you encounter any issues, please refer to the Troubleshooting Guide:\n https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js\n\n If the guide doesn't help or you encounter a bug, please let us know:\n https://github.com/getsentry/sentry-javascript/issues`,\n )}\n`);\n}\n"]}
@@ -50,8 +50,12 @@ async function configureSentryCLI(options, configureSourcemapGenerationFlow = de
50
50
  do {
51
51
  const rawArtifactPath = await (0, clack_1.abortIfCancelled)(clack.text({
52
52
  message: 'Where are your build artifacts located?',
53
- placeholder: options.defaultArtifactPath ?? `.${path.sep}out`,
54
- initialValue: options.defaultArtifactPath ?? `.${path.sep}out`,
53
+ placeholder: relativeArtifactPath ??
54
+ options.defaultArtifactPath ??
55
+ `.${path.sep}out`,
56
+ initialValue: relativeArtifactPath ??
57
+ options.defaultArtifactPath ??
58
+ `.${path.sep}out`,
55
59
  validate(value) {
56
60
  if (!value) {
57
61
  return 'Please enter a path.';
@@ -64,23 +68,17 @@ async function configureSentryCLI(options, configureSourcemapGenerationFlow = de
64
68
  else {
65
69
  relativeArtifactPath = rawArtifactPath;
66
70
  }
67
- try {
68
- await fs.promises.access(path.join(process.cwd(), relativeArtifactPath));
71
+ if ((0, clack_1.artifactsExist)(relativeArtifactPath)) {
69
72
  validPath = true;
73
+ continue;
70
74
  }
71
- catch {
72
- validPath = await (0, clack_1.abortIfCancelled)(clack.select({
73
- message: `We couldn't find artifacts at ${relativeArtifactPath}. Are you sure that this is the location that contains your build artifacts?`,
74
- options: [
75
- {
76
- label: 'No, let me verify.',
77
- value: false,
78
- },
79
- { label: 'Yes, I am sure!', value: true },
80
- ],
81
- initialValue: false,
82
- }));
83
- }
75
+ const runBuildOrEnterPathOrProceed = await (0, clack_1.askToRunBuildOrEnterPathOrProceed)({
76
+ relativeArtifactPath,
77
+ });
78
+ validPath = runBuildOrEnterPathOrProceed?.validPath ?? false;
79
+ relativeArtifactPath =
80
+ runBuildOrEnterPathOrProceed?.relativeArtifactPath ??
81
+ relativeArtifactPath;
84
82
  } while (!validPath);
85
83
  const relativePosixArtifactPath = relativeArtifactPath
86
84
  .split(path.sep)
@@ -1 +1 @@
1
- {"version":3,"file":"sentry-cli.js","sourceRoot":"","sources":["../../../../src/sourcemaps/tools/sentry-cli.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as Sentry from '@sentry/node';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport {\n abortIfCancelled,\n addSentryCliConfig,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n} from '../../utils/clack';\n\nimport { SourceMapUploadToolConfigurationOptions } from './types';\nimport { hasPackageInstalled } from '../../utils/package-json';\nimport { traceStep } from '../../telemetry';\nimport { NPM } from '../../utils/package-manager';\n\nconst SENTRY_NPM_SCRIPT_NAME = 'sentry:sourcemaps';\n\nlet addedToBuildCommand = false;\n\ntype configureSentryCLIOptions = SourceMapUploadToolConfigurationOptions & {\n defaultArtifactPath?: string;\n};\n\nexport async function configureSentryCLI(\n options: configureSentryCLIOptions,\n configureSourcemapGenerationFlow: () => Promise<void> = defaultConfigureSourcemapGenerationFlow,\n skipValidation = false,\n): Promise<void> {\n const packageDotJson = await getPackageDotJson();\n\n await installPackage({\n packageName: '@sentry/cli',\n alreadyInstalled: hasPackageInstalled('@sentry/cli', packageDotJson),\n });\n\n let validPath = false;\n let relativeArtifactPath;\n do {\n const rawArtifactPath = await abortIfCancelled(\n clack.text({\n message: 'Where are your build artifacts located?',\n placeholder: options.defaultArtifactPath ?? `.${path.sep}out`,\n initialValue: options.defaultArtifactPath ?? `.${path.sep}out`,\n validate(value) {\n if (!value) {\n return 'Please enter a path.';\n }\n },\n }),\n );\n\n if (path.isAbsolute(rawArtifactPath)) {\n relativeArtifactPath = path.relative(process.cwd(), rawArtifactPath);\n } else {\n relativeArtifactPath = rawArtifactPath;\n }\n\n try {\n await fs.promises.access(path.join(process.cwd(), relativeArtifactPath));\n validPath = true;\n } catch {\n validPath = await abortIfCancelled(\n clack.select({\n message: `We couldn't find artifacts at ${relativeArtifactPath}. Are you sure that this is the location that contains your build artifacts?`,\n options: [\n {\n label: 'No, let me verify.',\n value: false,\n },\n { label: 'Yes, I am sure!', value: true },\n ],\n initialValue: false,\n }),\n );\n }\n } while (!validPath);\n\n const relativePosixArtifactPath = relativeArtifactPath\n .split(path.sep)\n .join(path.posix.sep);\n\n if (!skipValidation) {\n await configureSourcemapGenerationFlow();\n }\n\n await createAndAddNpmScript(options, relativePosixArtifactPath);\n\n if (await askShouldAddToBuildCommand()) {\n await traceStep('sentry-cli-add-to-build-cmd', () =>\n addSentryCommandToBuildCommand(),\n );\n } else {\n clack.log.info(\n `No problem, just make sure to run this script ${chalk.bold(\n 'after',\n )} building your application but ${chalk.bold('before')} deploying!`,\n );\n }\n\n await addSentryCliConfig({ authToken: options.authToken });\n}\n\nexport async function setupNpmScriptInCI(): Promise<void> {\n if (addedToBuildCommand) {\n // No need to tell users to add it manually to their CI\n // if the script is already added to the build command\n return;\n }\n\n const addedToCI = await abortIfCancelled(\n clack.select({\n message: `Add a step to your CI pipeline that runs the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script ${chalk.bold('right after')} building your application.`,\n options: [\n { label: 'I did, continue!', value: true },\n {\n label: \"I'll do it later...\",\n value: false,\n hint: chalk.yellow(\n `You need to run ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} after each build for source maps to work properly.`,\n ),\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('added-ci-script', addedToCI);\n\n if (!addedToCI) {\n clack.log.info(\"Don't forget! :)\");\n }\n}\n\nasync function createAndAddNpmScript(\n options: SourceMapUploadToolConfigurationOptions,\n relativePosixArtifactPath: string,\n): Promise<void> {\n const sentryCliNpmScript = `sentry-cli sourcemaps inject --org ${\n options.orgSlug\n } --project ${\n options.projectSlug\n } ${relativePosixArtifactPath} && sentry-cli${\n options.selfHosted ? ` --url ${options.url}` : ''\n } sourcemaps upload --org ${options.orgSlug} --project ${\n options.projectSlug\n } ${relativePosixArtifactPath}`;\n\n const packageDotJson = await getPackageDotJson();\n\n packageDotJson.scripts = packageDotJson.scripts || {};\n packageDotJson.scripts[SENTRY_NPM_SCRIPT_NAME] = sentryCliNpmScript;\n\n await fs.promises.writeFile(\n path.join(process.cwd(), 'package.json'),\n JSON.stringify(packageDotJson, null, 2),\n );\n\n clack.log.info(\n `Added a ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(\n 'package.json',\n )}.`,\n );\n}\n\nasync function askShouldAddToBuildCommand(): Promise<boolean> {\n const shouldAddToBuildCommand = await abortIfCancelled(\n clack.select({\n message: `Do you want to automatically run the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script after each production build?`,\n options: [\n {\n label: 'Yes',\n value: true,\n hint: 'This will modify your prod build command',\n },\n { label: 'No', value: false },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('modify-build-command', shouldAddToBuildCommand);\n\n return shouldAddToBuildCommand;\n}\n\n/**\n * Add the sentry:sourcemaps command to the prod build command in the package.json\n * - Detect the user's build command\n * - Append the sentry:sourcemaps command to it\n *\n * @param packageDotJson The package.json which will be modified.\n */\nexport async function addSentryCommandToBuildCommand(): Promise<void> {\n const packageDotJson = await getPackageDotJson();\n // This usually shouldn't happen because earlier we added the\n // SENTRY_NPM_SCRIPT_NAME script but just to be sure\n packageDotJson.scripts = packageDotJson.scripts || {};\n\n const allNpmScripts = Object.keys(packageDotJson.scripts).filter(\n (s) => s !== SENTRY_NPM_SCRIPT_NAME,\n );\n\n const packageManager = await getPackageManager(NPM);\n\n // Heuristic to pre-select the build command:\n // Often, 'build' is the prod build command, so we favour it.\n // If it's not there, commands that include 'build' might be the prod build command.\n let buildCommand =\n typeof packageDotJson.scripts.build === 'string'\n ? 'build'\n : allNpmScripts.find((s) => s.toLocaleLowerCase().includes('build'));\n\n const isProdBuildCommand =\n !!buildCommand &&\n (await abortIfCancelled(\n clack.confirm({\n message: `Is ${chalk.cyan(\n `${packageManager.runScriptCommand} ${buildCommand}`,\n )} your production build command?`,\n }),\n ));\n\n if (allNpmScripts.length && (!buildCommand || !isProdBuildCommand)) {\n buildCommand = await abortIfCancelled(\n clack.select({\n message: `Which ${packageManager.name} command in your ${chalk.cyan(\n 'package.json',\n )} builds your application for production?`,\n options: allNpmScripts\n .map((script) => ({\n label: script,\n value: script,\n }))\n .concat({ label: 'None of the above', value: 'none' }),\n }),\n );\n }\n\n if (!buildCommand || buildCommand === 'none') {\n clack.log.warn(\n `We can only add the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script to another \\`script\\` in your ${chalk.cyan('package.json')}.\nPlease add it manually to your prod build command.`,\n );\n return;\n }\n\n const oldCommand = packageDotJson.scripts[buildCommand];\n if (!oldCommand) {\n // very unlikely to happen but nevertheless\n clack.log.warn(\n `\\`${buildCommand}\\` doesn't seem to be part of your package.json scripts`,\n );\n return;\n }\n\n const newCommand = `${oldCommand} && ${packageManager.runScriptCommand} ${SENTRY_NPM_SCRIPT_NAME}`;\n\n if (oldCommand.endsWith(SENTRY_NPM_SCRIPT_NAME)) {\n clack.log.info(\n `It seems like ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} is already part of your ${chalk.cyan(\n buildCommand,\n )} command. Will not add it again.\nCurrent command: ${chalk.dim(oldCommand)}\nWould have injected: ${chalk.dim(newCommand)}`,\n );\n\n return;\n }\n\n packageDotJson.scripts[buildCommand] = newCommand;\n\n await fs.promises.writeFile(\n path.join(process.cwd(), 'package.json'),\n JSON.stringify(packageDotJson, null, 2),\n );\n\n addedToBuildCommand = true;\n\n clack.log.info(\n `Added ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(\n buildCommand,\n )} command.`,\n );\n}\n\nasync function defaultConfigureSourcemapGenerationFlow(): Promise<void> {\n await abortIfCancelled(\n clack.select({\n message: `Verify that your build tool is generating source maps. ${chalk.dim(\n '(Your build output folder should contain .js.map files after a build)',\n )}`,\n options: [{ label: 'I checked. Continue!', value: true }],\n initialValue: true,\n }),\n );\n}\n"]}
1
+ {"version":3,"file":"sentry-cli.js","sourceRoot":"","sources":["../../../../src/sourcemaps/tools/sentry-cli.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as Sentry from '@sentry/node';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport {\n abortIfCancelled,\n addSentryCliConfig,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n artifactsExist,\n askToRunBuildOrEnterPathOrProceed,\n} from '../../utils/clack';\n\nimport { SourceMapUploadToolConfigurationOptions } from './types';\nimport { hasPackageInstalled } from '../../utils/package-json';\nimport { traceStep } from '../../telemetry';\nimport { NPM } from '../../utils/package-manager';\n\nconst SENTRY_NPM_SCRIPT_NAME = 'sentry:sourcemaps';\n\nlet addedToBuildCommand = false;\n\ntype configureSentryCLIOptions = SourceMapUploadToolConfigurationOptions & {\n defaultArtifactPath?: string;\n};\n\nexport async function configureSentryCLI(\n options: configureSentryCLIOptions,\n configureSourcemapGenerationFlow: () => Promise<void> = defaultConfigureSourcemapGenerationFlow,\n skipValidation = false,\n): Promise<void> {\n const packageDotJson = await getPackageDotJson();\n\n await installPackage({\n packageName: '@sentry/cli',\n alreadyInstalled: hasPackageInstalled('@sentry/cli', packageDotJson),\n });\n\n let validPath = false;\n let relativeArtifactPath: string | undefined;\n do {\n const rawArtifactPath = await abortIfCancelled(\n clack.text({\n message: 'Where are your build artifacts located?',\n placeholder:\n relativeArtifactPath ??\n options.defaultArtifactPath ??\n `.${path.sep}out`,\n initialValue:\n relativeArtifactPath ??\n options.defaultArtifactPath ??\n `.${path.sep}out`,\n validate(value) {\n if (!value) {\n return 'Please enter a path.';\n }\n },\n }),\n );\n\n if (path.isAbsolute(rawArtifactPath)) {\n relativeArtifactPath = path.relative(process.cwd(), rawArtifactPath);\n } else {\n relativeArtifactPath = rawArtifactPath;\n }\n\n if (artifactsExist(relativeArtifactPath)) {\n validPath = true;\n continue;\n }\n\n const runBuildOrEnterPathOrProceed =\n await askToRunBuildOrEnterPathOrProceed({\n relativeArtifactPath,\n });\n\n validPath = runBuildOrEnterPathOrProceed?.validPath ?? false;\n relativeArtifactPath =\n runBuildOrEnterPathOrProceed?.relativeArtifactPath ??\n relativeArtifactPath;\n } while (!validPath);\n\n const relativePosixArtifactPath = relativeArtifactPath\n .split(path.sep)\n .join(path.posix.sep);\n\n if (!skipValidation) {\n await configureSourcemapGenerationFlow();\n }\n\n await createAndAddNpmScript(options, relativePosixArtifactPath);\n\n if (await askShouldAddToBuildCommand()) {\n await traceStep('sentry-cli-add-to-build-cmd', () =>\n addSentryCommandToBuildCommand(),\n );\n } else {\n clack.log.info(\n `No problem, just make sure to run this script ${chalk.bold(\n 'after',\n )} building your application but ${chalk.bold('before')} deploying!`,\n );\n }\n\n await addSentryCliConfig({ authToken: options.authToken });\n}\n\nexport async function setupNpmScriptInCI(): Promise<void> {\n if (addedToBuildCommand) {\n // No need to tell users to add it manually to their CI\n // if the script is already added to the build command\n return;\n }\n\n const addedToCI = await abortIfCancelled(\n clack.select({\n message: `Add a step to your CI pipeline that runs the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script ${chalk.bold('right after')} building your application.`,\n options: [\n { label: 'I did, continue!', value: true },\n {\n label: \"I'll do it later...\",\n value: false,\n hint: chalk.yellow(\n `You need to run ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} after each build for source maps to work properly.`,\n ),\n },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('added-ci-script', addedToCI);\n\n if (!addedToCI) {\n clack.log.info(\"Don't forget! :)\");\n }\n}\n\nasync function createAndAddNpmScript(\n options: SourceMapUploadToolConfigurationOptions,\n relativePosixArtifactPath: string,\n): Promise<void> {\n const sentryCliNpmScript = `sentry-cli sourcemaps inject --org ${\n options.orgSlug\n } --project ${\n options.projectSlug\n } ${relativePosixArtifactPath} && sentry-cli${\n options.selfHosted ? ` --url ${options.url}` : ''\n } sourcemaps upload --org ${options.orgSlug} --project ${\n options.projectSlug\n } ${relativePosixArtifactPath}`;\n\n const packageDotJson = await getPackageDotJson();\n\n packageDotJson.scripts = packageDotJson.scripts || {};\n packageDotJson.scripts[SENTRY_NPM_SCRIPT_NAME] = sentryCliNpmScript;\n\n await fs.promises.writeFile(\n path.join(process.cwd(), 'package.json'),\n JSON.stringify(packageDotJson, null, 2),\n );\n\n clack.log.info(\n `Added a ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(\n 'package.json',\n )}.`,\n );\n}\n\nasync function askShouldAddToBuildCommand(): Promise<boolean> {\n const shouldAddToBuildCommand = await abortIfCancelled(\n clack.select({\n message: `Do you want to automatically run the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script after each production build?`,\n options: [\n {\n label: 'Yes',\n value: true,\n hint: 'This will modify your prod build command',\n },\n { label: 'No', value: false },\n ],\n initialValue: true,\n }),\n );\n\n Sentry.setTag('modify-build-command', shouldAddToBuildCommand);\n\n return shouldAddToBuildCommand;\n}\n\n/**\n * Add the sentry:sourcemaps command to the prod build command in the package.json\n * - Detect the user's build command\n * - Append the sentry:sourcemaps command to it\n *\n * @param packageDotJson The package.json which will be modified.\n */\nexport async function addSentryCommandToBuildCommand(): Promise<void> {\n const packageDotJson = await getPackageDotJson();\n // This usually shouldn't happen because earlier we added the\n // SENTRY_NPM_SCRIPT_NAME script but just to be sure\n packageDotJson.scripts = packageDotJson.scripts || {};\n\n const allNpmScripts = Object.keys(packageDotJson.scripts).filter(\n (s) => s !== SENTRY_NPM_SCRIPT_NAME,\n );\n\n const packageManager = await getPackageManager(NPM);\n\n // Heuristic to pre-select the build command:\n // Often, 'build' is the prod build command, so we favour it.\n // If it's not there, commands that include 'build' might be the prod build command.\n let buildCommand =\n typeof packageDotJson.scripts.build === 'string'\n ? 'build'\n : allNpmScripts.find((s) => s.toLocaleLowerCase().includes('build'));\n\n const isProdBuildCommand =\n !!buildCommand &&\n (await abortIfCancelled(\n clack.confirm({\n message: `Is ${chalk.cyan(\n `${packageManager.runScriptCommand} ${buildCommand}`,\n )} your production build command?`,\n }),\n ));\n\n if (allNpmScripts.length && (!buildCommand || !isProdBuildCommand)) {\n buildCommand = await abortIfCancelled(\n clack.select({\n message: `Which ${packageManager.name} command in your ${chalk.cyan(\n 'package.json',\n )} builds your application for production?`,\n options: allNpmScripts\n .map((script) => ({\n label: script,\n value: script,\n }))\n .concat({ label: 'None of the above', value: 'none' }),\n }),\n );\n }\n\n if (!buildCommand || buildCommand === 'none') {\n clack.log.warn(\n `We can only add the ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} script to another \\`script\\` in your ${chalk.cyan('package.json')}.\nPlease add it manually to your prod build command.`,\n );\n return;\n }\n\n const oldCommand = packageDotJson.scripts[buildCommand];\n if (!oldCommand) {\n // very unlikely to happen but nevertheless\n clack.log.warn(\n `\\`${buildCommand}\\` doesn't seem to be part of your package.json scripts`,\n );\n return;\n }\n\n const newCommand = `${oldCommand} && ${packageManager.runScriptCommand} ${SENTRY_NPM_SCRIPT_NAME}`;\n\n if (oldCommand.endsWith(SENTRY_NPM_SCRIPT_NAME)) {\n clack.log.info(\n `It seems like ${chalk.cyan(\n SENTRY_NPM_SCRIPT_NAME,\n )} is already part of your ${chalk.cyan(\n buildCommand,\n )} command. Will not add it again.\nCurrent command: ${chalk.dim(oldCommand)}\nWould have injected: ${chalk.dim(newCommand)}`,\n );\n\n return;\n }\n\n packageDotJson.scripts[buildCommand] = newCommand;\n\n await fs.promises.writeFile(\n path.join(process.cwd(), 'package.json'),\n JSON.stringify(packageDotJson, null, 2),\n );\n\n addedToBuildCommand = true;\n\n clack.log.info(\n `Added ${chalk.cyan(SENTRY_NPM_SCRIPT_NAME)} script to your ${chalk.cyan(\n buildCommand,\n )} command.`,\n );\n}\n\nasync function defaultConfigureSourcemapGenerationFlow(): Promise<void> {\n await abortIfCancelled(\n clack.select({\n message: `Verify that your build tool is generating source maps. ${chalk.dim(\n '(Your build output folder should contain .js.map files after a build)',\n )}`,\n options: [{ label: 'I checked. Continue!', value: true }],\n initialValue: true,\n }),\n );\n}\n"]}
@@ -252,4 +252,11 @@ export declare function featureSelectionPrompt<F extends ReadonlyArray<Feature>>
252
252
  }>;
253
253
  export declare function askShouldInstallPackage(pkgName: string): Promise<boolean>;
254
254
  export declare function askShouldAddPackageOverride(pkgName: string, pkgVersion: string): Promise<boolean>;
255
+ export declare function artifactsExist(relativePath: string): boolean;
256
+ export declare function askToRunBuildOrEnterPathOrProceed({ relativeArtifactPath, }: {
257
+ relativeArtifactPath: string;
258
+ }): Promise<{
259
+ validPath: boolean;
260
+ relativeArtifactPath?: string;
261
+ }>;
255
262
  export {};
@@ -26,12 +26,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.askShouldAddPackageOverride = exports.askShouldInstallPackage = exports.featureSelectionPrompt = exports.askShouldCreateExampleComponent = exports.askShouldCreateExamplePage = exports.createNewConfigFile = exports.makeCodeSnippet = exports.showCopyPasteInstructions = exports.askForToolConfigPath = exports.askForWizardLogin = exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageManager = exports.updatePackageDotJson = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.runPrettierIfInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.confirmContinueIfPackageVersionNotSupported = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueIfNoOrDirtyGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.propertiesCliSetupConfig = exports.rcCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
29
+ exports.askToRunBuildOrEnterPathOrProceed = exports.artifactsExist = exports.askShouldAddPackageOverride = exports.askShouldInstallPackage = exports.featureSelectionPrompt = exports.askShouldCreateExampleComponent = exports.askShouldCreateExamplePage = exports.createNewConfigFile = exports.makeCodeSnippet = exports.showCopyPasteInstructions = exports.askForToolConfigPath = exports.askForWizardLogin = exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageManager = exports.updatePackageDotJson = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.runPrettierIfInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.confirmContinueIfPackageVersionNotSupported = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueIfNoOrDirtyGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.propertiesCliSetupConfig = exports.rcCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
30
30
  const childProcess = __importStar(require("node:child_process"));
31
31
  const fs = __importStar(require("node:fs"));
32
+ const node_child_process_1 = require("node:child_process");
32
33
  const node_path_1 = require("node:path");
33
34
  const node_timers_1 = require("node:timers");
34
35
  const node_url_1 = require("node:url");
36
+ const path = __importStar(require("path"));
37
+ const package_manager_1 = require("../../utils/package-manager");
35
38
  // @ts-expect-error - clack is ESM and TS complains about that. It works though
36
39
  const clack = __importStar(require("@clack/prompts"));
37
40
  const Sentry = __importStar(require("@sentry/node"));
@@ -42,7 +45,7 @@ const telemetry_1 = require("../../telemetry");
42
45
  const version_1 = require("../../version");
43
46
  const debug_1 = require("../debug");
44
47
  const package_json_1 = require("../package-json");
45
- const package_manager_1 = require("../package-manager");
48
+ const package_manager_2 = require("../package-manager");
46
49
  const semver_1 = require("../semver");
47
50
  const git_1 = require("../git");
48
51
  exports.SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';
@@ -580,7 +583,7 @@ async function getPackageManager(fallback) {
580
583
  if (globalWithSentryWizard.__sentry_wizard_cached_package_manager) {
581
584
  return globalWithSentryWizard.__sentry_wizard_cached_package_manager;
582
585
  }
583
- const detectedPackageManager = (0, package_manager_1._detectPackageManger)();
586
+ const detectedPackageManager = (0, package_manager_2._detectPackageManger)();
584
587
  if (detectedPackageManager) {
585
588
  globalWithSentryWizard.__sentry_wizard_cached_package_manager =
586
589
  detectedPackageManager;
@@ -594,7 +597,7 @@ async function getPackageManager(fallback) {
594
597
  }
595
598
  const selectedPackageManager = await abortIfCancelled(clack.select({
596
599
  message: 'Please select your package manager.',
597
- options: package_manager_1.packageManagers.map((packageManager) => ({
600
+ options: package_manager_2.packageManagers.map((packageManager) => ({
598
601
  value: packageManager,
599
602
  label: packageManager.label,
600
603
  })),
@@ -1081,4 +1084,124 @@ async function askShouldAddPackageOverride(pkgName, pkgVersion) {
1081
1084
  })));
1082
1085
  }
1083
1086
  exports.askShouldAddPackageOverride = askShouldAddPackageOverride;
1087
+ async function getBuildCommand() {
1088
+ const packageDotJson = await getPackageDotJson();
1089
+ return typeof packageDotJson.scripts?.build === 'string' ? 'build' : null;
1090
+ }
1091
+ function artifactsExist(relativePath) {
1092
+ return fs.existsSync(path.join(process.cwd(), relativePath));
1093
+ }
1094
+ exports.artifactsExist = artifactsExist;
1095
+ async function askToRunBuildOrEnterPathOrProceed({ relativeArtifactPath, }) {
1096
+ const options = [];
1097
+ const buildCommand = await getBuildCommand();
1098
+ if (buildCommand) {
1099
+ options.push({
1100
+ label: 'Let the wizard run the build command',
1101
+ value: 'run-build',
1102
+ });
1103
+ }
1104
+ options.push({
1105
+ label: 'Enter a different path manually',
1106
+ value: 'manual',
1107
+ }, {
1108
+ label: 'Proceed anyway — I believe the path is correct',
1109
+ value: 'proceed',
1110
+ });
1111
+ const whatToDo = await abortIfCancelled(clack.select({
1112
+ message: `We couldn't find build artifacts at "${relativeArtifactPath}". What would you like to do?`,
1113
+ options,
1114
+ initialValue: buildCommand ? 'run-build' : 'manual',
1115
+ }));
1116
+ if (whatToDo === 'proceed') {
1117
+ return {
1118
+ validPath: true,
1119
+ };
1120
+ }
1121
+ if (whatToDo === 'run-build' && buildCommand) {
1122
+ const ranBuildAndCheckArtifacts = await runBuildAndCheckArtifacts(buildCommand, relativeArtifactPath);
1123
+ if (ranBuildAndCheckArtifacts.validPath === false) {
1124
+ return await askToRunBuildOrEnterPathOrProceed({ relativeArtifactPath });
1125
+ }
1126
+ return ranBuildAndCheckArtifacts;
1127
+ }
1128
+ return {
1129
+ validPath: false,
1130
+ };
1131
+ }
1132
+ exports.askToRunBuildOrEnterPathOrProceed = askToRunBuildOrEnterPathOrProceed;
1133
+ function getPossibleBuildFolders() {
1134
+ const commonBuildFolders = ['build', 'dist', 'out', '.next'];
1135
+ return commonBuildFolders.filter((folder) => fs.existsSync(path.join(process.cwd(), folder)));
1136
+ }
1137
+ async function promptForAlternativeArtifactPath() {
1138
+ const folders = getPossibleBuildFolders();
1139
+ if (!folders.length) {
1140
+ return undefined;
1141
+ }
1142
+ if (folders.length === 1) {
1143
+ const [onlyFolder] = folders;
1144
+ const confirmed = await abortIfCancelled(clack.select({
1145
+ message: `Detected one possible build folder. Use "${onlyFolder}" as your build artifacts folder?`,
1146
+ options: [
1147
+ {
1148
+ value: true,
1149
+ label: 'Yes',
1150
+ },
1151
+ { value: false, label: 'No' },
1152
+ ],
1153
+ }));
1154
+ return confirmed ? onlyFolder : undefined;
1155
+ }
1156
+ const selected = await abortIfCancelled(clack.select({
1157
+ message: `Detected multiple possible build folders. Is one of these your build artifacts folder?`,
1158
+ options: [
1159
+ ...folders.map((f) => ({ value: f, label: f })),
1160
+ { value: false, label: 'No' },
1161
+ ],
1162
+ }));
1163
+ if (selected) {
1164
+ return String(selected);
1165
+ }
1166
+ return undefined;
1167
+ }
1168
+ async function runBuildCommand(buildCommand) {
1169
+ const packageManager = await getPackageManager(package_manager_1.NPM);
1170
+ const command = `${packageManager.runScriptCommand} ${buildCommand}`;
1171
+ const spinner = clack.spinner();
1172
+ spinner.start(`Running ${chalk_1.default.cyan(command)}...`);
1173
+ try {
1174
+ (0, node_child_process_1.execSync)(command, {
1175
+ stdio: 'inherit',
1176
+ cwd: process.cwd(),
1177
+ });
1178
+ spinner.stop('Build finished running.');
1179
+ return true;
1180
+ }
1181
+ catch (error) {
1182
+ spinner.stop(`Build failed: ${error instanceof Error ? error.message : String(error)}`);
1183
+ clack.log.error('Failed to run your build command. Please run it manually and try again.');
1184
+ return false;
1185
+ }
1186
+ }
1187
+ async function runBuildAndCheckArtifacts(buildCommand, relativeArtifactPath) {
1188
+ const buildRan = await runBuildCommand(buildCommand);
1189
+ if (!buildRan) {
1190
+ return { validPath: false };
1191
+ }
1192
+ const found = artifactsExist(relativeArtifactPath);
1193
+ if (found) {
1194
+ clack.log.success('Build completed and build artifacts folder found!');
1195
+ return { validPath: true };
1196
+ }
1197
+ clack.log.warn(`Build ran, but build artifacts folder still not found at ${relativeArtifactPath}.`);
1198
+ const fallbackPath = await promptForAlternativeArtifactPath();
1199
+ if (!fallbackPath) {
1200
+ return { validPath: false };
1201
+ }
1202
+ return {
1203
+ validPath: artifactsExist(fallbackPath),
1204
+ relativeArtifactPath: fallbackPath,
1205
+ };
1206
+ }
1084
1207
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/clack/index.ts"],"names":[],"mappings":"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","sourcesContent":["import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { basename, isAbsolute, join, relative } from 'node:path';\nimport { setInterval } from 'node:timers';\nimport { URL } from 'node:url';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport axios from 'axios';\nimport chalk from 'chalk';\nimport opn from 'opn';\nimport { traceStep } from '../../telemetry';\nimport { WIZARD_VERSION } from '../../version';\nimport { debug } from '../debug';\nimport { type PackageDotJson, hasPackageInstalled } from '../package-json';\nimport {\n type PackageManager,\n _detectPackageManger,\n packageManagers,\n} from '../package-manager';\nimport { fulfillsVersionRange } from '../semver';\nimport type { Feature, SentryProjectData, WizardOptions } from '../types';\nimport { getUncommittedOrUntrackedFiles, isInGitRepo } from '../git';\n\nexport const SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';\nexport const SENTRY_CLI_RC_FILE = '.sentryclirc';\nexport const SENTRY_PROPERTIES_FILE = 'sentry.properties';\n\nconst SAAS_URL = 'https://sentry.io/';\n\nconst DUMMY_AUTH_TOKEN = '_YOUR_SENTRY_AUTH_TOKEN_';\n\ninterface WizardProjectData {\n apiKeys?: {\n token?: string;\n };\n projects?: SentryProjectData[];\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\nexport const rcCliSetupConfig: CliSetupConfig = {\n filename: SENTRY_CLI_RC_FILE,\n name: 'source maps',\n gitignore: true,\n likelyAlreadyHasAuthToken: function (contents: string): boolean {\n return !!(contents.includes('[auth]') && contents.match(/token=./g));\n },\n tokenContent: function (authToken: string): string {\n return `[auth]\\ntoken=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject: function (contents: string): boolean {\n return !!(\n contents.includes('[defaults]') &&\n contents.match(/org=./g) &&\n contents.match(/project=./g)\n );\n },\n orgAndProjContent: function (org: string, project: string): string {\n return `[defaults]\\norg=${org}\\nproject=${project}`;\n },\n};\n\nexport const propertiesCliSetupConfig: Required<CliSetupConfig> = {\n filename: SENTRY_PROPERTIES_FILE,\n gitignore: true,\n name: 'debug files',\n likelyAlreadyHasAuthToken(contents: string): boolean {\n return !!contents.match(/auth\\.token=./g);\n },\n tokenContent(authToken: string): string {\n return `auth.token=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject(contents: string): boolean {\n return !!(\n contents.match(/defaults\\.org=./g) &&\n contents.match(/defaults\\.project=./g)\n );\n },\n orgAndProjContent(org: string, project: string): string {\n return `defaults.org=${org}\\ndefaults.project=${project}`;\n },\n likelyAlreadyHasUrl(contents: string): boolean {\n return !!contents.match(/defaults\\.url=./g);\n },\n urlContent(url: string): string {\n return `defaults.url=${url}`;\n },\n};\n\n/**\n * Aborts the wizard and sets the Sentry transaction status to `cancelled` or `aborted`.\n *\n * @param message The message to display to the user.\n * @param status The status to set on the Sentry transaction. Defaults to `1`.\n */\nexport async function abort(message?: string, status?: number): Promise<never> {\n clack.outro(message ?? 'Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n // 'cancelled' doesn't increase the `failureRate()` shown in the Sentry UI\n // 'aborted' increases the failure rate\n // see: https://docs.sentry.io/product/insights/overview/metrics/#failure-rate\n sentryTransaction?.setStatus(status === 0 ? 'cancelled' : 'aborted');\n sentryTransaction?.finish();\n const sentrySession = sentryHub.getScope().getSession();\n if (sentrySession) {\n sentrySession.status = status === 0 ? 'abnormal' : 'crashed';\n sentryHub.captureSession(true);\n }\n await Sentry.flush(3000);\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n): Promise<Exclude<T, symbol>> {\n if (clack.isCancel(await input)) {\n clack.cancel('Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('cancelled');\n sentryTransaction?.finish();\n sentryHub.captureSession(true);\n await Sentry.flush(3000);\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: {\n wizardName: string;\n promoCode?: string;\n message?: string;\n telemetryEnabled?: boolean;\n}): void {\n // eslint-disable-next-line no-console\n console.log('');\n clack.intro(chalk.inverse(` ${options.wizardName} `));\n\n let welcomeText =\n options.message ||\n `The ${options.wizardName} will help you set up Sentry for your application.\\nThank you for using Sentry :)`;\n\n if (options.promoCode) {\n welcomeText = `${welcomeText}\\n\\nUsing promo-code: ${options.promoCode}`;\n }\n\n welcomeText = `${welcomeText}\\n\\nVersion: ${WIZARD_VERSION}`;\n\n if (options.telemetryEnabled) {\n welcomeText = `${welcomeText}\n\nThis wizard sends telemetry data and crash reports to Sentry. This helps us improve the Wizard.\nYou can turn this off at any time by running ${chalk.cyanBright(\n 'sentry-wizard --disable-telemetry',\n )}.`;\n }\n\n clack.note(welcomeText);\n}\n\n/**\n * Confirms if the user wants to continue with the wizard if the project is not a git repository.\n *\n * @param options.ignoreGitChanges If true, the wizard will not check if the project is a git repository.\n * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.\n */\nexport async function confirmContinueIfNoOrDirtyGitRepo(options: {\n ignoreGitChanges: boolean | undefined;\n cwd: string | undefined;\n}): Promise<void> {\n return traceStep('check-git-status', async () => {\n if (\n !isInGitRepo({\n cwd: options.cwd,\n }) &&\n options.ignoreGitChanges !== true\n ) {\n const continueWithoutGit = await abortIfCancelled(\n clack.confirm({\n message:\n 'You are not inside a git repository. The wizard will create and update files. Do you want to continue anyway?',\n }),\n );\n\n Sentry.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n // return early to avoid checking for uncommitted files\n return;\n }\n\n const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();\n if (\n uncommittedOrUntrackedFiles.length &&\n options.ignoreGitChanges !== true\n ) {\n clack.log.warn(\n `You have uncommitted or untracked files in your repo:\n\n${uncommittedOrUntrackedFiles.join('\\n')}\n\nThe wizard will create and update files.`,\n );\n const continueWithDirtyRepo = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n\n Sentry.setTag('continue-with-dirty-repo', continueWithDirtyRepo);\n\n if (!continueWithDirtyRepo) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function askToInstallSentryCLI(): Promise<boolean> {\n return await abortIfCancelled(\n clack.confirm({\n message:\n \"You don't have Sentry CLI installed. Do you want to install it?\",\n }),\n );\n}\n\nexport async function askForItemSelection(\n items: string[],\n message: string,\n): Promise<{ value: string; index: number }> {\n const selection: { value: string; index: number } | symbol =\n await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection;\n}\n\nexport async function confirmContinueIfPackageVersionNotSupported({\n packageId,\n packageName,\n packageVersion,\n acceptableVersions,\n note,\n}: {\n packageId: string;\n packageName: string;\n packageVersion: string;\n acceptableVersions: string;\n note?: string;\n}): Promise<void> {\n return traceStep(`check-package-version`, async () => {\n Sentry.setTag(`${packageName.toLowerCase()}-version`, packageVersion);\n const isSupportedVersion = fulfillsVersionRange({\n acceptableVersions,\n version: packageVersion,\n canBeLatest: true,\n });\n\n if (isSupportedVersion) {\n Sentry.setTag(`${packageName.toLowerCase()}-supported`, true);\n return;\n }\n\n clack.log.warn(\n `You have an unsupported version of ${packageName} installed:\n\n ${packageId}@${packageVersion}`,\n );\n\n clack.note(\n note ??\n `Please upgrade to ${acceptableVersions} if you wish to use the Sentry Wizard.`,\n );\n const continueWithUnsupportedVersion = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n Sentry.setTag(\n `${packageName.toLowerCase()}-continue-with-unsupported-version`,\n continueWithUnsupportedVersion,\n );\n\n if (!continueWithUnsupportedVersion) {\n await abort(undefined, 0);\n }\n });\n}\n\ntype InstallPackageOptions = {\n /** The string that is passed to the package manager CLI as identifier to install (e.g. `@sentry/nextjs`, or `@sentry/nextjs@^8`) */\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n /** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly (e.g. `@sentry/nextjs@^8`) */\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n /** Add force install flag to command to skip install precondition fails */\n forceInstall?: boolean;\n /** Install as a dev dependency (@default: false) */\n devDependency?: boolean;\n};\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n packageNameDisplayLabel,\n packageManager,\n forceInstall = false,\n devDependency = false,\n}: InstallPackageOptions): Promise<{ packageManager?: PackageManager }> {\n return traceStep('install-package', async () => {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n clack.confirm({\n message: `The ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return {};\n }\n }\n\n const sdkInstallSpinner = clack.spinner();\n\n const pkgManager = packageManager || (await getPackageManager());\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n try {\n await new Promise<void>((resolve, reject) => {\n const installArgs = [\n pkgManager.installCommand,\n ...(devDependency ? ['-D'] : []),\n pkgManager.registry\n ? `${pkgManager.registry}:${packageName}`\n : packageName,\n ...(pkgManager.flags ? pkgManager.flags.split(' ') : []),\n ...(forceInstall ? [pkgManager.forceInstallFlag] : []),\n ];\n\n const stringifiedInstallCmd = `${pkgManager.name} ${installArgs.join(\n ' ',\n )}`;\n\n function handleErrorAndReject(\n code: number | null,\n cause: Error | string,\n type: 'spawn_error' | 'process_error',\n ) {\n // Write a log file so we can better troubleshoot issues\n fs.writeFileSync(\n join(\n process.cwd(),\n `sentry-wizard-installation-error-${Date.now()}.log`,\n ),\n stderr,\n { encoding: 'utf8' },\n );\n\n Sentry.captureException('Package Installation Error', {\n tags: {\n 'install-command': stringifiedInstallCmd,\n 'package-manager': pkgManager.name,\n 'package-name': packageName,\n 'error-type': type,\n },\n });\n\n reject(\n new Error(\n `Installation command ${chalk.cyan(\n stringifiedInstallCmd,\n )} exited with code ${code ?? 'null'}.`,\n {\n cause,\n },\n ),\n );\n }\n\n const installProcess = childProcess.spawn(\n pkgManager.name,\n installArgs,\n {\n shell: true,\n // Ignoring `stdout` to prevent certain node + yarn v4 (observed on ubuntu + snap)\n // combinations from crashing here. See #851\n stdio: ['pipe', 'ignore', 'pipe'],\n },\n );\n\n let stderr = '';\n\n // Defining data as unknown to avoid TS and ESLint errors because of `any` type\n installProcess.stderr.on('data', (data: unknown) => {\n if (data && data.toString && typeof data.toString === 'function') {\n stderr += data.toString();\n }\n });\n\n installProcess.on('error', (err) => {\n handleErrorAndReject(null, err, 'spawn_error');\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n handleErrorAndReject(code, stderr, 'process_error');\n } else {\n resolve();\n }\n });\n });\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n \"The wizard has created a `sentry-wizard-installation-error-*.log` file. If you think this issue is caused by the Sentry wizard, create an issue on GitHub and include the log file's content:\\nhttps://github.com/getsentry/sentry-wizard/issues\",\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n return { packageManager: pkgManager };\n });\n}\n\nexport async function addSentryCliConfig(\n { authToken, org, project, url }: CliSetupConfigContent,\n setupConfig: CliSetupConfig = rcCliSetupConfig,\n): Promise<void> {\n return traceStep('add-sentry-cli-config', async () => {\n const configPath = join(process.cwd(), setupConfig.filename);\n const configExists = fs.existsSync(configPath);\n\n let configContents =\n (configExists && fs.readFileSync(configPath, 'utf8')) || '';\n configContents = addAuthTokenToSentryConfig(\n configContents,\n authToken,\n setupConfig,\n );\n configContents = addOrgAndProjectToSentryConfig(\n configContents,\n org,\n project,\n setupConfig,\n );\n configContents = addUrlToSentryConfig(configContents, url, setupConfig);\n\n try {\n await fs.promises.writeFile(configPath, configContents, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `${configExists ? 'Saved' : 'Created'} ${chalk.cyan(\n setupConfig.filename,\n )}.`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.cyan(\n setupConfig.filename,\n )}. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n\n if (setupConfig.gitignore) {\n await addCliConfigFileToGitIgnore(setupConfig.filename);\n } else {\n clack.log.warn(\n chalk.yellow('DO NOT commit auth token to your repository!'),\n );\n }\n });\n}\n\nfunction addAuthTokenToSentryConfig(\n configContents: string,\n authToken: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!authToken) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasAuthToken(configContents)) {\n clack.log.warn(\n `${chalk.cyan(\n setupConfig.filename,\n )} already has auth token. Will not add one.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.tokenContent(\n authToken,\n )}\\n`;\n clack.log.success(\n `Added auth token to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nfunction addOrgAndProjectToSentryConfig(\n configContents: string,\n org: string | undefined,\n project: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!org || !project) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasOrgAndProject(configContents)) {\n clack.log.warn(\n `${chalk.cyan(\n setupConfig.filename,\n )} already has org and project. Will not add them.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.orgAndProjContent(\n org,\n project,\n )}\\n`;\n clack.log.success(\n `Added default org and project to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nfunction addUrlToSentryConfig(\n configContents: string,\n url: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!url || !setupConfig.urlContent || !setupConfig.likelyAlreadyHasUrl) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasUrl(configContents)) {\n clack.log.warn(\n `${chalk.cyan(setupConfig.filename)} already has url. Will not add one.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.urlContent(url)}\\n`;\n clack.log.success(\n `Added default url to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nexport async function addDotEnvSentryBuildPluginFile(\n authToken: string,\n): Promise<void> {\n const envVarContent = `# DO NOT commit this file to your repository!\n# The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin.\n# It's used for authentication when uploading source maps.\n# You can also set this env variable in your own \\`.env\\` files and remove this file.\nSENTRY_AUTH_TOKEN=${authToken}\n`;\n\n const dotEnvFilePath = join(process.cwd(), SENTRY_DOT_ENV_FILE);\n const dotEnvFileExists = fs.existsSync(dotEnvFilePath);\n\n if (dotEnvFileExists) {\n const dotEnvFileContent = fs.readFileSync(dotEnvFilePath, 'utf8');\n\n const hasAuthToken = !!dotEnvFileContent.match(\n /^\\s*SENTRY_AUTH_TOKEN\\s*=/g,\n );\n\n if (hasAuthToken) {\n clack.log.warn(\n `${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n dotEnvFilePath,\n `${dotEnvFileContent}\\n${envVarContent}`,\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n clack.log.success(\n `Added auth token to ${chalk.bold.cyan(SENTRY_DOT_ENV_FILE)}`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )}. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(dotEnvFilePath, envVarContent, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `Created ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} with auth token for you to test source map uploading locally.`,\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} with auth token. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n\n await addCliConfigFileToGitIgnore(SENTRY_DOT_ENV_FILE);\n}\n\nasync function addCliConfigFileToGitIgnore(filename: string): Promise<void> {\n const gitignorePath = join(process.cwd(), '.gitignore');\n\n try {\n const gitignoreContent = await fs.promises.readFile(gitignorePath, 'utf8');\n if (gitignoreContent.split(/\\r?\\n/).includes(filename)) {\n clack.log.info(\n `${chalk.bold('.gitignore')} already has ${chalk.bold(\n filename,\n )}. Will not add it again.`,\n );\n return;\n }\n\n await fs.promises.appendFile(\n gitignorePath,\n `\\n# Sentry Config File\\n${filename}\\n`,\n { encoding: 'utf8' },\n );\n clack.log.success(\n `Added ${chalk.cyan(filename)} to ${chalk.cyan('.gitignore')}.`,\n );\n } catch {\n clack.log.error(\n `Failed adding ${chalk.cyan(filename)} to ${chalk.cyan(\n '.gitignore',\n )}. Please add it manually!`,\n );\n }\n}\n\n/**\n * Runs prettier on the changed or untracked files in the project.\n *\n * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.\n */\nexport async function runPrettierIfInstalled(opts: {\n cwd: string | undefined;\n}): Promise<void> {\n return traceStep('run-prettier', async () => {\n if (!isInGitRepo({ cwd: opts.cwd })) {\n // We only run formatting on changed files. If we're not in a git repo, we can't find\n // changed files. So let's early-return without showing any formatting-related messages.\n return;\n }\n\n const changedOrUntrackedFiles = getUncommittedOrUntrackedFiles()\n .map((filename) => {\n return filename.startsWith('- ') ? filename.slice(2) : filename;\n })\n .join(' ');\n\n if (!changedOrUntrackedFiles.length) {\n // Likewise, if we can't find changed or untracked files, there's no point in running Prettier.\n return;\n }\n\n const packageJson = await getPackageDotJson();\n const prettierInstalled = hasPackageInstalled('prettier', packageJson);\n\n Sentry.setTag('prettier-installed', prettierInstalled);\n\n if (!prettierInstalled) {\n return;\n }\n\n // prompt the user if they want to run prettier\n const shouldRunPrettier = await abortIfCancelled(\n clack.confirm({\n message:\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n }),\n );\n\n if (!shouldRunPrettier) {\n return;\n }\n\n const prettierSpinner = clack.spinner();\n prettierSpinner.start('Running Prettier on your files.');\n\n try {\n await new Promise<void>((resolve, reject) => {\n childProcess.exec(\n `npx prettier --ignore-unknown --write ${changedOrUntrackedFiles}`,\n (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n },\n );\n });\n } catch (e) {\n prettierSpinner.stop('Prettier failed to run.');\n clack.log.warn(\n 'Prettier failed to run. There may be formatting issues in your updated files.',\n );\n return;\n }\n\n prettierSpinner.stop('Prettier has formatted your files.');\n });\n}\n\n/**\n * Checks if @param packageId is listed as a dependency in @param packageJson.\n * If not, it will ask users if they want to continue without the package.\n *\n * Use this function to check if e.g. a the framework of the SDK is installed\n *\n * @param packageJson the package.json object\n * @param packageId the npm name of the package\n * @param packageName a human readable name of the package\n */\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n): Promise<void> {\n return traceStep('ensure-package-installed', async () => {\n const installed = hasPackageInstalled(packageId, packageJson);\n\n Sentry.setTag(`${packageName.toLowerCase()}-installed`, installed);\n\n if (!installed) {\n Sentry.setTag(`${packageName.toLowerCase()}-installed`, false);\n const continueWithoutPackage = await abortIfCancelled(\n clack.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function getPackageDotJson(): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises\n .readFile(join(process.cwd(), 'package.json'), 'utf8')\n .catch(() => {\n clack.log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n clack.log.error(\n `Unable to parse your ${chalk.cyan(\n 'package.json',\n )}. Make sure it has a valid format!`,\n );\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageDotJson,\n): Promise<void> {\n try {\n await fs.promises.writeFile(\n join(process.cwd(), 'package.json'),\n // TODO: maybe figure out the original indentation\n JSON.stringify(packageDotJson, null, 2),\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n } catch {\n clack.log.error(`Unable to update your ${chalk.cyan('package.json')}.`);\n\n await abort();\n }\n}\n\n/**\n * Use this function to get the used JS Package manager.\n *\n * This function:\n * - attempts to auto-detect the used package manager and return it\n * - if unsuccessful, returns the passed fallback package manager\n * - if no fallback is passed, it asks the user to select a package manager\n *\n * The result is cached on the first invocation to avoid asking the user multiple times.\n *\n * @param fallback the package manager to use if auto-detection fails and you don't want to\n * ask the user. This is useful in cases where asking users would be too intrusive/low in value\n * and where it's okay to fall back to a default package manager. Use this with caution.\n */\nexport async function getPackageManager(\n fallback?: PackageManager,\n): Promise<PackageManager> {\n const globalWithSentryWizard: typeof global & {\n __sentry_wizard_cached_package_manager?: PackageManager;\n } = global;\n\n if (globalWithSentryWizard.__sentry_wizard_cached_package_manager) {\n return globalWithSentryWizard.__sentry_wizard_cached_package_manager;\n }\n\n const detectedPackageManager = _detectPackageManger();\n\n if (detectedPackageManager) {\n globalWithSentryWizard.__sentry_wizard_cached_package_manager =\n detectedPackageManager;\n return detectedPackageManager;\n }\n\n if (fallback) {\n // explicitly avoiding to cache the fallback in case this function\n // gets called again without a fallback (or a different fallback)\n // later on in the wizard flow.\n return fallback;\n }\n\n const selectedPackageManager: PackageManager | symbol =\n await abortIfCancelled(\n clack.select({\n message: 'Please select your package manager.',\n options: packageManagers.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n globalWithSentryWizard.__sentry_wizard_cached_package_manager =\n selectedPackageManager;\n\n Sentry.setTag('package-manager', selectedPackageManager.name);\n\n return selectedPackageManager;\n}\n\nexport function isUsingTypeScript() {\n try {\n return fs.existsSync(join(process.cwd(), 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if we already got project data from a previous wizard invocation.\n * If yes, this data is returned.\n * Otherwise, we start the login flow and ask the user to select a project.\n *\n * Use this function to get project data for the wizard.\n *\n * @param options wizard options\n * @param platform the platform of the wizard\n * @returns project data (org, project, token, url)\n */\nexport async function getOrAskForProjectData(\n options: WizardOptions,\n platform?:\n | 'javascript-angular'\n | 'javascript-nextjs'\n | 'javascript-nuxt'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android'\n | 'react-native'\n | 'flutter',\n): Promise<{\n sentryUrl: string;\n selfHosted: boolean;\n selectedProject: SentryProjectData;\n authToken: string;\n}> {\n if (options.preSelectedProject) {\n return {\n selfHosted: options.preSelectedProject.selfHosted,\n sentryUrl: options.url ?? SAAS_URL,\n authToken: options.preSelectedProject.authToken,\n selectedProject: options.preSelectedProject.project,\n };\n }\n const { url: sentryUrl, selfHosted } = await traceStep(\n 'ask-self-hosted',\n () => askForSelfHosted(options.url, options.saas),\n );\n\n const { projects, apiKeys } = await traceStep('login', () =>\n askForWizardLogin({\n promoCode: options.promoCode,\n url: sentryUrl,\n platform: platform,\n orgSlug: options.orgSlug,\n projectSlug: options.projectSlug,\n comingFrom: options.comingFrom,\n }),\n );\n\n if (!projects || !projects.length) {\n clack.log.error(\n 'No projects found. Please create a project in Sentry and try again.',\n );\n Sentry.setTag('no-projects-found', true);\n await abort();\n // This rejection won't return due to the abort call but TS doesn't know that\n return Promise.reject();\n }\n\n const selectedProject = await traceStep('select-project', () =>\n askForProjectSelection(projects, options.orgSlug, options.projectSlug),\n );\n\n const { token } = apiKeys ?? {};\n\n if (!token) {\n clack.log.error(`Didn't receive an auth token. This shouldn't happen :(\n\nPlease let us know if you think this is a bug in the wizard:\n${chalk.cyan('https://github.com/getsentry/sentry-wizard/issues')}`);\n\n clack.log.info(`In the meantime, we'll add a dummy auth token (${chalk.cyan(\n `\"${DUMMY_AUTH_TOKEN}\"`,\n )}) for you to replace later.\nCreate your auth token here:\n${chalk.cyan(\n selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/settings/auth-tokens`\n : `https://${selectedProject.organization.slug}.sentry.io/settings/auth-tokens`,\n)}`);\n }\n\n return {\n sentryUrl,\n selfHosted,\n authToken: apiKeys?.token || DUMMY_AUTH_TOKEN,\n selectedProject,\n };\n}\n\n/**\n * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.\n *\n * If users started the wizard with a --url arg, that URL is used as the default and we skip\n * the self-hosted question. However, the passed url is still validated and in case it's\n * invalid, users are asked to enter a new one until it is valid.\n *\n * @param urlFromArgs the url passed via the --url arg\n */\nasync function askForSelfHosted(\n urlFromArgs?: string,\n saas?: boolean,\n): Promise<{\n url: string;\n selfHosted: boolean;\n}> {\n if (saas) {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n\n if (!urlFromArgs) {\n const choice: 'saas' | 'self-hosted' | symbol = await abortIfCancelled(\n clack.select({\n message: 'Are you using Sentry SaaS or self-hosted Sentry?',\n options: [\n { value: 'saas', label: 'Sentry SaaS (sentry.io)' },\n {\n value: 'self-hosted',\n label: 'Self-hosted/on-premise/single-tenant',\n },\n ],\n }),\n );\n\n if (choice === 'saas') {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n }\n\n let validUrl: string | undefined;\n let tmpUrlFromArgs = urlFromArgs;\n\n while (validUrl === undefined) {\n const url =\n tmpUrlFromArgs ||\n (await abortIfCancelled(\n clack.text({\n message: `Please enter the URL of your ${\n urlFromArgs ? '' : 'self-hosted '\n }Sentry instance.`,\n placeholder: 'https://sentry.io/',\n }),\n ));\n tmpUrlFromArgs = undefined;\n\n try {\n validUrl = new URL(url).toString();\n\n // We assume everywhere else that the URL ends in a slash\n if (!validUrl.endsWith('/')) {\n validUrl += '/';\n }\n } catch {\n clack.log.error(\n `Please enter a valid URL. (It should look something like \"https://sentry.mydomain.com/\", got ${url})`,\n );\n }\n }\n\n const isSelfHostedUrl = new URL(validUrl).host !== new URL(SAAS_URL).host;\n\n Sentry.setTag('url', validUrl);\n Sentry.setTag('self-hosted', isSelfHostedUrl);\n\n return { url: validUrl, selfHosted: true };\n}\n\n/**\n * Exported for testing\n */\nexport async function askForWizardLogin(options: {\n url: string;\n promoCode?: string;\n platform?:\n | 'javascript-angular'\n | 'javascript-nextjs'\n | 'javascript-nuxt'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android'\n | 'react-native'\n | 'flutter';\n orgSlug?: string;\n projectSlug?: string;\n comingFrom?: string;\n}): Promise<WizardProjectData> {\n const { orgSlug, projectSlug, url, platform, promoCode, comingFrom } =\n options;\n\n Sentry.setTag('has-promo-code', !!promoCode);\n\n const projectAndOrgPreselected = !!(orgSlug && projectSlug);\n\n const hasSentryAccount =\n projectAndOrgPreselected || (await askHasSentryAccount());\n\n Sentry.setTag('already-has-sentry-account', hasSentryAccount);\n\n const wizardHash = await makeInitialWizardHashRequest(url);\n\n const loginUrl = new URL(`${url}account/settings/wizard/${wizardHash}/`);\n\n if (orgSlug) {\n loginUrl.searchParams.set('org_slug', orgSlug);\n }\n\n if (projectSlug) {\n loginUrl.searchParams.set('project_slug', projectSlug);\n }\n\n if (!hasSentryAccount) {\n loginUrl.searchParams.set('signup', '1');\n }\n\n if (platform) {\n loginUrl.searchParams.set('project_platform', platform);\n }\n\n if (promoCode) {\n loginUrl.searchParams.set('code', promoCode);\n }\n\n if (comingFrom) {\n loginUrl.searchParams.set('partner', comingFrom);\n }\n\n const urlToOpen = loginUrl.toString();\n clack.log.info(\n `${chalk.bold(\n `If the browser window didn't open automatically, please open the following link to ${\n hasSentryAccount ? 'log' : 'sign'\n } into Sentry:`,\n )}\\n\\n${chalk.cyan(urlToOpen)}`,\n );\n\n // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here\n const noop = () => {}; // eslint-disable-line @typescript-eslint/no-empty-function\n opn(urlToOpen, { wait: false }).then((cp) => cp.on('error', noop), noop);\n\n const loginSpinner = clack.spinner();\n\n loginSpinner.start('Waiting for you to log in using the link above');\n\n const data = await new Promise<WizardProjectData>((resolve) => {\n const pollingInterval = setInterval(() => {\n axios\n .get<WizardProjectData>(`${url}api/0/wizard/${wizardHash}/`, {\n headers: {\n 'Accept-Encoding': 'deflate',\n },\n })\n .then((result) => {\n resolve(result.data);\n clearTimeout(timeout);\n clearInterval(pollingInterval);\n void axios.delete(`${url}api/0/wizard/${wizardHash}/`);\n })\n .catch(() => {\n // noop - just try again\n });\n }, 500);\n\n const timeout = setTimeout(() => {\n clearInterval(pollingInterval);\n loginSpinner.stop(\n 'Login timed out. No worries - it happens to the best of us.',\n );\n\n Sentry.setTag('opened-wizard-link', false);\n void abort('Please restart the Wizard and log in to complete the setup.');\n }, 180_000);\n });\n\n loginSpinner.stop('Login complete.');\n Sentry.setTag('opened-wizard-link', true);\n\n return data;\n}\n\n/**\n * This first request to Sentry creates a cache on the Sentry backend whose key is returned.\n * We use this key later on to poll for the actual project data.\n */\nasync function makeInitialWizardHashRequest(url: string): Promise<string> {\n const reqUrl = `${url}api/0/wizard/`;\n try {\n return (await axios.get<{ hash: string }>(reqUrl)).data.hash;\n } catch (e: unknown) {\n if (url !== SAAS_URL) {\n clack.log.error(\n `Loading Wizard failed. Did you provide the right URL? (url: ${reqUrl})`,\n );\n clack.log.info(JSON.stringify(e, null, 2));\n await abort(\n chalk.red(\n 'Please check your configuration and try again.\\n\\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n } else {\n clack.log.error('Loading Wizard failed.');\n clack.log.info(JSON.stringify(e, null, 2));\n await abort(\n chalk.red(\n 'Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n }\n }\n\n // We don't get here as we abort in an error case but TS doesn't know that\n return 'invalid hash';\n}\n\nasync function askHasSentryAccount(): Promise<boolean> {\n const hasSentryAccount = await clack.confirm({\n message: 'Do you already have a Sentry account?',\n });\n\n return abortIfCancelled(hasSentryAccount);\n}\n\nasync function askForProjectSelection(\n projects: SentryProjectData[],\n orgSlug?: string,\n projectSlug?: string,\n): Promise<SentryProjectData> {\n const label = (project: SentryProjectData): string => {\n return `${project.organization.slug}/${project.slug}`;\n };\n\n const filteredProjects = filterProjectsBySlugs(\n projects,\n orgSlug,\n projectSlug,\n );\n\n if (filteredProjects.length === 1) {\n const selection = filteredProjects[0];\n\n Sentry.setTag('project', selection.slug);\n Sentry.setUser({ id: selection.organization.slug });\n clack.log.step(`Selected project ${label(selection)}`);\n\n return selection;\n }\n\n if (filteredProjects.length === 0) {\n clack.log.warn('Could not find a project with the provided slugs.');\n }\n\n const sortedProjects = filteredProjects.length ? filteredProjects : projects;\n sortedProjects.sort((a: SentryProjectData, b: SentryProjectData) => {\n return label(a).localeCompare(label(b));\n });\n\n const selection: SentryProjectData | symbol = await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: 'Select your Sentry project.',\n options: sortedProjects.map((project) => {\n return {\n value: project,\n label: label(project),\n };\n }),\n }),\n );\n\n Sentry.setTag('project', selection.slug);\n Sentry.setUser({ id: selection.organization.slug });\n\n return selection;\n}\n\nfunction filterProjectsBySlugs(\n projects: SentryProjectData[],\n orgSlug?: string,\n projectSlug?: string,\n): SentryProjectData[] {\n if (!orgSlug && !projectSlug) {\n return projects;\n }\n if (orgSlug && !projectSlug) {\n return projects.filter((p) => p.organization.slug === orgSlug);\n }\n if (!orgSlug && projectSlug) {\n return projects.filter((p) => p.slug === projectSlug);\n }\n\n return projects.filter(\n (p) => p.organization.slug === orgSlug && p.slug === projectSlug,\n );\n}\n\n/**\n * Asks users if they have a config file for @param tool (e.g. Vite).\n * If yes, asks users to specify the path to their config file.\n *\n * Use this helper function as a fallback mechanism if the lookup for\n * a config file with its most usual location/name fails.\n *\n * @param toolName Name of the tool for which we're looking for the config file\n * @param configFileName Name of the most common config file name (e.g. vite.config.js)\n *\n * @returns a user path to the config file or undefined if the user doesn't have a config file\n */\nexport async function askForToolConfigPath(\n toolName: string,\n configFileName: string,\n): Promise<string | undefined> {\n const hasConfig = await abortIfCancelled(\n clack.confirm({\n message: `Do you have a ${toolName} config file (e.g. ${chalk.cyan(\n configFileName,\n )})?`,\n initialValue: true,\n }),\n );\n\n if (!hasConfig) {\n return undefined;\n }\n\n return await abortIfCancelled(\n clack.text({\n message: `Please enter the path to your ${toolName} config file:`,\n placeholder: join('.', configFileName),\n validate: (value) => {\n if (!value) {\n return 'Please enter a path.';\n }\n\n try {\n fs.accessSync(value);\n } catch {\n return 'Could not access the file at this path.';\n }\n },\n }),\n );\n}\n\ntype ShowCopyPasteInstructionsOptions = { codeSnippet: string } & (\n | {\n filename: string;\n hint?: string;\n }\n | {\n instructions: string;\n }\n);\n\n/**\n * Prints copy/paste-able instructions to the console.\n * Afterwards asks the user if they added the code snippet to their file.\n *\n * While there's no point in providing a \"no\" answer here, it gives users time to fulfill the\n * task before the wizard continues with additional steps.\n *\n * Use this function if you want to show users instructions on how to add/modify\n * code in their file. This is helpful if automatic insertion failed or is not possible/feasible.\n *\n * @param filename the name of the file to which the code snippet should be applied.\n * If a path is provided, only the filename will be used.\n *\n * @param codeSnippet the snippet to be printed. Use {@link makeCodeSnippet} to create the\n * diff-like format for visually highlighting unchanged or modified lines of code.\n *\n * @param hint (optional) a hint to be printed after the main instruction to add\n * the code from @param codeSnippet to their @param filename.\n *\n * More guidelines on copy/paste instructions:\n * @see {@link https://develop.sentry.dev/sdk/setup-wizards/#copy--paste-snippets}\n *\n * TODO: refactor copy paste instructions across different wizards to use this function.\n * this might require adding a custom message parameter to the function\n */\nexport async function showCopyPasteInstructions(\n opts: ShowCopyPasteInstructionsOptions,\n): Promise<void> {\n if ('instructions' in opts) {\n clack.log.step(opts.instructions);\n } else {\n const defaultInstructions = `Add the following code to your ${chalk.cyan(\n basename(opts.filename),\n )} file:${opts.hint ? chalk.dim(` (${chalk.dim(opts.hint)})`) : ''}`;\n\n clack.log.step(defaultInstructions);\n }\n\n // Padding the code snippet to be printed with a \\n at the beginning and end\n // This makes it easier to distinguish the snippet from the rest of the output\n // Intentionally logging directly to console here so that the code can be copied/pasted directly\n // eslint-disable-next-line no-console\n console.log(`\\n${opts.codeSnippet}\\n`);\n\n await abortIfCancelled(\n clack.select({\n message: 'Did you apply the snippet above?',\n options: [{ label: 'Yes, continue!', value: true }],\n initialValue: true,\n }),\n );\n}\n\n/**\n * Callback that exposes formatting helpers for a code snippet.\n * @param unchanged - Formats text as old code.\n * @param plus - Formats text as new code.\n * @param minus - Formats text as removed code.\n */\ntype CodeSnippetFormatter = (\n unchanged: (txt: string) => string,\n plus: (txt: string) => string,\n minus: (txt: string) => string,\n) => string;\n\n/**\n * Crafts a code snippet that can be used to e.g.\n * - print copy/paste instructions to the console\n * - create a new config file.\n *\n * @param colors set this to true if you want the final snippet to be colored.\n * This is useful for printing the snippet to the console as part of copy/paste instructions.\n *\n * @param callback the callback that returns the formatted code snippet.\n * It exposes takes the helper functions for marking code as unchanged, new or removed.\n * These functions no-op if no special formatting should be applied\n * and otherwise apply the appropriate formatting/coloring.\n * (@see {@link CodeSnippetFormatter})\n *\n * @see {@link showCopyPasteInstructions} for the helper with which to display the snippet in the console.\n *\n * @returns a string containing the final, formatted code snippet.\n */\nexport function makeCodeSnippet(\n colors: boolean,\n callback: CodeSnippetFormatter,\n): string {\n const unchanged = (txt: string) => (colors ? chalk.grey(txt) : txt);\n const plus = (txt: string) => (colors ? chalk.greenBright(txt) : txt);\n const minus = (txt: string) => (colors ? chalk.redBright(txt) : txt);\n\n return callback(unchanged, plus, minus);\n}\n\n/**\n * Creates a new config file with the given @param filepath and @param codeSnippet.\n *\n * Use this function to create a new config file for users. This is useful\n * when users answered that they don't yet have a config file for a tool.\n *\n * (This doesn't mean that they don't yet have some other way of configuring\n * their tool but we can leave it up to them to figure out how to merge configs\n * here.)\n *\n * @param filepath absolute path to the new config file\n * @param codeSnippet the snippet to be inserted into the file\n * @param moreInformation (optional) the message to be printed after the file was created\n * For example, this can be a link to more information about configuring the tool.\n *\n * @returns true on success, false otherwise\n */\nexport async function createNewConfigFile(\n filepath: string,\n codeSnippet: string,\n moreInformation?: string,\n): Promise<boolean> {\n if (!isAbsolute(filepath)) {\n debug(`createNewConfigFile: filepath is not absolute: ${filepath}`);\n return false;\n }\n\n const prettyFilename = chalk.cyan(relative(process.cwd(), filepath));\n\n try {\n await fs.promises.writeFile(filepath, codeSnippet);\n\n clack.log.success(`Added new ${prettyFilename} file.`);\n\n if (moreInformation) {\n clack.log.info(chalk.gray(moreInformation));\n }\n\n return true;\n } catch (e) {\n debug(e);\n clack.log.warn(\n `Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`,\n );\n }\n\n return false;\n}\n\nexport async function askShouldCreateExamplePage(\n customRoute?: string,\n): Promise<boolean> {\n const route = chalk.cyan(customRoute ?? '/sentry-example-page');\n return traceStep('ask-create-example-page', () =>\n abortIfCancelled(\n clack.select({\n message: `Do you want to create an example page (\"${route}\") to test your Sentry setup?`,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended - Check your git status before committing!',\n },\n { value: false, label: 'No' },\n ],\n }),\n ),\n );\n}\n\nexport async function askShouldCreateExampleComponent(): Promise<boolean> {\n return traceStep('ask-create-example-component', () =>\n abortIfCancelled(\n clack.select({\n message: `Do you want to create an example component to test your Sentry setup?`,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended - Check your git status before committing!',\n },\n { value: false, label: 'No' },\n ],\n }),\n ),\n );\n}\n\nexport async function featureSelectionPrompt<F extends ReadonlyArray<Feature>>(\n features: F,\n): Promise<{ [key in F[number]['id']]: boolean }> {\n return traceStep('feature-selection', async () => {\n const selectedFeatures: Record<string, boolean> = {};\n\n for (const feature of features) {\n const selected = await abortIfCancelled(\n clack.select({\n message: feature.prompt,\n initialValue: true,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: feature.enabledHint,\n },\n {\n value: false,\n label: 'No',\n hint: feature.disabledHint,\n },\n ],\n }),\n );\n\n selectedFeatures[feature.id] = selected;\n }\n\n return selectedFeatures as { [key in F[number]['id']]: boolean };\n });\n}\n\nexport async function askShouldInstallPackage(\n pkgName: string,\n): Promise<boolean> {\n return traceStep(`ask-install-package`, () =>\n abortIfCancelled(\n clack.confirm({\n message: `Do you want to install ${chalk.cyan(pkgName)}?`,\n }),\n ),\n );\n}\n\nexport async function askShouldAddPackageOverride(\n pkgName: string,\n pkgVersion: string,\n): Promise<boolean> {\n return traceStep(`ask-add-package-override`, () =>\n abortIfCancelled(\n clack.confirm({\n message: `Do you want to add an override for ${chalk.cyan(\n pkgName,\n )} version ${chalk.cyan(pkgVersion)}?`,\n }),\n ),\n );\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/clack/index.ts"],"names":[],"mappings":"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","sourcesContent":["import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { basename, isAbsolute, join, relative } from 'node:path';\nimport { setInterval } from 'node:timers';\nimport { URL } from 'node:url';\nimport * as path from 'path';\nimport { NPM } from '../../utils/package-manager';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as Sentry from '@sentry/node';\nimport axios from 'axios';\nimport chalk from 'chalk';\nimport opn from 'opn';\nimport { traceStep } from '../../telemetry';\nimport { WIZARD_VERSION } from '../../version';\nimport { debug } from '../debug';\nimport { type PackageDotJson, hasPackageInstalled } from '../package-json';\nimport {\n type PackageManager,\n _detectPackageManger,\n packageManagers,\n} from '../package-manager';\nimport { fulfillsVersionRange } from '../semver';\nimport type { Feature, SentryProjectData, WizardOptions } from '../types';\nimport { getUncommittedOrUntrackedFiles, isInGitRepo } from '../git';\n\nexport const SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';\nexport const SENTRY_CLI_RC_FILE = '.sentryclirc';\nexport const SENTRY_PROPERTIES_FILE = 'sentry.properties';\n\nconst SAAS_URL = 'https://sentry.io/';\n\nconst DUMMY_AUTH_TOKEN = '_YOUR_SENTRY_AUTH_TOKEN_';\n\ninterface WizardProjectData {\n apiKeys?: {\n token?: string;\n };\n projects?: SentryProjectData[];\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\nexport const rcCliSetupConfig: CliSetupConfig = {\n filename: SENTRY_CLI_RC_FILE,\n name: 'source maps',\n gitignore: true,\n likelyAlreadyHasAuthToken: function (contents: string): boolean {\n return !!(contents.includes('[auth]') && contents.match(/token=./g));\n },\n tokenContent: function (authToken: string): string {\n return `[auth]\\ntoken=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject: function (contents: string): boolean {\n return !!(\n contents.includes('[defaults]') &&\n contents.match(/org=./g) &&\n contents.match(/project=./g)\n );\n },\n orgAndProjContent: function (org: string, project: string): string {\n return `[defaults]\\norg=${org}\\nproject=${project}`;\n },\n};\n\nexport const propertiesCliSetupConfig: Required<CliSetupConfig> = {\n filename: SENTRY_PROPERTIES_FILE,\n gitignore: true,\n name: 'debug files',\n likelyAlreadyHasAuthToken(contents: string): boolean {\n return !!contents.match(/auth\\.token=./g);\n },\n tokenContent(authToken: string): string {\n return `auth.token=${authToken}`;\n },\n likelyAlreadyHasOrgAndProject(contents: string): boolean {\n return !!(\n contents.match(/defaults\\.org=./g) &&\n contents.match(/defaults\\.project=./g)\n );\n },\n orgAndProjContent(org: string, project: string): string {\n return `defaults.org=${org}\\ndefaults.project=${project}`;\n },\n likelyAlreadyHasUrl(contents: string): boolean {\n return !!contents.match(/defaults\\.url=./g);\n },\n urlContent(url: string): string {\n return `defaults.url=${url}`;\n },\n};\n\n/**\n * Aborts the wizard and sets the Sentry transaction status to `cancelled` or `aborted`.\n *\n * @param message The message to display to the user.\n * @param status The status to set on the Sentry transaction. Defaults to `1`.\n */\nexport async function abort(message?: string, status?: number): Promise<never> {\n clack.outro(message ?? 'Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n // 'cancelled' doesn't increase the `failureRate()` shown in the Sentry UI\n // 'aborted' increases the failure rate\n // see: https://docs.sentry.io/product/insights/overview/metrics/#failure-rate\n sentryTransaction?.setStatus(status === 0 ? 'cancelled' : 'aborted');\n sentryTransaction?.finish();\n const sentrySession = sentryHub.getScope().getSession();\n if (sentrySession) {\n sentrySession.status = status === 0 ? 'abnormal' : 'crashed';\n sentryHub.captureSession(true);\n }\n await Sentry.flush(3000);\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n): Promise<Exclude<T, symbol>> {\n if (clack.isCancel(await input)) {\n clack.cancel('Wizard setup cancelled.');\n const sentryHub = Sentry.getCurrentHub();\n const sentryTransaction = sentryHub.getScope().getTransaction();\n sentryTransaction?.setStatus('cancelled');\n sentryTransaction?.finish();\n sentryHub.captureSession(true);\n await Sentry.flush(3000);\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: {\n wizardName: string;\n promoCode?: string;\n message?: string;\n telemetryEnabled?: boolean;\n}): void {\n // eslint-disable-next-line no-console\n console.log('');\n clack.intro(chalk.inverse(` ${options.wizardName} `));\n\n let welcomeText =\n options.message ||\n `The ${options.wizardName} will help you set up Sentry for your application.\\nThank you for using Sentry :)`;\n\n if (options.promoCode) {\n welcomeText = `${welcomeText}\\n\\nUsing promo-code: ${options.promoCode}`;\n }\n\n welcomeText = `${welcomeText}\\n\\nVersion: ${WIZARD_VERSION}`;\n\n if (options.telemetryEnabled) {\n welcomeText = `${welcomeText}\n\nThis wizard sends telemetry data and crash reports to Sentry. This helps us improve the Wizard.\nYou can turn this off at any time by running ${chalk.cyanBright(\n 'sentry-wizard --disable-telemetry',\n )}.`;\n }\n\n clack.note(welcomeText);\n}\n\n/**\n * Confirms if the user wants to continue with the wizard if the project is not a git repository.\n *\n * @param options.ignoreGitChanges If true, the wizard will not check if the project is a git repository.\n * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.\n */\nexport async function confirmContinueIfNoOrDirtyGitRepo(options: {\n ignoreGitChanges: boolean | undefined;\n cwd: string | undefined;\n}): Promise<void> {\n return traceStep('check-git-status', async () => {\n if (\n !isInGitRepo({\n cwd: options.cwd,\n }) &&\n options.ignoreGitChanges !== true\n ) {\n const continueWithoutGit = await abortIfCancelled(\n clack.confirm({\n message:\n 'You are not inside a git repository. The wizard will create and update files. Do you want to continue anyway?',\n }),\n );\n\n Sentry.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n // return early to avoid checking for uncommitted files\n return;\n }\n\n const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();\n if (\n uncommittedOrUntrackedFiles.length &&\n options.ignoreGitChanges !== true\n ) {\n clack.log.warn(\n `You have uncommitted or untracked files in your repo:\n\n${uncommittedOrUntrackedFiles.join('\\n')}\n\nThe wizard will create and update files.`,\n );\n const continueWithDirtyRepo = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n\n Sentry.setTag('continue-with-dirty-repo', continueWithDirtyRepo);\n\n if (!continueWithDirtyRepo) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function askToInstallSentryCLI(): Promise<boolean> {\n return await abortIfCancelled(\n clack.confirm({\n message:\n \"You don't have Sentry CLI installed. Do you want to install it?\",\n }),\n );\n}\n\nexport async function askForItemSelection(\n items: string[],\n message: string,\n): Promise<{ value: string; index: number }> {\n const selection: { value: string; index: number } | symbol =\n await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection;\n}\n\nexport async function confirmContinueIfPackageVersionNotSupported({\n packageId,\n packageName,\n packageVersion,\n acceptableVersions,\n note,\n}: {\n packageId: string;\n packageName: string;\n packageVersion: string;\n acceptableVersions: string;\n note?: string;\n}): Promise<void> {\n return traceStep(`check-package-version`, async () => {\n Sentry.setTag(`${packageName.toLowerCase()}-version`, packageVersion);\n const isSupportedVersion = fulfillsVersionRange({\n acceptableVersions,\n version: packageVersion,\n canBeLatest: true,\n });\n\n if (isSupportedVersion) {\n Sentry.setTag(`${packageName.toLowerCase()}-supported`, true);\n return;\n }\n\n clack.log.warn(\n `You have an unsupported version of ${packageName} installed:\n\n ${packageId}@${packageVersion}`,\n );\n\n clack.note(\n note ??\n `Please upgrade to ${acceptableVersions} if you wish to use the Sentry Wizard.`,\n );\n const continueWithUnsupportedVersion = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n Sentry.setTag(\n `${packageName.toLowerCase()}-continue-with-unsupported-version`,\n continueWithUnsupportedVersion,\n );\n\n if (!continueWithUnsupportedVersion) {\n await abort(undefined, 0);\n }\n });\n}\n\ntype InstallPackageOptions = {\n /** The string that is passed to the package manager CLI as identifier to install (e.g. `@sentry/nextjs`, or `@sentry/nextjs@^8`) */\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n /** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly (e.g. `@sentry/nextjs@^8`) */\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n /** Add force install flag to command to skip install precondition fails */\n forceInstall?: boolean;\n /** Install as a dev dependency (@default: false) */\n devDependency?: boolean;\n};\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n packageNameDisplayLabel,\n packageManager,\n forceInstall = false,\n devDependency = false,\n}: InstallPackageOptions): Promise<{ packageManager?: PackageManager }> {\n return traceStep('install-package', async () => {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n clack.confirm({\n message: `The ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return {};\n }\n }\n\n const sdkInstallSpinner = clack.spinner();\n\n const pkgManager = packageManager || (await getPackageManager());\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n try {\n await new Promise<void>((resolve, reject) => {\n const installArgs = [\n pkgManager.installCommand,\n ...(devDependency ? ['-D'] : []),\n pkgManager.registry\n ? `${pkgManager.registry}:${packageName}`\n : packageName,\n ...(pkgManager.flags ? pkgManager.flags.split(' ') : []),\n ...(forceInstall ? [pkgManager.forceInstallFlag] : []),\n ];\n\n const stringifiedInstallCmd = `${pkgManager.name} ${installArgs.join(\n ' ',\n )}`;\n\n function handleErrorAndReject(\n code: number | null,\n cause: Error | string,\n type: 'spawn_error' | 'process_error',\n ) {\n // Write a log file so we can better troubleshoot issues\n fs.writeFileSync(\n join(\n process.cwd(),\n `sentry-wizard-installation-error-${Date.now()}.log`,\n ),\n stderr,\n { encoding: 'utf8' },\n );\n\n Sentry.captureException('Package Installation Error', {\n tags: {\n 'install-command': stringifiedInstallCmd,\n 'package-manager': pkgManager.name,\n 'package-name': packageName,\n 'error-type': type,\n },\n });\n\n reject(\n new Error(\n `Installation command ${chalk.cyan(\n stringifiedInstallCmd,\n )} exited with code ${code ?? 'null'}.`,\n {\n cause,\n },\n ),\n );\n }\n\n const installProcess = childProcess.spawn(\n pkgManager.name,\n installArgs,\n {\n shell: true,\n // Ignoring `stdout` to prevent certain node + yarn v4 (observed on ubuntu + snap)\n // combinations from crashing here. See #851\n stdio: ['pipe', 'ignore', 'pipe'],\n },\n );\n\n let stderr = '';\n\n // Defining data as unknown to avoid TS and ESLint errors because of `any` type\n installProcess.stderr.on('data', (data: unknown) => {\n if (data && data.toString && typeof data.toString === 'function') {\n stderr += data.toString();\n }\n });\n\n installProcess.on('error', (err) => {\n handleErrorAndReject(null, err, 'spawn_error');\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n handleErrorAndReject(code, stderr, 'process_error');\n } else {\n resolve();\n }\n });\n });\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n clack.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n \"The wizard has created a `sentry-wizard-installation-error-*.log` file. If you think this issue is caused by the Sentry wizard, create an issue on GitHub and include the log file's content:\\nhttps://github.com/getsentry/sentry-wizard/issues\",\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n return { packageManager: pkgManager };\n });\n}\n\nexport async function addSentryCliConfig(\n { authToken, org, project, url }: CliSetupConfigContent,\n setupConfig: CliSetupConfig = rcCliSetupConfig,\n): Promise<void> {\n return traceStep('add-sentry-cli-config', async () => {\n const configPath = join(process.cwd(), setupConfig.filename);\n const configExists = fs.existsSync(configPath);\n\n let configContents =\n (configExists && fs.readFileSync(configPath, 'utf8')) || '';\n configContents = addAuthTokenToSentryConfig(\n configContents,\n authToken,\n setupConfig,\n );\n configContents = addOrgAndProjectToSentryConfig(\n configContents,\n org,\n project,\n setupConfig,\n );\n configContents = addUrlToSentryConfig(configContents, url, setupConfig);\n\n try {\n await fs.promises.writeFile(configPath, configContents, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `${configExists ? 'Saved' : 'Created'} ${chalk.cyan(\n setupConfig.filename,\n )}.`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.cyan(\n setupConfig.filename,\n )}. Uploading ${\n setupConfig.name\n } during build will likely not work locally.`,\n );\n }\n\n if (setupConfig.gitignore) {\n await addCliConfigFileToGitIgnore(setupConfig.filename);\n } else {\n clack.log.warn(\n chalk.yellow('DO NOT commit auth token to your repository!'),\n );\n }\n });\n}\n\nfunction addAuthTokenToSentryConfig(\n configContents: string,\n authToken: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!authToken) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasAuthToken(configContents)) {\n clack.log.warn(\n `${chalk.cyan(\n setupConfig.filename,\n )} already has auth token. Will not add one.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.tokenContent(\n authToken,\n )}\\n`;\n clack.log.success(\n `Added auth token to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nfunction addOrgAndProjectToSentryConfig(\n configContents: string,\n org: string | undefined,\n project: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!org || !project) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasOrgAndProject(configContents)) {\n clack.log.warn(\n `${chalk.cyan(\n setupConfig.filename,\n )} already has org and project. Will not add them.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.orgAndProjContent(\n org,\n project,\n )}\\n`;\n clack.log.success(\n `Added default org and project to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nfunction addUrlToSentryConfig(\n configContents: string,\n url: string | undefined,\n setupConfig: CliSetupConfig,\n): string {\n if (!url || !setupConfig.urlContent || !setupConfig.likelyAlreadyHasUrl) {\n return configContents;\n }\n\n if (setupConfig.likelyAlreadyHasUrl(configContents)) {\n clack.log.warn(\n `${chalk.cyan(setupConfig.filename)} already has url. Will not add one.`,\n );\n return configContents;\n }\n\n const newContents = `${configContents}\\n${setupConfig.urlContent(url)}\\n`;\n clack.log.success(\n `Added default url to ${chalk.cyan(\n setupConfig.filename,\n )} for you to test uploading ${setupConfig.name} locally.`,\n );\n return newContents;\n}\n\nexport async function addDotEnvSentryBuildPluginFile(\n authToken: string,\n): Promise<void> {\n const envVarContent = `# DO NOT commit this file to your repository!\n# The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin.\n# It's used for authentication when uploading source maps.\n# You can also set this env variable in your own \\`.env\\` files and remove this file.\nSENTRY_AUTH_TOKEN=${authToken}\n`;\n\n const dotEnvFilePath = join(process.cwd(), SENTRY_DOT_ENV_FILE);\n const dotEnvFileExists = fs.existsSync(dotEnvFilePath);\n\n if (dotEnvFileExists) {\n const dotEnvFileContent = fs.readFileSync(dotEnvFilePath, 'utf8');\n\n const hasAuthToken = !!dotEnvFileContent.match(\n /^\\s*SENTRY_AUTH_TOKEN\\s*=/g,\n );\n\n if (hasAuthToken) {\n clack.log.warn(\n `${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} already has auth token. Will not add one.`,\n );\n } else {\n try {\n await fs.promises.writeFile(\n dotEnvFilePath,\n `${dotEnvFileContent}\\n${envVarContent}`,\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n clack.log.success(\n `Added auth token to ${chalk.bold.cyan(SENTRY_DOT_ENV_FILE)}`,\n );\n } catch {\n clack.log.warning(\n `Failed to add auth token to ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )}. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n } else {\n try {\n await fs.promises.writeFile(dotEnvFilePath, envVarContent, {\n encoding: 'utf8',\n flag: 'w',\n });\n clack.log.success(\n `Created ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} with auth token for you to test source map uploading locally.`,\n );\n } catch {\n clack.log.warning(\n `Failed to create ${chalk.bold.cyan(\n SENTRY_DOT_ENV_FILE,\n )} with auth token. Uploading source maps during build will likely not work locally.`,\n );\n }\n }\n\n await addCliConfigFileToGitIgnore(SENTRY_DOT_ENV_FILE);\n}\n\nasync function addCliConfigFileToGitIgnore(filename: string): Promise<void> {\n const gitignorePath = join(process.cwd(), '.gitignore');\n\n try {\n const gitignoreContent = await fs.promises.readFile(gitignorePath, 'utf8');\n if (gitignoreContent.split(/\\r?\\n/).includes(filename)) {\n clack.log.info(\n `${chalk.bold('.gitignore')} already has ${chalk.bold(\n filename,\n )}. Will not add it again.`,\n );\n return;\n }\n\n await fs.promises.appendFile(\n gitignorePath,\n `\\n# Sentry Config File\\n${filename}\\n`,\n { encoding: 'utf8' },\n );\n clack.log.success(\n `Added ${chalk.cyan(filename)} to ${chalk.cyan('.gitignore')}.`,\n );\n } catch {\n clack.log.error(\n `Failed adding ${chalk.cyan(filename)} to ${chalk.cyan(\n '.gitignore',\n )}. Please add it manually!`,\n );\n }\n}\n\n/**\n * Runs prettier on the changed or untracked files in the project.\n *\n * @param options.cwd The directory of the project. If undefined, the current process working directory will be used.\n */\nexport async function runPrettierIfInstalled(opts: {\n cwd: string | undefined;\n}): Promise<void> {\n return traceStep('run-prettier', async () => {\n if (!isInGitRepo({ cwd: opts.cwd })) {\n // We only run formatting on changed files. If we're not in a git repo, we can't find\n // changed files. So let's early-return without showing any formatting-related messages.\n return;\n }\n\n const changedOrUntrackedFiles = getUncommittedOrUntrackedFiles()\n .map((filename) => {\n return filename.startsWith('- ') ? filename.slice(2) : filename;\n })\n .join(' ');\n\n if (!changedOrUntrackedFiles.length) {\n // Likewise, if we can't find changed or untracked files, there's no point in running Prettier.\n return;\n }\n\n const packageJson = await getPackageDotJson();\n const prettierInstalled = hasPackageInstalled('prettier', packageJson);\n\n Sentry.setTag('prettier-installed', prettierInstalled);\n\n if (!prettierInstalled) {\n return;\n }\n\n // prompt the user if they want to run prettier\n const shouldRunPrettier = await abortIfCancelled(\n clack.confirm({\n message:\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n }),\n );\n\n if (!shouldRunPrettier) {\n return;\n }\n\n const prettierSpinner = clack.spinner();\n prettierSpinner.start('Running Prettier on your files.');\n\n try {\n await new Promise<void>((resolve, reject) => {\n childProcess.exec(\n `npx prettier --ignore-unknown --write ${changedOrUntrackedFiles}`,\n (err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n },\n );\n });\n } catch (e) {\n prettierSpinner.stop('Prettier failed to run.');\n clack.log.warn(\n 'Prettier failed to run. There may be formatting issues in your updated files.',\n );\n return;\n }\n\n prettierSpinner.stop('Prettier has formatted your files.');\n });\n}\n\n/**\n * Checks if @param packageId is listed as a dependency in @param packageJson.\n * If not, it will ask users if they want to continue without the package.\n *\n * Use this function to check if e.g. a the framework of the SDK is installed\n *\n * @param packageJson the package.json object\n * @param packageId the npm name of the package\n * @param packageName a human readable name of the package\n */\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n): Promise<void> {\n return traceStep('ensure-package-installed', async () => {\n const installed = hasPackageInstalled(packageId, packageJson);\n\n Sentry.setTag(`${packageName.toLowerCase()}-installed`, installed);\n\n if (!installed) {\n Sentry.setTag(`${packageName.toLowerCase()}-installed`, false);\n const continueWithoutPackage = await abortIfCancelled(\n clack.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function getPackageDotJson(): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises\n .readFile(join(process.cwd(), 'package.json'), 'utf8')\n .catch(() => {\n clack.log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n clack.log.error(\n `Unable to parse your ${chalk.cyan(\n 'package.json',\n )}. Make sure it has a valid format!`,\n );\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageDotJson,\n): Promise<void> {\n try {\n await fs.promises.writeFile(\n join(process.cwd(), 'package.json'),\n // TODO: maybe figure out the original indentation\n JSON.stringify(packageDotJson, null, 2),\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n } catch {\n clack.log.error(`Unable to update your ${chalk.cyan('package.json')}.`);\n\n await abort();\n }\n}\n\n/**\n * Use this function to get the used JS Package manager.\n *\n * This function:\n * - attempts to auto-detect the used package manager and return it\n * - if unsuccessful, returns the passed fallback package manager\n * - if no fallback is passed, it asks the user to select a package manager\n *\n * The result is cached on the first invocation to avoid asking the user multiple times.\n *\n * @param fallback the package manager to use if auto-detection fails and you don't want to\n * ask the user. This is useful in cases where asking users would be too intrusive/low in value\n * and where it's okay to fall back to a default package manager. Use this with caution.\n */\nexport async function getPackageManager(\n fallback?: PackageManager,\n): Promise<PackageManager> {\n const globalWithSentryWizard: typeof global & {\n __sentry_wizard_cached_package_manager?: PackageManager;\n } = global;\n\n if (globalWithSentryWizard.__sentry_wizard_cached_package_manager) {\n return globalWithSentryWizard.__sentry_wizard_cached_package_manager;\n }\n\n const detectedPackageManager = _detectPackageManger();\n\n if (detectedPackageManager) {\n globalWithSentryWizard.__sentry_wizard_cached_package_manager =\n detectedPackageManager;\n return detectedPackageManager;\n }\n\n if (fallback) {\n // explicitly avoiding to cache the fallback in case this function\n // gets called again without a fallback (or a different fallback)\n // later on in the wizard flow.\n return fallback;\n }\n\n const selectedPackageManager: PackageManager | symbol =\n await abortIfCancelled(\n clack.select({\n message: 'Please select your package manager.',\n options: packageManagers.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n globalWithSentryWizard.__sentry_wizard_cached_package_manager =\n selectedPackageManager;\n\n Sentry.setTag('package-manager', selectedPackageManager.name);\n\n return selectedPackageManager;\n}\n\nexport function isUsingTypeScript() {\n try {\n return fs.existsSync(join(process.cwd(), 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Checks if we already got project data from a previous wizard invocation.\n * If yes, this data is returned.\n * Otherwise, we start the login flow and ask the user to select a project.\n *\n * Use this function to get project data for the wizard.\n *\n * @param options wizard options\n * @param platform the platform of the wizard\n * @returns project data (org, project, token, url)\n */\nexport async function getOrAskForProjectData(\n options: WizardOptions,\n platform?:\n | 'javascript-angular'\n | 'javascript-nextjs'\n | 'javascript-nuxt'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android'\n | 'react-native'\n | 'flutter',\n): Promise<{\n sentryUrl: string;\n selfHosted: boolean;\n selectedProject: SentryProjectData;\n authToken: string;\n}> {\n if (options.preSelectedProject) {\n return {\n selfHosted: options.preSelectedProject.selfHosted,\n sentryUrl: options.url ?? SAAS_URL,\n authToken: options.preSelectedProject.authToken,\n selectedProject: options.preSelectedProject.project,\n };\n }\n const { url: sentryUrl, selfHosted } = await traceStep(\n 'ask-self-hosted',\n () => askForSelfHosted(options.url, options.saas),\n );\n\n const { projects, apiKeys } = await traceStep('login', () =>\n askForWizardLogin({\n promoCode: options.promoCode,\n url: sentryUrl,\n platform: platform,\n orgSlug: options.orgSlug,\n projectSlug: options.projectSlug,\n comingFrom: options.comingFrom,\n }),\n );\n\n if (!projects || !projects.length) {\n clack.log.error(\n 'No projects found. Please create a project in Sentry and try again.',\n );\n Sentry.setTag('no-projects-found', true);\n await abort();\n // This rejection won't return due to the abort call but TS doesn't know that\n return Promise.reject();\n }\n\n const selectedProject = await traceStep('select-project', () =>\n askForProjectSelection(projects, options.orgSlug, options.projectSlug),\n );\n\n const { token } = apiKeys ?? {};\n\n if (!token) {\n clack.log.error(`Didn't receive an auth token. This shouldn't happen :(\n\nPlease let us know if you think this is a bug in the wizard:\n${chalk.cyan('https://github.com/getsentry/sentry-wizard/issues')}`);\n\n clack.log.info(`In the meantime, we'll add a dummy auth token (${chalk.cyan(\n `\"${DUMMY_AUTH_TOKEN}\"`,\n )}) for you to replace later.\nCreate your auth token here:\n${chalk.cyan(\n selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/settings/auth-tokens`\n : `https://${selectedProject.organization.slug}.sentry.io/settings/auth-tokens`,\n)}`);\n }\n\n return {\n sentryUrl,\n selfHosted,\n authToken: apiKeys?.token || DUMMY_AUTH_TOKEN,\n selectedProject,\n };\n}\n\n/**\n * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.\n *\n * If users started the wizard with a --url arg, that URL is used as the default and we skip\n * the self-hosted question. However, the passed url is still validated and in case it's\n * invalid, users are asked to enter a new one until it is valid.\n *\n * @param urlFromArgs the url passed via the --url arg\n */\nasync function askForSelfHosted(\n urlFromArgs?: string,\n saas?: boolean,\n): Promise<{\n url: string;\n selfHosted: boolean;\n}> {\n if (saas) {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n\n if (!urlFromArgs) {\n const choice: 'saas' | 'self-hosted' | symbol = await abortIfCancelled(\n clack.select({\n message: 'Are you using Sentry SaaS or self-hosted Sentry?',\n options: [\n { value: 'saas', label: 'Sentry SaaS (sentry.io)' },\n {\n value: 'self-hosted',\n label: 'Self-hosted/on-premise/single-tenant',\n },\n ],\n }),\n );\n\n if (choice === 'saas') {\n Sentry.setTag('url', SAAS_URL);\n Sentry.setTag('self-hosted', false);\n return { url: SAAS_URL, selfHosted: false };\n }\n }\n\n let validUrl: string | undefined;\n let tmpUrlFromArgs = urlFromArgs;\n\n while (validUrl === undefined) {\n const url =\n tmpUrlFromArgs ||\n (await abortIfCancelled(\n clack.text({\n message: `Please enter the URL of your ${\n urlFromArgs ? '' : 'self-hosted '\n }Sentry instance.`,\n placeholder: 'https://sentry.io/',\n }),\n ));\n tmpUrlFromArgs = undefined;\n\n try {\n validUrl = new URL(url).toString();\n\n // We assume everywhere else that the URL ends in a slash\n if (!validUrl.endsWith('/')) {\n validUrl += '/';\n }\n } catch {\n clack.log.error(\n `Please enter a valid URL. (It should look something like \"https://sentry.mydomain.com/\", got ${url})`,\n );\n }\n }\n\n const isSelfHostedUrl = new URL(validUrl).host !== new URL(SAAS_URL).host;\n\n Sentry.setTag('url', validUrl);\n Sentry.setTag('self-hosted', isSelfHostedUrl);\n\n return { url: validUrl, selfHosted: true };\n}\n\n/**\n * Exported for testing\n */\nexport async function askForWizardLogin(options: {\n url: string;\n promoCode?: string;\n platform?:\n | 'javascript-angular'\n | 'javascript-nextjs'\n | 'javascript-nuxt'\n | 'javascript-remix'\n | 'javascript-sveltekit'\n | 'apple-ios'\n | 'android'\n | 'react-native'\n | 'flutter';\n orgSlug?: string;\n projectSlug?: string;\n comingFrom?: string;\n}): Promise<WizardProjectData> {\n const { orgSlug, projectSlug, url, platform, promoCode, comingFrom } =\n options;\n\n Sentry.setTag('has-promo-code', !!promoCode);\n\n const projectAndOrgPreselected = !!(orgSlug && projectSlug);\n\n const hasSentryAccount =\n projectAndOrgPreselected || (await askHasSentryAccount());\n\n Sentry.setTag('already-has-sentry-account', hasSentryAccount);\n\n const wizardHash = await makeInitialWizardHashRequest(url);\n\n const loginUrl = new URL(`${url}account/settings/wizard/${wizardHash}/`);\n\n if (orgSlug) {\n loginUrl.searchParams.set('org_slug', orgSlug);\n }\n\n if (projectSlug) {\n loginUrl.searchParams.set('project_slug', projectSlug);\n }\n\n if (!hasSentryAccount) {\n loginUrl.searchParams.set('signup', '1');\n }\n\n if (platform) {\n loginUrl.searchParams.set('project_platform', platform);\n }\n\n if (promoCode) {\n loginUrl.searchParams.set('code', promoCode);\n }\n\n if (comingFrom) {\n loginUrl.searchParams.set('partner', comingFrom);\n }\n\n const urlToOpen = loginUrl.toString();\n clack.log.info(\n `${chalk.bold(\n `If the browser window didn't open automatically, please open the following link to ${\n hasSentryAccount ? 'log' : 'sign'\n } into Sentry:`,\n )}\\n\\n${chalk.cyan(urlToOpen)}`,\n );\n\n // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here\n const noop = () => {}; // eslint-disable-line @typescript-eslint/no-empty-function\n opn(urlToOpen, { wait: false }).then((cp) => cp.on('error', noop), noop);\n\n const loginSpinner = clack.spinner();\n\n loginSpinner.start('Waiting for you to log in using the link above');\n\n const data = await new Promise<WizardProjectData>((resolve) => {\n const pollingInterval = setInterval(() => {\n axios\n .get<WizardProjectData>(`${url}api/0/wizard/${wizardHash}/`, {\n headers: {\n 'Accept-Encoding': 'deflate',\n },\n })\n .then((result) => {\n resolve(result.data);\n clearTimeout(timeout);\n clearInterval(pollingInterval);\n void axios.delete(`${url}api/0/wizard/${wizardHash}/`);\n })\n .catch(() => {\n // noop - just try again\n });\n }, 500);\n\n const timeout = setTimeout(() => {\n clearInterval(pollingInterval);\n loginSpinner.stop(\n 'Login timed out. No worries - it happens to the best of us.',\n );\n\n Sentry.setTag('opened-wizard-link', false);\n void abort('Please restart the Wizard and log in to complete the setup.');\n }, 180_000);\n });\n\n loginSpinner.stop('Login complete.');\n Sentry.setTag('opened-wizard-link', true);\n\n return data;\n}\n\n/**\n * This first request to Sentry creates a cache on the Sentry backend whose key is returned.\n * We use this key later on to poll for the actual project data.\n */\nasync function makeInitialWizardHashRequest(url: string): Promise<string> {\n const reqUrl = `${url}api/0/wizard/`;\n try {\n return (await axios.get<{ hash: string }>(reqUrl)).data.hash;\n } catch (e: unknown) {\n if (url !== SAAS_URL) {\n clack.log.error(\n `Loading Wizard failed. Did you provide the right URL? (url: ${reqUrl})`,\n );\n clack.log.info(JSON.stringify(e, null, 2));\n await abort(\n chalk.red(\n 'Please check your configuration and try again.\\n\\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n } else {\n clack.log.error('Loading Wizard failed.');\n clack.log.info(JSON.stringify(e, null, 2));\n await abort(\n chalk.red(\n 'Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues',\n ),\n );\n }\n }\n\n // We don't get here as we abort in an error case but TS doesn't know that\n return 'invalid hash';\n}\n\nasync function askHasSentryAccount(): Promise<boolean> {\n const hasSentryAccount = await clack.confirm({\n message: 'Do you already have a Sentry account?',\n });\n\n return abortIfCancelled(hasSentryAccount);\n}\n\nasync function askForProjectSelection(\n projects: SentryProjectData[],\n orgSlug?: string,\n projectSlug?: string,\n): Promise<SentryProjectData> {\n const label = (project: SentryProjectData): string => {\n return `${project.organization.slug}/${project.slug}`;\n };\n\n const filteredProjects = filterProjectsBySlugs(\n projects,\n orgSlug,\n projectSlug,\n );\n\n if (filteredProjects.length === 1) {\n const selection = filteredProjects[0];\n\n Sentry.setTag('project', selection.slug);\n Sentry.setUser({ id: selection.organization.slug });\n clack.log.step(`Selected project ${label(selection)}`);\n\n return selection;\n }\n\n if (filteredProjects.length === 0) {\n clack.log.warn('Could not find a project with the provided slugs.');\n }\n\n const sortedProjects = filteredProjects.length ? filteredProjects : projects;\n sortedProjects.sort((a: SentryProjectData, b: SentryProjectData) => {\n return label(a).localeCompare(label(b));\n });\n\n const selection: SentryProjectData | symbol = await abortIfCancelled(\n clack.select({\n maxItems: 12,\n message: 'Select your Sentry project.',\n options: sortedProjects.map((project) => {\n return {\n value: project,\n label: label(project),\n };\n }),\n }),\n );\n\n Sentry.setTag('project', selection.slug);\n Sentry.setUser({ id: selection.organization.slug });\n\n return selection;\n}\n\nfunction filterProjectsBySlugs(\n projects: SentryProjectData[],\n orgSlug?: string,\n projectSlug?: string,\n): SentryProjectData[] {\n if (!orgSlug && !projectSlug) {\n return projects;\n }\n if (orgSlug && !projectSlug) {\n return projects.filter((p) => p.organization.slug === orgSlug);\n }\n if (!orgSlug && projectSlug) {\n return projects.filter((p) => p.slug === projectSlug);\n }\n\n return projects.filter(\n (p) => p.organization.slug === orgSlug && p.slug === projectSlug,\n );\n}\n\n/**\n * Asks users if they have a config file for @param tool (e.g. Vite).\n * If yes, asks users to specify the path to their config file.\n *\n * Use this helper function as a fallback mechanism if the lookup for\n * a config file with its most usual location/name fails.\n *\n * @param toolName Name of the tool for which we're looking for the config file\n * @param configFileName Name of the most common config file name (e.g. vite.config.js)\n *\n * @returns a user path to the config file or undefined if the user doesn't have a config file\n */\nexport async function askForToolConfigPath(\n toolName: string,\n configFileName: string,\n): Promise<string | undefined> {\n const hasConfig = await abortIfCancelled(\n clack.confirm({\n message: `Do you have a ${toolName} config file (e.g. ${chalk.cyan(\n configFileName,\n )})?`,\n initialValue: true,\n }),\n );\n\n if (!hasConfig) {\n return undefined;\n }\n\n return await abortIfCancelled(\n clack.text({\n message: `Please enter the path to your ${toolName} config file:`,\n placeholder: join('.', configFileName),\n validate: (value) => {\n if (!value) {\n return 'Please enter a path.';\n }\n\n try {\n fs.accessSync(value);\n } catch {\n return 'Could not access the file at this path.';\n }\n },\n }),\n );\n}\n\ntype ShowCopyPasteInstructionsOptions = { codeSnippet: string } & (\n | {\n filename: string;\n hint?: string;\n }\n | {\n instructions: string;\n }\n);\n\n/**\n * Prints copy/paste-able instructions to the console.\n * Afterwards asks the user if they added the code snippet to their file.\n *\n * While there's no point in providing a \"no\" answer here, it gives users time to fulfill the\n * task before the wizard continues with additional steps.\n *\n * Use this function if you want to show users instructions on how to add/modify\n * code in their file. This is helpful if automatic insertion failed or is not possible/feasible.\n *\n * @param filename the name of the file to which the code snippet should be applied.\n * If a path is provided, only the filename will be used.\n *\n * @param codeSnippet the snippet to be printed. Use {@link makeCodeSnippet} to create the\n * diff-like format for visually highlighting unchanged or modified lines of code.\n *\n * @param hint (optional) a hint to be printed after the main instruction to add\n * the code from @param codeSnippet to their @param filename.\n *\n * More guidelines on copy/paste instructions:\n * @see {@link https://develop.sentry.dev/sdk/setup-wizards/#copy--paste-snippets}\n *\n * TODO: refactor copy paste instructions across different wizards to use this function.\n * this might require adding a custom message parameter to the function\n */\nexport async function showCopyPasteInstructions(\n opts: ShowCopyPasteInstructionsOptions,\n): Promise<void> {\n if ('instructions' in opts) {\n clack.log.step(opts.instructions);\n } else {\n const defaultInstructions = `Add the following code to your ${chalk.cyan(\n basename(opts.filename),\n )} file:${opts.hint ? chalk.dim(` (${chalk.dim(opts.hint)})`) : ''}`;\n\n clack.log.step(defaultInstructions);\n }\n\n // Padding the code snippet to be printed with a \\n at the beginning and end\n // This makes it easier to distinguish the snippet from the rest of the output\n // Intentionally logging directly to console here so that the code can be copied/pasted directly\n // eslint-disable-next-line no-console\n console.log(`\\n${opts.codeSnippet}\\n`);\n\n await abortIfCancelled(\n clack.select({\n message: 'Did you apply the snippet above?',\n options: [{ label: 'Yes, continue!', value: true }],\n initialValue: true,\n }),\n );\n}\n\n/**\n * Callback that exposes formatting helpers for a code snippet.\n * @param unchanged - Formats text as old code.\n * @param plus - Formats text as new code.\n * @param minus - Formats text as removed code.\n */\ntype CodeSnippetFormatter = (\n unchanged: (txt: string) => string,\n plus: (txt: string) => string,\n minus: (txt: string) => string,\n) => string;\n\n/**\n * Crafts a code snippet that can be used to e.g.\n * - print copy/paste instructions to the console\n * - create a new config file.\n *\n * @param colors set this to true if you want the final snippet to be colored.\n * This is useful for printing the snippet to the console as part of copy/paste instructions.\n *\n * @param callback the callback that returns the formatted code snippet.\n * It exposes takes the helper functions for marking code as unchanged, new or removed.\n * These functions no-op if no special formatting should be applied\n * and otherwise apply the appropriate formatting/coloring.\n * (@see {@link CodeSnippetFormatter})\n *\n * @see {@link showCopyPasteInstructions} for the helper with which to display the snippet in the console.\n *\n * @returns a string containing the final, formatted code snippet.\n */\nexport function makeCodeSnippet(\n colors: boolean,\n callback: CodeSnippetFormatter,\n): string {\n const unchanged = (txt: string) => (colors ? chalk.grey(txt) : txt);\n const plus = (txt: string) => (colors ? chalk.greenBright(txt) : txt);\n const minus = (txt: string) => (colors ? chalk.redBright(txt) : txt);\n\n return callback(unchanged, plus, minus);\n}\n\n/**\n * Creates a new config file with the given @param filepath and @param codeSnippet.\n *\n * Use this function to create a new config file for users. This is useful\n * when users answered that they don't yet have a config file for a tool.\n *\n * (This doesn't mean that they don't yet have some other way of configuring\n * their tool but we can leave it up to them to figure out how to merge configs\n * here.)\n *\n * @param filepath absolute path to the new config file\n * @param codeSnippet the snippet to be inserted into the file\n * @param moreInformation (optional) the message to be printed after the file was created\n * For example, this can be a link to more information about configuring the tool.\n *\n * @returns true on success, false otherwise\n */\nexport async function createNewConfigFile(\n filepath: string,\n codeSnippet: string,\n moreInformation?: string,\n): Promise<boolean> {\n if (!isAbsolute(filepath)) {\n debug(`createNewConfigFile: filepath is not absolute: ${filepath}`);\n return false;\n }\n\n const prettyFilename = chalk.cyan(relative(process.cwd(), filepath));\n\n try {\n await fs.promises.writeFile(filepath, codeSnippet);\n\n clack.log.success(`Added new ${prettyFilename} file.`);\n\n if (moreInformation) {\n clack.log.info(chalk.gray(moreInformation));\n }\n\n return true;\n } catch (e) {\n debug(e);\n clack.log.warn(\n `Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`,\n );\n }\n\n return false;\n}\n\nexport async function askShouldCreateExamplePage(\n customRoute?: string,\n): Promise<boolean> {\n const route = chalk.cyan(customRoute ?? '/sentry-example-page');\n return traceStep('ask-create-example-page', () =>\n abortIfCancelled(\n clack.select({\n message: `Do you want to create an example page (\"${route}\") to test your Sentry setup?`,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended - Check your git status before committing!',\n },\n { value: false, label: 'No' },\n ],\n }),\n ),\n );\n}\n\nexport async function askShouldCreateExampleComponent(): Promise<boolean> {\n return traceStep('ask-create-example-component', () =>\n abortIfCancelled(\n clack.select({\n message: `Do you want to create an example component to test your Sentry setup?`,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: 'Recommended - Check your git status before committing!',\n },\n { value: false, label: 'No' },\n ],\n }),\n ),\n );\n}\n\nexport async function featureSelectionPrompt<F extends ReadonlyArray<Feature>>(\n features: F,\n): Promise<{ [key in F[number]['id']]: boolean }> {\n return traceStep('feature-selection', async () => {\n const selectedFeatures: Record<string, boolean> = {};\n\n for (const feature of features) {\n const selected = await abortIfCancelled(\n clack.select({\n message: feature.prompt,\n initialValue: true,\n options: [\n {\n value: true,\n label: 'Yes',\n hint: feature.enabledHint,\n },\n {\n value: false,\n label: 'No',\n hint: feature.disabledHint,\n },\n ],\n }),\n );\n\n selectedFeatures[feature.id] = selected;\n }\n\n return selectedFeatures as { [key in F[number]['id']]: boolean };\n });\n}\n\nexport async function askShouldInstallPackage(\n pkgName: string,\n): Promise<boolean> {\n return traceStep(`ask-install-package`, () =>\n abortIfCancelled(\n clack.confirm({\n message: `Do you want to install ${chalk.cyan(pkgName)}?`,\n }),\n ),\n );\n}\n\nexport async function askShouldAddPackageOverride(\n pkgName: string,\n pkgVersion: string,\n): Promise<boolean> {\n return traceStep(`ask-add-package-override`, () =>\n abortIfCancelled(\n clack.confirm({\n message: `Do you want to add an override for ${chalk.cyan(\n pkgName,\n )} version ${chalk.cyan(pkgVersion)}?`,\n }),\n ),\n );\n}\n\nasync function getBuildCommand(): Promise<string | null> {\n const packageDotJson = await getPackageDotJson();\n return typeof packageDotJson.scripts?.build === 'string' ? 'build' : null;\n}\n\nexport function artifactsExist(relativePath: string): boolean {\n return fs.existsSync(path.join(process.cwd(), relativePath));\n}\n\nexport async function askToRunBuildOrEnterPathOrProceed({\n relativeArtifactPath,\n}: {\n relativeArtifactPath: string;\n}): Promise<{ validPath: boolean; relativeArtifactPath?: string }> {\n const options: { label: string; value: string }[] = [];\n\n const buildCommand = await getBuildCommand();\n\n if (buildCommand) {\n options.push({\n label: 'Let the wizard run the build command',\n value: 'run-build',\n });\n }\n\n options.push(\n {\n label: 'Enter a different path manually',\n value: 'manual',\n },\n {\n label: 'Proceed anyway — I believe the path is correct',\n value: 'proceed',\n },\n );\n\n const whatToDo = await abortIfCancelled(\n clack.select({\n message: `We couldn't find build artifacts at \"${relativeArtifactPath}\". What would you like to do?`,\n options,\n initialValue: buildCommand ? 'run-build' : 'manual',\n }),\n );\n\n if (whatToDo === 'proceed') {\n return {\n validPath: true,\n };\n }\n\n if (whatToDo === 'run-build' && buildCommand) {\n const ranBuildAndCheckArtifacts = await runBuildAndCheckArtifacts(\n buildCommand,\n relativeArtifactPath,\n );\n\n if (ranBuildAndCheckArtifacts.validPath === false) {\n return await askToRunBuildOrEnterPathOrProceed({ relativeArtifactPath });\n }\n\n return ranBuildAndCheckArtifacts;\n }\n\n return {\n validPath: false,\n };\n}\n\nfunction getPossibleBuildFolders(): string[] {\n const commonBuildFolders = ['build', 'dist', 'out', '.next'];\n\n return commonBuildFolders.filter((folder) =>\n fs.existsSync(path.join(process.cwd(), folder)),\n );\n}\n\nasync function promptForAlternativeArtifactPath(): Promise<string | undefined> {\n const folders = getPossibleBuildFolders();\n\n if (!folders.length) {\n return undefined;\n }\n\n if (folders.length === 1) {\n const [onlyFolder] = folders;\n\n const confirmed = await abortIfCancelled(\n clack.select({\n message: `Detected one possible build folder. Use \"${onlyFolder}\" as your build artifacts folder?`,\n options: [\n {\n value: true,\n label: 'Yes',\n },\n { value: false, label: 'No' },\n ],\n }),\n );\n\n return confirmed ? onlyFolder : undefined;\n }\n\n const selected = await abortIfCancelled(\n clack.select({\n message: `Detected multiple possible build folders. Is one of these your build artifacts folder?`,\n options: [\n ...folders.map((f) => ({ value: f, label: f })),\n { value: false, label: 'No' },\n ],\n }),\n );\n\n if (selected) {\n return String(selected);\n }\n\n return undefined;\n}\n\nasync function runBuildCommand(buildCommand: string): Promise<boolean> {\n const packageManager = await getPackageManager(NPM);\n const command = `${packageManager.runScriptCommand} ${buildCommand}`;\n const spinner = clack.spinner();\n\n spinner.start(`Running ${chalk.cyan(command)}...`);\n try {\n execSync(command, {\n stdio: 'inherit',\n cwd: process.cwd(),\n });\n spinner.stop('Build finished running.');\n return true;\n } catch (error) {\n spinner.stop(\n `Build failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n clack.log.error(\n 'Failed to run your build command. Please run it manually and try again.',\n );\n return false;\n }\n}\n\nasync function runBuildAndCheckArtifacts(\n buildCommand: string,\n relativeArtifactPath: string,\n): Promise<{ validPath: boolean; relativeArtifactPath?: string }> {\n const buildRan = await runBuildCommand(buildCommand);\n\n if (!buildRan) {\n return { validPath: false };\n }\n\n const found = artifactsExist(relativeArtifactPath);\n\n if (found) {\n clack.log.success('Build completed and build artifacts folder found!');\n return { validPath: true };\n }\n\n clack.log.warn(\n `Build ran, but build artifacts folder still not found at ${relativeArtifactPath}.`,\n );\n\n const fallbackPath = await promptForAlternativeArtifactPath();\n\n if (!fallbackPath) {\n return { validPath: false };\n }\n\n return {\n validPath: artifactsExist(fallbackPath),\n relativeArtifactPath: fallbackPath,\n };\n}\n"]}
@@ -1 +1 @@
1
- export declare const WIZARD_VERSION = "5.3.0";
1
+ export declare const WIZARD_VERSION = "5.4.0";
@@ -3,5 +3,5 @@
3
3
  // This is file is updated at release time.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.WIZARD_VERSION = void 0;
6
- exports.WIZARD_VERSION = '5.3.0';
6
+ exports.WIZARD_VERSION = '5.4.0';
7
7
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '5.3.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '5.4.0';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wizard",
3
- "version": "5.3.0",
3
+ "version": "5.4.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",