@@ -2,7 +2,7 @@ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
22import { tmpdir } from 'node:os' ;
33import { join } from 'node:path' ;
44import { parse } from 'acorn' ;
5- import { afterEach , describe , expect , it } from 'vitest' ;
5+ import { afterEach , describe , expect , it , vi } from 'vitest' ;
66import { sentryCloudflareAutoInstrumentPlugin } from '../../src/vite/autoInstrument' ;
77
88function parseJS ( code : string ) {
@@ -55,6 +55,95 @@ describe('sentryCloudflareAutoInstrumentPlugin', () => {
5555 expect ( result . code ) . toContain ( '__SENTRY__.withSentry(' ) ;
5656 } ) ;
5757
58+ it ( 'wraps the entry with `@sentry/nextjs/cloudflare` in a vinext build' , async ( ) => {
59+ const dir = writeTempDir ( { 'wrangler.toml' : 'main = "src/index.ts"' } ) ;
60+ const plugin = sentryCloudflareAutoInstrumentPlugin ( ) ;
61+ plugin . configResolved ( { root : dir , plugins : [ { name : 'vinext:config' } ] } ) ;
62+ const resolve = vi
63+ . fn ( )
64+ . mockResolvedValue ( { id : join ( dir , 'node_modules/@sentry/nextjs/build/esm/cloudflare/index.js' ) } ) ;
65+
66+ const code = 'export default { fetch() { return new Response("ok"); } };' ;
67+ const result = await plugin . transform . call (
68+ { parse : ( c : string ) => parseJS ( c ) , resolve } ,
69+ code ,
70+ join ( dir , 'src/index.ts' ) ,
71+ ) ;
72+
73+ expect ( resolve ) . toHaveBeenCalledWith ( '@sentry/nextjs/cloudflare' , join ( dir , 'src/index.ts' ) ) ;
74+ expect ( result . code ) . toBe (
75+ "import * as __SENTRY__ from '@sentry/nextjs/cloudflare';\n" +
76+ 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' +
77+ 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n' ,
78+ ) ;
79+ } ) ;
80+
81+ it ( 'wraps the entry with `@sentry/cloudflare` when `@sentry/nextjs/cloudflare` resolves outside a vinext build' , async ( ) => {
82+ const dir = writeTempDir ( { 'wrangler.toml' : 'main = "src/index.ts"' } ) ;
83+ const plugin = sentryCloudflareAutoInstrumentPlugin ( ) ;
84+ plugin . configResolved ( { root : dir , plugins : [ { name : 'vite:react' } ] } ) ;
85+ const resolve = vi
86+ . fn ( )
87+ . mockResolvedValue ( { id : join ( dir , 'node_modules/@sentry/nextjs/build/esm/cloudflare/index.js' ) } ) ;
88+
89+ const code = 'export default { fetch() { return new Response("ok"); } };' ;
90+ const result = await plugin . transform . call (
91+ { parse : ( c : string ) => parseJS ( c ) , resolve } ,
92+ code ,
93+ join ( dir , 'src/index.ts' ) ,
94+ ) ;
95+
96+ expect ( result . code ) . toBe (
97+ "import * as __SENTRY__ from '@sentry/cloudflare';\n" +
98+ 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' +
99+ 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n' ,
100+ ) ;
101+ } ) ;
102+
103+ it ( 'wraps the entry with `@sentry/cloudflare` in a vinext build without `@sentry/nextjs`' , async ( ) => {
104+ const dir = writeTempDir ( { 'wrangler.toml' : 'main = "src/index.ts"' } ) ;
105+ const plugin = sentryCloudflareAutoInstrumentPlugin ( ) ;
106+ plugin . configResolved ( { root : dir , plugins : [ { name : 'vinext:config' } ] } ) ;
107+ const resolve = vi . fn ( ) . mockResolvedValue ( null ) ;
108+
109+ const code = 'export default { fetch() { return new Response("ok"); } };' ;
110+ const result = await plugin . transform . call (
111+ { parse : ( c : string ) => parseJS ( c ) , resolve } ,
112+ code ,
113+ join ( dir , 'src/index.ts' ) ,
114+ ) ;
115+
116+ expect ( result . code ) . toBe (
117+ "import * as __SENTRY__ from '@sentry/cloudflare';\n" +
118+ 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' +
119+ 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n' ,
120+ ) ;
121+ } ) ;
122+
123+ it ( 'wraps the entry with `@sentry/cloudflare` in a vinext build with an `@sentry/nextjs` without the `./cloudflare` entry' , async ( ) => {
124+ const dir = writeTempDir ( { 'wrangler.toml' : 'main = "src/index.ts"' } ) ;
125+ const plugin = sentryCloudflareAutoInstrumentPlugin ( ) ;
126+ plugin . configResolved ( { root : dir , plugins : [ { name : 'vinext:config' } ] } ) ;
127+ const resolve = vi
128+ . fn ( )
129+ . mockRejectedValue (
130+ new Error ( '"./cloudflare" is not exported under the conditions ["workerd"] from package @sentry/nextjs' ) ,
131+ ) ;
132+
133+ const code = 'export default { fetch() { return new Response("ok"); } };' ;
134+ const result = await plugin . transform . call (
135+ { parse : ( c : string ) => parseJS ( c ) , resolve } ,
136+ code ,
137+ join ( dir , 'src/index.ts' ) ,
138+ ) ;
139+
140+ expect ( result . code ) . toBe (
141+ "import * as __SENTRY__ from '@sentry/cloudflare';\n" +
142+ 'const __SENTRY_DEFAULT_EXPORT__ = { fetch() { return new Response("ok"); } };\n' +
143+ 'export default __SENTRY__.withSentry(() => undefined, __SENTRY_DEFAULT_EXPORT__);\n' ,
144+ ) ;
145+ } ) ;
146+
58147 it ( 'leaves an already-manually-wrapped entry untouched' , async ( ) => {
59148 const { transform : tx , entryPath } = createPlugin ( 'main = "src/index.ts"' ) ;
60149
0 commit comments