From b419ceab4f615947a53a75207c13944ab65fdd18 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 10 Jul 2023 11:52:05 +0200 Subject: [PATCH 1/3] ref(sourcemaps): Improve Outro message (#344) Improve the outro message for the source maps wizard by * Showing an example build command for the detected package manager * Showing the URL of the selected project's issues page --- CHANGELOG.md | 4 ++++ src/sourcemaps/sourcemaps-wizard.ts | 28 ++++++++++++++++++++++++---- src/utils/clack-utils.ts | 22 ++++++++++++++-------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c19d014..601b0738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- ref(sourcemaps): Improve Outro message (#344) + ## 3.5.0 - feat(sourcemaps): Check if correct SDK version is installed (#336) diff --git a/src/sourcemaps/sourcemaps-wizard.ts b/src/sourcemaps/sourcemaps-wizard.ts index 26c97bbc..a13e0ddc 100644 --- a/src/sourcemaps/sourcemaps-wizard.ts +++ b/src/sourcemaps/sourcemaps-wizard.ts @@ -9,6 +9,7 @@ import { askForSelfHosted, askForWizardLogin, confirmContinueEvenThoughNoGitRepo, + detectPackageManager, printWelcome, } from '../utils/clack-utils'; import { isUnicodeSupported } from '../utils/vendor/is-unicorn-supported'; @@ -23,6 +24,7 @@ import { WizardOptions } from '../utils/types'; import { configureCRASourcemapGenerationFlow } from './tools/create-react-app'; import { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version'; import { traceStep } from '../telemetry'; +import { URL } from 'url'; type SupportedTools = | 'webpack' @@ -79,7 +81,13 @@ export async function runSourcemapsWizard( await traceStep('ci-setup', () => setupCi(apiKeys.token)); - traceStep('outro', printOutro); + traceStep('outro', () => + printOutro( + sentryUrl, + selectedProject.organization.slug, + selectedProject.id, + ), + ); } async function askForUsedBundlerTool(): Promise { @@ -199,19 +207,31 @@ SENTRY_AUTH_TOKEN=${authToken} } } -function printOutro() { +function printOutro(url: string, orgSlug: string, projectId: string) { + const pacMan = detectPackageManager() || 'npm'; + const buildCommand = `'${pacMan}${pacMan === 'npm' ? ' run' : ''} build'`; + + const urlObject = new URL(url); + urlObject.host = `${orgSlug}.${urlObject.host}`; + urlObject.pathname = '/issues/'; + urlObject.searchParams.set('project', projectId); + + const issueStreamUrl = urlObject.toString(); + const arrow = isUnicodeSupported() ? '→' : '->'; clack.outro(`${chalk.green("That's it - everything is set up!")} - ${chalk.cyan(`Validate your setup with the following Steps: + ${chalk.cyan(`Test and validate your setup locally with the following Steps: 1. Build your application in ${chalk.bold('production mode')}. + ${chalk.gray(`${arrow} For example, run ${chalk.bold(buildCommand)}.`)} ${chalk.gray( `${arrow} You should see source map upload logs in your console.`, )} 2. Run your application and throw a test error. - ${chalk.gray(`${arrow} The error should be visible in Sentry.`)} + ${chalk.gray(`${arrow} The error should appear in Sentry:`)} + ${chalk.gray(`${arrow} ${issueStreamUrl}`)} 3. Open the error in Sentry and verify that it's source-mapped. ${chalk.gray( `${arrow} The stack trace should show your original source code.`, diff --git a/src/utils/clack-utils.ts b/src/utils/clack-utils.ts index 181cc1ad..aa5d0839 100644 --- a/src/utils/clack-utils.ts +++ b/src/utils/clack-utils.ts @@ -604,14 +604,7 @@ export function getPackageVersion( } async function getPackageManager(): Promise { - let detectedPackageManager; - if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) { - detectedPackageManager = 'yarn'; - } else if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) { - detectedPackageManager = 'npm'; - } else if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) { - detectedPackageManager = 'pnpm'; - } + const detectedPackageManager = detectPackageManager(); if (detectedPackageManager) { return detectedPackageManager; @@ -632,3 +625,16 @@ async function getPackageManager(): Promise { return selectedPackageManager; } + +export function detectPackageManager(): 'yarn' | 'npm' | 'pnpm' | undefined { + if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) { + return 'yarn'; + } + if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) { + return 'npm'; + } + if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) { + return 'pnpm'; + } + return undefined; +} From f4ac8d5865ceb4398bd67433e00aa84447f3c379 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 10 Jul 2023 15:08:47 +0200 Subject: [PATCH 2/3] chore: Bump Sentry to 7.57.0 (#347) --- package.json | 2 +- yarn.lock | 75 ++++++++++++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index a2e6ef79..937f77b2 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@clack/core": "0.3.2", "@clack/prompts": "0.6.3", "@sentry/cli": "^1.72.0", - "@sentry/node": "^7.56.0", + "@sentry/node": "^7.57.0", "axios": "1.3.5", "chalk": "^2.4.1", "glob": "^7.1.3", diff --git a/yarn.lock b/yarn.lock index f36831b3..73383897 100644 --- a/yarn.lock +++ b/yarn.lock @@ -742,15 +742,15 @@ dependencies: requireindex "~1.1.0" -"@sentry-internal/tracing@7.56.0": - version "7.56.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.56.0.tgz#ba709258f2f0f3d8a36f9740403088b39212b843" - integrity sha512-OKI4Pz/O13gng8hT9rNc+gRV3+P7nnk1HnHlV8fgaQydS6DsRxoDL1sHa42tZGbh7K9jqNAP3TC6VjBOsr2tXA== +"@sentry-internal/tracing@7.57.0": + version "7.57.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.57.0.tgz#cb761931b635f8f24c84be0eecfacb8516b20551" + integrity sha512-tpViyDd8AhQGYYhI94xi2aaDopXOPfL2Apwrtb3qirWkomIQ2K86W1mPmkce+B0cFOnW2Dxv/ZTFKz6ghjK75A== dependencies: - "@sentry/core" "7.56.0" - "@sentry/types" "7.56.0" - "@sentry/utils" "7.56.0" - tslib "^1.9.3" + "@sentry/core" "7.57.0" + "@sentry/types" "7.57.0" + "@sentry/utils" "7.57.0" + tslib "^2.4.1 || ^1.9.3" "@sentry-internal/typescript@7.48.0": version "7.48.0" @@ -769,41 +769,41 @@ progress "^2.0.3" proxy-from-env "^1.1.0" -"@sentry/core@7.56.0": - version "7.56.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.56.0.tgz#f4253e0d61f55444180a63e5278b62e57303f7cf" - integrity sha512-Nuyyfh09Yz27kPo74fXHlrdmZeK6zrlJVtxQ6LkwuoaTBcNcesNXVaOtr6gjvUGUmsfriVPP3Jero5LXufV7GQ== +"@sentry/core@7.57.0": + version "7.57.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.57.0.tgz#65093d739c04f320a54395a21be955fcbe326acb" + integrity sha512-l014NudPH0vQlzybtXajPxYFfs9w762NoarjObC3gu76D1jzBBFzhdRelkGpDbSLNTIsKhEDDRpgAjBWJ9icfw== dependencies: - "@sentry/types" "7.56.0" - "@sentry/utils" "7.56.0" - tslib "^1.9.3" + "@sentry/types" "7.57.0" + "@sentry/utils" "7.57.0" + tslib "^2.4.1 || ^1.9.3" -"@sentry/node@^7.56.0": - version "7.56.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.56.0.tgz#ddeb34a848c8a544d0dbb5f2c3031615be040d2b" - integrity sha512-QXbWy/ypRxfFd8iP6zLvHInYZyjGKPrkVNYt43mhKAZHm764NxX/29vDfj1FztgG9Z6lVLIG2eyqTvLruYmsWw== +"@sentry/node@^7.57.0": + version "7.57.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.57.0.tgz#31052f5988ed4496d7f3ff925240cf9b02d09941" + integrity sha512-63mjyUVM6sfJFVQ5TGVRVGUsoEfESl5ABzIW1W0s9gUiQPaG8SOdaQJglb2VNrkMYxnRHgD8Q9LUh/qcmUyPGw== dependencies: - "@sentry-internal/tracing" "7.56.0" - "@sentry/core" "7.56.0" - "@sentry/types" "7.56.0" - "@sentry/utils" "7.56.0" + "@sentry-internal/tracing" "7.57.0" + "@sentry/core" "7.57.0" + "@sentry/types" "7.57.0" + "@sentry/utils" "7.57.0" cookie "^0.4.1" https-proxy-agent "^5.0.0" lru_map "^0.3.3" - tslib "^1.9.3" + tslib "^2.4.1 || ^1.9.3" -"@sentry/types@7.56.0": - version "7.56.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.56.0.tgz#9042a099cf9e8816d081886d24b88082a5d9f87a" - integrity sha512-5WjhVOQm75ItOytOx2jTx+5yw8/qJ316+g1Di8dS9+kgIi1zniqdMcX00C2yYe3FMUgFB49PegCUYulm9Evapw== +"@sentry/types@7.57.0": + version "7.57.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.57.0.tgz#4fdb80cbd49ba034dd8d9be0c0005a016d5db3ce" + integrity sha512-D7ifoUfxuVCUyktIr5Gc+jXUbtcUMmfHdTtTbf1XCZHua5mJceK9wtl3YCg3eq/HK2Ppd52BKnTzEcS5ZKQM+w== -"@sentry/utils@7.56.0": - version "7.56.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.56.0.tgz#e60e4935d17b2197584abf6ce61b522ad055352c" - integrity sha512-wgeX7bufxc//TjjSIE+gCMm8hVId7Jzvc+f441bYrWnNZBuzPIDW2BummCcPrKzSYe5GeYZDTZGV8YZGMLGBjw== +"@sentry/utils@7.57.0": + version "7.57.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.57.0.tgz#8253c6fcf35138b4c424234b8da1596e11b98ad8" + integrity sha512-YXrkMCiNklqkXctn4mKYkrzNCf/dfVcRUQrkXjeBC+PHXbcpPyaJgInNvztR7Skl8lE3JPGPN4v5XhLxK1bUUg== dependencies: - "@sentry/types" "7.56.0" - tslib "^1.9.3" + "@sentry/types" "7.57.0" + tslib "^2.4.1 || ^1.9.3" "@sinclair/typebox@^0.25.16": version "0.25.24" @@ -4322,7 +4322,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -4332,6 +4332,11 @@ tslib@^2.0.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +"tslib@^2.4.1 || ^1.9.3": + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + tsutils@^3.0.0, tsutils@^3.17.1, tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" From a8932dc01d35e1f668d3873ec9303cf580aef4cc Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 10 Jul 2023 17:22:21 +0200 Subject: [PATCH 3/3] feat(sourcemaps): Detect SvelteKit and NextJS projects and redirect to dedicated wizards (#341) Detect SvelteKit and NextJS project and redirect to dedicated wizards We observed that several users run the source maps wizard in NextJs (or potentially SvelteKit) projects which isn't ideal. With this change we let them know that a better option exists for them and offer to redirect them to the dedicated wizard. --- CHANGELOG.md | 1 + src/sourcemaps/sourcemaps-wizard.ts | 12 +++ src/sourcemaps/tools/esbuild.ts | 2 +- src/sourcemaps/tools/rollup.ts | 6 +- src/sourcemaps/tools/sentry-cli.ts | 2 +- src/sourcemaps/tools/vite.ts | 2 +- src/sourcemaps/tools/webpack.ts | 2 +- src/sourcemaps/utils/other-wizards.ts | 148 ++++++++++++++++++++++++++ src/sourcemaps/utils/sdk-version.ts | 22 ++-- src/sveltekit/sveltekit-wizard.ts | 2 +- src/utils/clack-utils.ts | 24 +---- src/utils/package-json.ts | 45 ++++++++ 12 files changed, 220 insertions(+), 48 deletions(-) create mode 100644 src/sourcemaps/utils/other-wizards.ts create mode 100644 src/utils/package-json.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 601b0738..cbc005e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- feat(sourcemaps): Detect SvelteKit and NextJS projects and redirect to dedicated wizards (#341) - ref(sourcemaps): Improve Outro message (#344) ## 3.5.0 diff --git a/src/sourcemaps/sourcemaps-wizard.ts b/src/sourcemaps/sourcemaps-wizard.ts index a13e0ddc..5a3f78c3 100644 --- a/src/sourcemaps/sourcemaps-wizard.ts +++ b/src/sourcemaps/sourcemaps-wizard.ts @@ -25,6 +25,7 @@ import { configureCRASourcemapGenerationFlow } from './tools/create-react-app'; import { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version'; import { traceStep } from '../telemetry'; import { URL } from 'url'; +import { checkIfMoreSuitableWizardExistsAndAskForRedirect } from './utils/other-wizards'; type SupportedTools = | 'webpack' @@ -45,6 +46,17 @@ export async function runSourcemapsWizard( promoCode: options.promoCode, }); + const moreSuitableWizard = await traceStep( + 'check-framework-wizard', + checkIfMoreSuitableWizardExistsAndAskForRedirect, + ); + if (moreSuitableWizard) { + await traceStep('run-to-framework-wizard', () => + moreSuitableWizard(options), + ); + return; + } + await traceStep('detect-git', confirmContinueEvenThoughNoGitRepo); await traceStep('check-sdk-version', ensureMinimumSdkVersionIsInstalled); diff --git a/src/sourcemaps/tools/esbuild.ts b/src/sourcemaps/tools/esbuild.ts index a54e8751..7edcd419 100644 --- a/src/sourcemaps/tools/esbuild.ts +++ b/src/sourcemaps/tools/esbuild.ts @@ -5,9 +5,9 @@ import { abortIfCancelled, addDotEnvSentryBuildPluginFile, getPackageDotJson, - hasPackageInstalled, installPackage, } from '../../utils/clack-utils'; +import { hasPackageInstalled } from '../../utils/package-json'; import { SourceMapUploadToolConfigurationFunction, diff --git a/src/sourcemaps/tools/rollup.ts b/src/sourcemaps/tools/rollup.ts index f2505b3b..8d15bcd0 100644 --- a/src/sourcemaps/tools/rollup.ts +++ b/src/sourcemaps/tools/rollup.ts @@ -5,9 +5,9 @@ import { abortIfCancelled, addDotEnvSentryBuildPluginFile, getPackageDotJson, - hasPackageInstalled, installPackage, } from '../../utils/clack-utils'; +import { hasPackageInstalled } from '../../utils/package-json'; import { SourceMapUploadToolConfigurationFunction, @@ -49,9 +49,7 @@ export const configureRollupPlugin: SourceMapUploadToolConfigurationFunction = ), }); - clack.log.step( - `Add the following code to your rollup config:`, - ); + clack.log.step(`Add the following code to your rollup config:`); // Intentially logging directly to console here so that the code can be copied/pasted directly // eslint-disable-next-line no-console diff --git a/src/sourcemaps/tools/sentry-cli.ts b/src/sourcemaps/tools/sentry-cli.ts index 37c66df1..2bfbd2ce 100644 --- a/src/sourcemaps/tools/sentry-cli.ts +++ b/src/sourcemaps/tools/sentry-cli.ts @@ -8,11 +8,11 @@ import { abortIfCancelled, addSentryCliRc, getPackageDotJson, - hasPackageInstalled, installPackage, } from '../../utils/clack-utils'; import { SourceMapUploadToolConfigurationOptions } from './types'; +import { hasPackageInstalled } from '../../utils/package-json'; export async function configureSentryCLI( options: SourceMapUploadToolConfigurationOptions, diff --git a/src/sourcemaps/tools/vite.ts b/src/sourcemaps/tools/vite.ts index fa20cf2f..373d3650 100644 --- a/src/sourcemaps/tools/vite.ts +++ b/src/sourcemaps/tools/vite.ts @@ -5,9 +5,9 @@ import { abortIfCancelled, addDotEnvSentryBuildPluginFile, getPackageDotJson, - hasPackageInstalled, installPackage, } from '../../utils/clack-utils'; +import { hasPackageInstalled } from '../../utils/package-json'; import { SourceMapUploadToolConfigurationFunction, diff --git a/src/sourcemaps/tools/webpack.ts b/src/sourcemaps/tools/webpack.ts index 671f1cbf..b87b81cb 100644 --- a/src/sourcemaps/tools/webpack.ts +++ b/src/sourcemaps/tools/webpack.ts @@ -5,9 +5,9 @@ import { abortIfCancelled, addDotEnvSentryBuildPluginFile, getPackageDotJson, - hasPackageInstalled, installPackage, } from '../../utils/clack-utils'; +import { hasPackageInstalled } from '../../utils/package-json'; import { SourceMapUploadToolConfigurationFunction, diff --git a/src/sourcemaps/utils/other-wizards.ts b/src/sourcemaps/utils/other-wizards.ts new file mode 100644 index 00000000..b1e0b325 --- /dev/null +++ b/src/sourcemaps/utils/other-wizards.ts @@ -0,0 +1,148 @@ +// @ts-ignore - clack is ESM and TS complains about that. It works though +import clack from '@clack/prompts'; +import chalk from 'chalk'; +import { runNextjsWizard } from '../../nextjs/nextjs-wizard'; +import { runSvelteKitWizard } from '../../sveltekit/sveltekit-wizard'; + +import { + abort, + abortIfCancelled, + getPackageDotJson, +} from '../../utils/clack-utils'; +import { + findPackageFromList, + hasPackageInstalled, +} from '../../utils/package-json'; + +import * as Sentry from '@sentry/node'; +import { WizardOptions } from '../../utils/types'; + +type WizardFunction = (options: WizardOptions) => Promise; + +type FrameworkInfo = { + frameworkName: string; + frameworkSlug: string; + frameworkPackage: string; + sourcemapsDocsLink: string; + wizard: WizardFunction; +}; + +const sdkMap: Record = { + '@sentry/nextjs': { + frameworkName: 'Next.js', + frameworkSlug: 'nextjs', + frameworkPackage: 'next', + sourcemapsDocsLink: + 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-source-maps', + wizard: runNextjsWizard, + }, + '@sentry/sveltekit': { + frameworkName: 'SvelteKit', + frameworkSlug: 'sveltekit', + frameworkPackage: '@sveltejs/kit', + sourcemapsDocsLink: + 'https://docs.sentry.io/platforms/javascript/guides/sveltekit/manual-setup/#configure-source-maps-upload', + wizard: runSvelteKitWizard, + }, +}; + +export async function checkIfMoreSuitableWizardExistsAndAskForRedirect(): Promise< + WizardFunction | undefined +> { + const sdkName = await checkIfMoreSuitableWizardExists(); + + if (!sdkName) { + return undefined; + } + + return await askForRedirect(sdkName); +} + +async function checkIfMoreSuitableWizardExists(): Promise { + Sentry.setTag('using-wrong-wizard', false); + + const packageJson = await getPackageDotJson(); + + const installedSdkPackage = findPackageFromList( + Object.keys(sdkMap), + packageJson, + ); + + if (!installedSdkPackage) { + return undefined; + } + + const sdkPackageName = installedSdkPackage.name; + + const { frameworkPackage } = sdkMap[sdkPackageName]; + + if (!hasPackageInstalled(frameworkPackage, packageJson)) { + // The user has installed the SDK but not the framework. + // Maybe it's a false positive and the user is using a different framework. + // Let's not redirect them to the framework wizard in that case. + return undefined; + } + + Sentry.setTag('using-wrong-wizard', true); + + return sdkPackageName; +} + +async function askForRedirect( + sdkName: string, +): Promise { + const { frameworkName, sourcemapsDocsLink, frameworkSlug, wizard } = + sdkMap[sdkName]; + + clack.log.warn( + `${chalk.yellow( + `It seems like you're using this wizard in a ${frameworkName} project.`, + )} + +We recommend using our dedicated ${frameworkName} wizard instead of this wizard. +The ${frameworkName} wizard will set up our ${sdkName} SDK and also configure uploading source maps for you. + +If you already tried the ${frameworkName} wizard and it didn't work for you, check out the following guides: + +Manual source maps configuration for ${frameworkName}: +${sourcemapsDocsLink} + +Troubleshooting Source Maps: +https://docs.sentry.io/platforms/javascript/guides/${frameworkSlug}/sourcemaps/troubleshooting_js/ +`, + ); + + const nextStep: 'redirect' | 'continue' | 'stop' = await abortIfCancelled( + clack.select({ + message: `Do you want to run the ${frameworkName} wizard now?`, + options: [ + { + label: 'Yes', + value: 'redirect', + hint: `${chalk.green('Recommended')}`, + }, + { + label: 'No, continue with this wizard', + value: 'continue', + }, + { + label: "No, I'll check out the guides ", + value: 'stop', + hint: 'Exit this wizard', + }, + ], + }), + ); + + Sentry.setTag('wrong-wizard-decision', nextStep); + + switch (nextStep) { + case 'redirect': + return wizard; + case 'stop': + await abort('Exiting Wizard', 0); + break; + default: + return undefined; + } +} diff --git a/src/sourcemaps/utils/sdk-version.ts b/src/sourcemaps/utils/sdk-version.ts index d79fe4de..5529a578 100644 --- a/src/sourcemaps/utils/sdk-version.ts +++ b/src/sourcemaps/utils/sdk-version.ts @@ -5,11 +5,11 @@ import { minVersion, satisfies } from 'semver'; import { abortIfCancelled, getPackageDotJson, - getPackageVersion, installPackage, } from '../../utils/clack-utils'; import * as Sentry from '@sentry/node'; +import { findPackageFromList } from '../../utils/package-json'; const MINIMUM_DEBUG_ID_SDK_VERSION = '7.47.0'; @@ -36,12 +36,7 @@ const SENTRY_SDK_PACKAGE_NAMES = [ // Base SDKs '@sentry/browser', '@sentry/node', -] as const; - -type SdkPackage = { - name: (typeof SENTRY_SDK_PACKAGE_NAMES)[number]; - version: string; -}; +]; /** * Check for a minimum SDK version and prompt the user to upgrade if necessary. @@ -57,15 +52,10 @@ type SdkPackage = { * -> We tell users to manually upgrade (migrate between majors) */ export async function ensureMinimumSdkVersionIsInstalled(): Promise { - const packageJson = await getPackageDotJson(); - - const installedSdkPackages = SENTRY_SDK_PACKAGE_NAMES.map((packageName) => ({ - name: packageName, - version: getPackageVersion(packageName, packageJson), - })).filter((sdkPackage): sdkPackage is SdkPackage => !!sdkPackage.version); - - const installedSdkPackage = - installedSdkPackages.length > 0 && installedSdkPackages[0]; + const installedSdkPackage = findPackageFromList( + SENTRY_SDK_PACKAGE_NAMES, + await getPackageDotJson(), + ); // Case 1: if (!installedSdkPackage) { diff --git a/src/sveltekit/sveltekit-wizard.ts b/src/sveltekit/sveltekit-wizard.ts index 9fd67f07..c7ce7f85 100644 --- a/src/sveltekit/sveltekit-wizard.ts +++ b/src/sveltekit/sveltekit-wizard.ts @@ -9,10 +9,10 @@ import { confirmContinueEvenThoughNoGitRepo, ensurePackageIsInstalled, getPackageDotJson, - hasPackageInstalled, installPackage, printWelcome, } from '../utils/clack-utils'; +import { hasPackageInstalled } from '../utils/package-json'; import { WizardOptions } from '../utils/types'; import { createExamplePage } from './sdk-example'; import { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup'; diff --git a/src/utils/clack-utils.ts b/src/utils/clack-utils.ts index aa5d0839..5a562bd4 100644 --- a/src/utils/clack-utils.ts +++ b/src/utils/clack-utils.ts @@ -10,6 +10,7 @@ import { URL } from 'url'; import { promisify } from 'util'; import * as Sentry from '@sentry/node'; import { windowedSelect } from './vendor/clack-custom-select'; +import { hasPackageInstalled, PackageDotJson } from './package-json'; const opn = require('opn') as ( url: string, @@ -24,12 +25,6 @@ interface WizardProjectData { projects: SentryProjectData[]; } -export type PackageDotJson = { - scripts?: Record; - dependencies?: Record; - devDependencies?: Record; -}; - export interface SentryProjectData { id: string; slug: string; @@ -586,23 +581,6 @@ export async function getPackageDotJson(): Promise { return packageJson || {}; } -export function hasPackageInstalled( - packageName: string, - packageJson: PackageDotJson, -): boolean { - return getPackageVersion(packageName, packageJson) !== undefined; -} - -export function getPackageVersion( - packageName: string, - packageJson: PackageDotJson, -): string | undefined { - return ( - packageJson?.dependencies?.[packageName] || - packageJson?.devDependencies?.[packageName] - ); -} - async function getPackageManager(): Promise { const detectedPackageManager = detectPackageManager(); diff --git a/src/utils/package-json.ts b/src/utils/package-json.ts new file mode 100644 index 00000000..916543b6 --- /dev/null +++ b/src/utils/package-json.ts @@ -0,0 +1,45 @@ +export type PackageDotJson = { + scripts?: Record; + dependencies?: Record; + devDependencies?: Record; +}; + +type NpmPackage = { + name: string; + version: string; +}; + +/** + * Checks if @param packageJson has any of the @param packageNamesList package names + * listed as a dependency or devDependency. + * If so, it returns the first package name that is found, including the + * version (range) specified in the package.json. + */ +export function findPackageFromList( + packageNamesList: string[], + packageJson: PackageDotJson, +): NpmPackage | undefined { + return packageNamesList + .map((packageName) => ({ + name: packageName, + version: getPackageVersion(packageName, packageJson), + })) + .find((sdkPackage): sdkPackage is NpmPackage => !!sdkPackage.version); +} + +export function hasPackageInstalled( + packageName: string, + packageJson: PackageDotJson, +): boolean { + return getPackageVersion(packageName, packageJson) !== undefined; +} + +export function getPackageVersion( + packageName: string, + packageJson: PackageDotJson, +): string | undefined { + return ( + packageJson?.dependencies?.[packageName] || + packageJson?.devDependencies?.[packageName] + ); +}