@@ -190,63 +190,59 @@ export function sentryCliBinaryExists(): boolean {
190190 return fs . existsSync ( SentryCli . getPath ( ) ) ;
191191}
192192
193+ // We need to be careful not to inject the snippet before any `"use strict";`s.
194+ // As an additional complication `"use strict";`s may come after any number of comments.
195+ const COMMENT_USE_STRICT_REGEX =
196+ // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
197+ / ^ (?: \s * | \/ \* (?: .| \r | \n ) * ?\* \/ | \/ \/ .* [ \n \r ] ) * (?: " [ ^ " ] * " ; | ' [ ^ ' ] * ' ; ) ? / ;
198+
199+ /**
200+ * Simplified `renderChunk` hook type from Rollup.
201+ * We can't reference the type directly because the Vite plugin complains
202+ * about type mismatches
203+ */
204+ type RenderChunkHook = (
205+ code : string ,
206+ chunk : {
207+ fileName : string ;
208+ }
209+ ) => {
210+ code : string ;
211+ map : SourceMap ;
212+ } | null ;
213+
193214export function createRollupReleaseInjectionHooks ( injectionCode : string ) : {
194- resolveId : UnpluginOptions [ "resolveId" ] ;
195- load : UnpluginOptions [ "load" ] ;
196- transform : UnpluginOptions [ "transform" ] ;
215+ renderChunk : RenderChunkHook ;
197216} {
198- const virtualReleaseInjectionFileId = "\0sentry-release-injection-file" ;
199217 return {
200- resolveId ( id : string ) {
201- if ( id === virtualReleaseInjectionFileId ) {
202- return {
203- id : virtualReleaseInjectionFileId ,
204- external : false ,
205- moduleSideEffects : true ,
206- } ;
207- } else {
208- return null ;
209- }
210- } ,
211-
212- load ( id : string ) {
213- if ( id === virtualReleaseInjectionFileId ) {
214- return injectionCode ;
215- } else {
216- return null ;
217- }
218- } ,
219-
220- transform ( code : string , id : string ) {
221- if ( id === virtualReleaseInjectionFileId ) {
222- return null ;
223- }
224-
225- // id may contain query and hash which will trip up our file extension logic below
226- const idWithoutQueryAndHash = stripQueryAndHashFromPath ( id ) ;
227-
228- if ( idWithoutQueryAndHash . match ( / \\ n o d e _ m o d u l e s \\ | \/ n o d e _ m o d u l e s \/ / ) ) {
229- return null ;
230- }
231-
218+ renderChunk ( code : string , chunk : { fileName : string } ) {
232219 if (
233- ! [ ".js" , ".ts" , ".jsx" , ".tsx" , ".mjs" ] . some ( ( ending ) =>
234- idWithoutQueryAndHash . endsWith ( ending )
220+ // chunks could be any file (html, md, ...)
221+ [ ".js" , ".mjs" , ".cjs" ] . some ( ( ending ) =>
222+ stripQueryAndHashFromPath ( chunk . fileName ) . endsWith ( ending )
235223 )
236224 ) {
237- return null ;
238- }
225+ const ms = new MagicString ( code , { filename : chunk . fileName } ) ;
239226
240- const ms = new MagicString ( code ) ;
227+ const match = code . match ( COMMENT_USE_STRICT_REGEX ) ?. [ 0 ] ;
241228
242- // Appending instead of prepending has less probability of mucking with user's source maps.
243- // Luckily import statements get hoisted to the top anyways.
244- ms . append ( `\n\n;import "${ virtualReleaseInjectionFileId } ";` ) ;
229+ if ( match ) {
230+ // Add injected code after any comments or "use strict" at the beginning of the bundle.
231+ ms . appendLeft ( match . length , injectionCode ) ;
232+ } else {
233+ // ms.replace() doesn't work when there is an empty string match (which happens if
234+ // there is neither, a comment, nor a "use strict" at the top of the chunk) so we
235+ // need this special case here.
236+ ms . prepend ( injectionCode ) ;
237+ }
245238
246- return {
247- code : ms . toString ( ) ,
248- map : ms . generateMap ( { hires : "boundary" } ) ,
249- } ;
239+ return {
240+ code : ms . toString ( ) ,
241+ map : ms . generateMap ( { file : chunk . fileName , hires : "boundary" } ) ,
242+ } ;
243+ } else {
244+ return null ; // returning null means not modifying the chunk at all
245+ }
250246 } ,
251247 } ;
252248}
@@ -261,27 +257,6 @@ export function createRollupBundleSizeOptimizationHooks(replacementValues: Sentr
261257 } ;
262258}
263259
264- // We need to be careful not to inject the snippet before any `"use strict";`s.
265- // As an additional complication `"use strict";`s may come after any number of comments.
266- const COMMENT_USE_STRICT_REGEX =
267- // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
268- / ^ (?: \s * | \/ \* (?: .| \r | \n ) * ?\* \/ | \/ \/ .* [ \n \r ] ) * (?: " [ ^ " ] * " ; | ' [ ^ ' ] * ' ; ) ? / ;
269-
270- /**
271- * Simplified `renderChunk` hook type from Rollup.
272- * We can't reference the type directly because the Vite plugin complains
273- * about type mismatches
274- */
275- type RenderChunkHook = (
276- code : string ,
277- chunk : {
278- fileName : string ;
279- }
280- ) => {
281- code : string ;
282- map : SourceMap ;
283- } | null ;
284-
285260export function createRollupDebugIdInjectionHooks ( ) : {
286261 renderChunk : RenderChunkHook ;
287262} {
0 commit comments