UNPKG

@sentry/wizard

Version:

Sentry wizard helping you to configure your project

231 lines (204 loc) 7.26 kB
// @ts-expect-error - clack is ESM and TS complains about that. It works though import clack from '@clack/prompts'; import chalk from 'chalk'; import { addSentryCliConfig, askShouldCreateExamplePage, confirmContinueIfNoOrDirtyGitRepo, ensurePackageIsInstalled, getOrAskForProjectData, getPackageDotJson, installPackage, isUsingTypeScript, printWelcome, rcCliSetupConfig, } from '../utils/clack-utils'; import { hasPackageInstalled } from '../utils/package-json'; import { WizardOptions } from '../utils/types'; import { initializeSentryOnEntryClient, instrumentSentryOnEntryServer, updateBuildScript, instrumentRootRoute, isRemixV2, loadRemixConfig, runRemixReveal, insertServerInstrumentationFile, createServerInstrumentationFile, updateStartScript, } from './sdk-setup'; import { debug } from '../utils/debug'; import { traceStep, withTelemetry } from '../telemetry'; import { isHydrogenApp } from './utils'; import { DEFAULT_URL } from '../../lib/Constants'; import { findFile } from '../utils/ast-utils'; import { configureVitePlugin } from '../sourcemaps/tools/vite'; import { createExamplePage } from './sdk-example'; export async function runRemixWizard(options: WizardOptions): Promise<void> { return withTelemetry( { enabled: options.telemetryEnabled, integration: 'remix', }, () => runRemixWizardWithTelemetry(options), ); } async function runRemixWizardWithTelemetry( options: WizardOptions, ): Promise<void> { printWelcome({ wizardName: 'Sentry Remix Wizard', promoCode: options.promoCode, telemetryEnabled: options.telemetryEnabled, }); await confirmContinueIfNoOrDirtyGitRepo(); const remixConfig = await loadRemixConfig(); const packageJson = await getPackageDotJson(); // We expect `@remix-run/dev` to be installed for every Remix project await ensurePackageIsInstalled(packageJson, '@remix-run/dev', 'Remix'); const { selectedProject, authToken, sentryUrl, selfHosted } = await getOrAskForProjectData(options, 'javascript-remix'); await installPackage({ packageName: '@sentry/remix', alreadyInstalled: hasPackageInstalled('@sentry/remix', packageJson), }); const dsn = selectedProject.keys[0].dsn.public; const isTS = isUsingTypeScript(); const isV2 = isRemixV2(remixConfig, packageJson); const viteConfig = findFile('vite.config'); await addSentryCliConfig({ authToken }, rcCliSetupConfig); if (viteConfig) { await traceStep( 'Update vite configuration for sourcemap uploads', async () => { try { await configureVitePlugin({ orgSlug: selectedProject.organization.slug, projectSlug: selectedProject.slug, url: sentryUrl, selfHosted, authToken, }); } catch (e) { clack.log .warn(`Could not update vite configuration to generate and upload sourcemaps. Please update your vite configuration manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`); debug(e); } }, ); } else { await traceStep('Update build script for sourcemap uploads', async () => { try { await updateBuildScript({ org: selectedProject.organization.slug, project: selectedProject.slug, url: sentryUrl === DEFAULT_URL ? undefined : sentryUrl, isHydrogen: isHydrogenApp(packageJson), }); } catch (e) { clack.log .warn(`Could not update build script to generate and upload sourcemaps. Please update your build script manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/sourcemaps/`); debug(e); } }); } await traceStep('Instrument root route', async () => { try { await instrumentRootRoute(isV2, isTS); } catch (e) { clack.log.warn(`Could not instrument root route. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`); debug(e); } }); traceStep('Reveal missing entry files', () => { try { runRemixReveal(isTS); } catch (e) { clack.log.warn(`Could not run 'npx remix reveal'. Please create your entry files manually`); debug(e); } }); await traceStep('Initialize Sentry on client entry', async () => { try { await initializeSentryOnEntryClient(dsn, isTS); } catch (e) { clack.log.warn(`Could not initialize Sentry on client entry. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`); debug(e); } }); let instrumentationFile = ''; await traceStep('Create server instrumentation file', async () => { try { instrumentationFile = await createServerInstrumentationFile(dsn); } catch (e) { clack.log.warn( 'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/', ); debug(e); } }); let serverFileInstrumented = false; await traceStep( 'Create server instrumentation file and import it', async () => { try { serverFileInstrumented = await insertServerInstrumentationFile(dsn); } catch (e) { clack.log.warn( 'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/', ); debug(e); } }, ); if (!serverFileInstrumented && instrumentationFile) { await traceStep( 'Update `start` script to import instrumentation file.', async () => { try { await updateStartScript(instrumentationFile); } catch (e) { clack.log .warn(`Could not automatically add Sentry initialization to server entry. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`); debug(e); } }, ); } await traceStep('Instrument server `handleError`', async () => { try { await instrumentSentryOnEntryServer(isV2, isTS); } catch (e) { clack.log.warn(`Could not initialize Sentry on server entry. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`); debug(e); } }); const shouldCreateExamplePage = await askShouldCreateExamplePage(); if (shouldCreateExamplePage) { await traceStep('Create example page', async () => { await createExamplePage({ isTS, selfHosted, orgSlug: selectedProject.organization.slug, projectId: selectedProject.id, url: sentryUrl, }); }); } clack.outro(` ${chalk.green( 'Sentry has been successfully configured for your Remix project.', )} ${chalk.cyan('You can now deploy your project to see Sentry in action.')} ${chalk.cyan( `To learn more about how to use Sentry with Remix, visit our documentation: https://docs.sentry.io/platforms/javascript/guides/remix/`, )}`); }