@@ -24,13 +24,6 @@ type Sorcery = {
2424 load ( filepath : string ) : Promise < Chain > ;
2525} ;
2626
27- type GlobalWithSourceMapSetting = typeof globalThis & {
28- _sentry_sourceMapSetting ?: {
29- updatedSourceMapSetting ?: boolean | 'inline' | 'hidden' ;
30- previousSourceMapSetting ?: UserSourceMapSetting ;
31- } ;
32- } ;
33-
3427// storing this in the module scope because `makeCustomSentryVitePlugin` is called multiple times
3528// and we only want to generate a uuid once in case we have to fall back to it.
3629const releaseName = detectSentryRelease ( ) ;
@@ -57,8 +50,6 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
5750 const usedAdapter = options ?. adapter || 'other' ;
5851 const adapterOutputDir = await getAdapterOutputDir ( svelteConfig , usedAdapter ) ;
5952
60- const globalWithSourceMapSetting = globalThis as GlobalWithSourceMapSetting ;
61-
6253 const defaultPluginOptions : SentryVitePluginOptions = {
6354 release : {
6455 name : releaseName ,
@@ -70,61 +61,8 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
7061 } ,
7162 } ;
7263
73- // Including all hidden (`.*`) directories by default so that folders like .vercel,
74- // .netlify, etc are also cleaned up. Additionally, we include the adapter output
75- // dir which could be a non-hidden directory, like `build` for the Node adapter.
76- const defaultFileDeletionGlob = [ './.*/**/*.map' , `./${ adapterOutputDir } /**/*.map` ] ;
77-
78- if ( ! globalWithSourceMapSetting . _sentry_sourceMapSetting ) {
79- let configFile : {
80- path : string ;
81- config : UserConfig ;
82- dependencies : string [ ] ;
83- } | null = null ;
84-
85- try {
86- // @ts -expect-error - the dynamic import here works fine
87- const Vite = await import ( 'vite' ) ;
88- configFile = await Vite . loadConfigFromFile ( { command : 'build' , mode : 'production' } ) ;
89- } catch {
90- if ( options ?. debug ) {
91- consoleSandbox ( ( ) => {
92- // eslint-disable-next-line no-console
93- console . warn (
94- '[Sentry] Could not import Vite to load your vite config. Please set `build.sourcemap` to `true` or `hidden` to enable source map generation.' ,
95- ) ;
96- } ) ;
97- }
98- }
99-
100- if ( configFile ) {
101- globalWithSourceMapSetting . _sentry_sourceMapSetting = getUpdatedSourceMapSetting ( configFile . config ) ;
102- } else {
103- if ( options ?. debug ) {
104- consoleSandbox ( ( ) => {
105- // eslint-disable-next-line no-console
106- console . warn (
107- '[Sentry] Could not load Vite config with Vite "production" mode. This is needed for Sentry to automatically update source map settings.' ,
108- ) ;
109- } ) ;
110- }
111- }
112-
113- if ( options ?. debug && globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' ) {
114- consoleSandbox ( ( ) => {
115- // eslint-disable-next-line no-console
116- console . warn (
117- `[Sentry] Automatically setting \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload: [${ defaultFileDeletionGlob
118- . map ( file => `"${ file } "` )
119- . join ( ', ' ) } ]\` to delete generated source maps after they were uploaded to Sentry.`,
120- ) ;
121- } ) ;
122- }
123- }
124-
125- const shouldDeleteDefaultSourceMaps =
126- globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' &&
127- ! options ?. sourcemaps ?. filesToDeleteAfterUpload ;
64+ const { promise : filesToDeleteAfterUpload , resolve : resolveFilesToDeleteAfterUpload } =
65+ createFilesToDeleteAfterUploadPromise ( ) ;
12866
12967 const mergedOptions = {
13068 ...defaultPluginOptions ,
@@ -135,9 +73,7 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
13573 } ,
13674 sourcemaps : {
13775 ...options ?. sourcemaps ,
138- filesToDeleteAfterUpload : shouldDeleteDefaultSourceMaps
139- ? defaultFileDeletionGlob
140- : options ?. sourcemaps ?. filesToDeleteAfterUpload ,
76+ filesToDeleteAfterUpload,
14177 } ,
14278 } ;
14379
@@ -163,6 +99,10 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
16399 console . warn (
164100 'sentry-vite-debug-id-upload-plugin not found in sentryPlugins! Cannot modify plugin - returning default Sentry Vite plugins' ,
165101 ) ;
102+
103+ // resolving filesToDeleteAfterUpload here, because we return the original deletion plugin which awaits the promise
104+ resolveFilesToDeleteAfterUpload ( undefined ) ;
105+
166106 return sentryPlugins ;
167107 }
168108
@@ -172,6 +112,10 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
172112 console . warn (
173113 'sentry-file-deletion-plugin not found in sentryPlugins! Cannot modify plugin - returning default Sentry Vite plugins' ,
174114 ) ;
115+
116+ // resolving filesToDeleteAfterUpload here, because we return the original deletion plugin which awaits the promise
117+ resolveFilesToDeleteAfterUpload ( undefined ) ;
118+
175119 return sentryPlugins ;
176120 }
177121
@@ -181,6 +125,10 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
181125 console . warn (
182126 'sentry-release-management-plugin not found in sentryPlugins! Cannot modify plugin - returning default Sentry Vite plugins' ,
183127 ) ;
128+
129+ // resolving filesToDeleteAfterUpload here, because we return the original deletion plugin which awaits the promise
130+ resolveFilesToDeleteAfterUpload ( undefined ) ;
131+
184132 return sentryPlugins ;
185133 }
186134
@@ -205,37 +153,66 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
205153 const sourceMapSettingsPlugin : Plugin = {
206154 name : 'sentry-sveltekit-update-source-map-setting-plugin' ,
207155 apply : 'build' , // only apply this plugin at build time
208- config : ( config : UserConfig ) => {
156+ config : async ( config : UserConfig ) => {
209157 const settingKey = 'build.sourcemap' ;
210158
211- if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'unset' ) {
159+ const { updatedSourceMapSetting, previousSourceMapSetting } = getUpdatedSourceMapSetting ( config ) ;
160+
161+ const userProvidedFilesToDeleteAfterUpload = await options ?. sourcemaps ?. filesToDeleteAfterUpload ;
162+
163+ if ( previousSourceMapSetting === 'unset' ) {
212164 consoleSandbox ( ( ) => {
213165 // eslint-disable-next-line no-console
214166 console . log ( `[Sentry] Enabled source map generation in the build options with \`${ settingKey } : "hidden"\`.` ) ;
215167 } ) ;
216168
169+ if ( userProvidedFilesToDeleteAfterUpload ) {
170+ resolveFilesToDeleteAfterUpload ( userProvidedFilesToDeleteAfterUpload ) ;
171+ } else {
172+ // Including all hidden (`.*`) directories by default so that folders like .vercel,
173+ // .netlify, etc are also cleaned up. Additionally, we include the adapter output
174+ // dir which could be a non-hidden directory, like `build` for the Node adapter.
175+ const defaultFileDeletionGlob = [ './.*/**/*.map' , `./${ adapterOutputDir } /**/*.map` ] ;
176+
177+ consoleSandbox ( ( ) => {
178+ // eslint-disable-next-line no-console
179+ console . warn (
180+ `[Sentry] Automatically setting \`sourceMapsUploadOptions.sourcemaps.filesToDeleteAfterUpload: [${ defaultFileDeletionGlob
181+ . map ( file => `"${ file } "` )
182+ . join ( ', ' ) } ]\` to delete generated source maps after they were uploaded to Sentry.`,
183+ ) ;
184+ } ) ;
185+
186+ // In case we enabled source maps and users didn't specify a glob patter to delete, we set a default pattern:
187+ resolveFilesToDeleteAfterUpload ( defaultFileDeletionGlob ) ;
188+ }
189+
217190 return {
218191 ...config ,
219- build : { ...config . build , sourcemap : 'hidden' } ,
192+ build : { ...config . build , sourcemap : updatedSourceMapSetting } ,
220193 } ;
221- } else if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'disabled' ) {
194+ }
195+
196+ if ( previousSourceMapSetting === 'disabled' ) {
222197 consoleSandbox ( ( ) => {
223198 // eslint-disable-next-line no-console
224199 console . warn (
225200 `[Sentry] Parts of source map generation are currently disabled in your Vite configuration (\`${ settingKey } : false\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \`${ settingKey } \` (e.g. by setting them to \`hidden\`).` ,
226201 ) ;
227202 } ) ;
228- } else if ( globalWithSourceMapSetting . _sentry_sourceMapSetting ?. previousSourceMapSetting === 'enabled' ) {
203+ } else if ( previousSourceMapSetting === 'enabled' ) {
229204 if ( mergedOptions ?. debug ) {
230205 consoleSandbox ( ( ) => {
231206 // eslint-disable-next-line no-console
232207 console . log (
233- `[Sentry] We discovered you enabled source map generation in your Vite configuration (\`${ settingKey } \`). Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.` ,
208+ `[Sentry] We discovered you enabled source map generation in your Vite configuration (\`${ settingKey } \`). Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.` ,
234209 ) ;
235210 } ) ;
236211 }
237212 }
238213
214+ resolveFilesToDeleteAfterUpload ( userProvidedFilesToDeleteAfterUpload ) ;
215+
239216 return config ;
240217 } ,
241218 } ;
@@ -423,7 +400,7 @@ export async function makeCustomSentryVitePlugins(options?: CustomSentryVitePlug
423400/**
424401 * Whether the user enabled (true, 'hidden', 'inline') or disabled (false) source maps
425402 */
426- export type UserSourceMapSetting = 'enabled' | 'disabled' | 'unset' | undefined ;
403+ type UserSourceMapSetting = 'enabled' | 'disabled' | 'unset' | undefined ;
427404
428405/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)
429406 *
@@ -445,25 +422,25 @@ export function getUpdatedSourceMapSetting(viteConfig: {
445422 sourcemap ?: boolean | 'inline' | 'hidden' ;
446423 } ;
447424} ) : { updatedSourceMapSetting : boolean | 'inline' | 'hidden' ; previousSourceMapSetting : UserSourceMapSetting } {
448- let previousSourceMapSetting : UserSourceMapSetting ;
449- let updatedSourceMapSetting : boolean | 'inline' | 'hidden' | undefined ;
450-
451425 viteConfig . build = viteConfig . build || { } ;
452426
453- const viteSourceMap = viteConfig . build . sourcemap ;
454-
455- if ( viteSourceMap === false ) {
456- previousSourceMapSetting = 'disabled' ;
457- updatedSourceMapSetting = viteSourceMap ;
458- } else if ( viteSourceMap && [ 'hidden' , 'inline' , true ] . includes ( viteSourceMap ) ) {
459- previousSourceMapSetting = 'enabled' ;
460- updatedSourceMapSetting = viteSourceMap ;
461- } else {
462- previousSourceMapSetting = 'unset' ;
463- updatedSourceMapSetting = 'hidden' ;
427+ const originalSourcemapSetting = viteConfig . build . sourcemap ;
428+
429+ if ( originalSourcemapSetting === false ) {
430+ return {
431+ previousSourceMapSetting : 'disabled' ,
432+ updatedSourceMapSetting : originalSourcemapSetting ,
433+ } ;
434+ }
435+
436+ if ( originalSourcemapSetting && [ 'hidden' , 'inline' , true ] . includes ( originalSourcemapSetting ) ) {
437+ return { previousSourceMapSetting : 'enabled' , updatedSourceMapSetting : originalSourcemapSetting } ;
464438 }
465439
466- return { previousSourceMapSetting, updatedSourceMapSetting } ;
440+ return {
441+ previousSourceMapSetting : 'unset' ,
442+ updatedSourceMapSetting : 'hidden' ,
443+ } ;
467444}
468445
469446function getFiles ( dir : string ) : string [ ] {
@@ -499,3 +476,22 @@ function detectSentryRelease(): string {
499476
500477 return release ;
501478}
479+
480+ /**
481+ * Creates a deferred promise that can be resolved/rejected by calling the
482+ * `resolve` or `reject` function.
483+ * Inspired by: https://stackoverflow.com/a/69027809
484+ */
485+ function createFilesToDeleteAfterUploadPromise ( ) : {
486+ promise : Promise < string | string [ ] | undefined > ;
487+ resolve : ( value : string | string [ ] | undefined ) => void ;
488+ reject : ( reason ?: unknown ) => void ;
489+ } {
490+ let resolve ! : ( value : string | string [ ] | undefined ) => void ;
491+ let reject ! : ( reason ?: unknown ) => void ;
492+ const promise = new Promise < string | string [ ] | undefined > ( ( res , rej ) => {
493+ resolve = res ;
494+ reject = rej ;
495+ } ) ;
496+ return { resolve, reject, promise } ;
497+ }
0 commit comments