From 8c7c8214632ff1e9aceb5c1730ee903a55e77619 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 12 Oct 2022 13:12:25 +0200 Subject: [PATCH 1/8] add withSentryConfig function --- packages/svelte/src/config.ts | 76 ++++++++++++++++++++++++++++ packages/svelte/src/index.ts | 4 ++ packages/svelte/src/preprocessors.ts | 20 ++++++-- packages/svelte/src/types.ts | 37 ++------------ 4 files changed, 101 insertions(+), 36 deletions(-) create mode 100644 packages/svelte/src/config.ts diff --git a/packages/svelte/src/config.ts b/packages/svelte/src/config.ts new file mode 100644 index 000000000000..50634cc7d30a --- /dev/null +++ b/packages/svelte/src/config.ts @@ -0,0 +1,76 @@ +import { CompileOptions } from 'svelte/types/compiler'; +import { PreprocessorGroup } from 'svelte/types/compiler/preprocess'; + +import { componentTrackingPreprocessor, defaultComponentTrackingOptions } from './preprocessors'; +import { ComponentTrackingInitOptions, SentryPreprocessorGroup } from './types'; + +export type SvelteConfig = { + [key: string]: unknown; + preprocess?: PreprocessorGroup[] | PreprocessorGroup; + compilerOptions?: CompileOptions; +}; + +export type SentrySvelteConfigOptions = { + componentTracking?: ComponentTrackingInitOptions; +}; + +const DEFAULT_SENTRY_OPTIONS: SentrySvelteConfigOptions = { + componentTracking: defaultComponentTrackingOptions, +}; + +/** + * Add Sentry options to the Svelte config to be exported from the user's `svelte.config.js` file. + * + * @param originalConfig The existing config to be exported prior to adding Sentry + * @param sentryOptions The configuration of the Sentry-added options + * + * @return The wrapped and modified config to be exported + */ +export function withSentryConfig( + originalConfig: SvelteConfig, + sentryOptions?: SentrySvelteConfigOptions, +): SvelteConfig { + const mergedOptions = { + ...DEFAULT_SENTRY_OPTIONS, + ...sentryOptions, + }; + + const originalPreprocessors = getOriginalPreprocessorArray(originalConfig); + const sentryPreprocessors: SentryPreprocessorGroup[] = []; + + const shouldTrackComponents = mergedOptions.componentTracking && mergedOptions.componentTracking.trackComponents; + if (shouldTrackComponents) { + // TODO(v8): Remove eslint rule + // eslint-disable-next-line deprecation/deprecation + sentryPreprocessors.push(componentTrackingPreprocessor(mergedOptions.componentTracking)); + } + + const dedupedSentryPreprocessors = sentryPreprocessors.filter( + sentryPreproc => + originalPreprocessors.find(p => (p as SentryPreprocessorGroup).id === sentryPreproc.id) === undefined, + ); + + const mergedPreprocessors = [...dedupedSentryPreprocessors, ...originalPreprocessors]; + + return { + ...originalConfig, + preprocess: mergedPreprocessors, + }; +} + +/** + * Standardizes the different ways the user-provided preprocessor option can be specified. + * Users can specify an array of preprocessors, one single one or nothing at all. + * + * @param originalConfig the user-provided svelte config oject + * @return an array of preprocessors or an empty array if no preprocessors were specified + */ +function getOriginalPreprocessorArray(originalConfig: SvelteConfig): PreprocessorGroup[] { + if (originalConfig.preprocess) { + if (Array.isArray(originalConfig.preprocess)) { + return originalConfig.preprocess; + } + return [originalConfig.preprocess]; + } + return []; +} diff --git a/packages/svelte/src/index.ts b/packages/svelte/src/index.ts index 40f648a46286..bc82551784d6 100644 --- a/packages/svelte/src/index.ts +++ b/packages/svelte/src/index.ts @@ -7,5 +7,9 @@ export * from '@sentry/browser'; export { init } from './sdk'; +// TODO(v8): Remove this export export { componentTrackingPreprocessor } from './preprocessors'; + export { trackComponent } from './performance'; + +export { withSentryConfig } from './config'; diff --git a/packages/svelte/src/preprocessors.ts b/packages/svelte/src/preprocessors.ts index 9102636c045f..219b679c7d35 100644 --- a/packages/svelte/src/preprocessors.ts +++ b/packages/svelte/src/preprocessors.ts @@ -1,6 +1,7 @@ import MagicString from 'magic-string'; +import { PreprocessorGroup } from 'svelte/types/compiler/preprocess'; -import { ComponentTrackingInitOptions, PreprocessorGroup, TrackComponentOptions } from './types'; +import { ComponentTrackingInitOptions, SentryPreprocessorGroup, TrackComponentOptions } from './types'; export const defaultComponentTrackingOptions: Required = { trackComponents: true, @@ -8,18 +9,22 @@ export const defaultComponentTrackingOptions: Required(); - return { - // This script hook is called whenever a Svelte component's