@@ -4,7 +4,7 @@ import * as fs from 'fs';
44import * as path from 'path' ;
55import type { RollupBuild , RollupError } from 'rollup' ;
66import { rollup } from 'rollup' ;
7- import type { ServerComponentContext , VercelCronsConfig } from '../../common/types' ;
7+ import type { ServerComponentContext } from '../../common/types' ;
88import type { LoaderThis } from './types' ;
99
1010// Just a simple placeholder to make referencing module consistent
@@ -13,12 +13,12 @@ const SENTRY_WRAPPER_MODULE_NAME = 'sentry-wrapper-module';
1313// Needs to end in .cjs in order for the `commonjs` plugin to pick it up
1414const WRAPPING_TARGET_MODULE_NAME = '__SENTRY_WRAPPING_TARGET_FILE__.cjs' ;
1515
16- const apiWrapperTemplatePath = path . resolve ( __dirname , '..' , 'templates' , 'apiWrapperTemplate.js' ) ;
17- const apiWrapperTemplateCode = fs . readFileSync ( apiWrapperTemplatePath , { encoding : 'utf8' } ) ;
18-
1916const pageWrapperTemplatePath = path . resolve ( __dirname , '..' , 'templates' , 'pageWrapperTemplate.js' ) ;
2017const pageWrapperTemplateCode = fs . readFileSync ( pageWrapperTemplatePath , { encoding : 'utf8' } ) ;
2118
19+ const edgeApiWrapperTemplatePath = path . resolve ( __dirname , '..' , 'templates' , 'edgeApiWrapperTemplate.js' ) ;
20+ const edgeApiWrapperTemplateCode = fs . readFileSync ( edgeApiWrapperTemplatePath , { encoding : 'utf8' } ) ;
21+
2222const middlewareWrapperTemplatePath = path . resolve ( __dirname , '..' , 'templates' , 'middlewareWrapperTemplate.js' ) ;
2323const middlewareWrapperTemplateCode = fs . readFileSync ( middlewareWrapperTemplatePath , { encoding : 'utf8' } ) ;
2424
@@ -40,17 +40,15 @@ export type WrappingLoaderOptions = {
4040 appDir : string | undefined ;
4141 pageExtensionRegex : string ;
4242 excludeServerRoutes : Array < RegExp | string > ;
43- wrappingTargetKind : 'page' | 'api-route' | 'middleware' | 'server-component' | 'route-handler' ;
44- vercelCronsConfig ?: VercelCronsConfig ;
43+ wrappingTargetKind : 'page' | 'edge-api-route' | 'middleware' | 'server-component' | 'route-handler' ;
4544 nextjsRequestAsyncStorageModulePath ?: string ;
4645} ;
4746
4847/**
4948 * Replace the loaded file with a wrapped version the original file. In the wrapped version, the original file is loaded,
50- * any data-fetching functions (`getInitialProps`, `getStaticProps`, and `getServerSideProps`) or API routes it contains
49+ * any data-fetching functions (`getInitialProps`, `getStaticProps`, and `getServerSideProps`) it contains
5150 * are wrapped, and then everything is re-exported.
5251 */
53- // eslint-disable-next-line complexity
5452export default function wrappingLoader (
5553 this : LoaderThis < WrappingLoaderOptions > ,
5654 userCode : string ,
@@ -64,15 +62,14 @@ export default function wrappingLoader(
6462 pageExtensionRegex,
6563 excludeServerRoutes = [ ] ,
6664 wrappingTargetKind,
67- vercelCronsConfig,
6865 nextjsRequestAsyncStorageModulePath,
6966 } = 'getOptions' in this ? this . getOptions ( ) : this . query ;
7067
7168 this . async ( ) ;
7269
7370 let templateCode : string ;
7471
75- if ( wrappingTargetKind === 'page' || wrappingTargetKind === 'api-route' ) {
72+ if ( wrappingTargetKind === 'page' ) {
7673 if ( pagesDir === undefined ) {
7774 this . callback ( null , userCode , userModuleSourceMap ) ;
7875 return ;
@@ -102,15 +99,41 @@ export default function wrappingLoader(
10299 return ;
103100 }
104101
105- if ( wrappingTargetKind === 'page' ) {
106- templateCode = pageWrapperTemplateCode ;
107- } else if ( wrappingTargetKind === 'api-route' ) {
108- templateCode = apiWrapperTemplateCode ;
109- } else {
110- throw new Error ( `Invariant: Could not get template code of unknown kind "${ wrappingTargetKind } "` ) ;
102+ templateCode = pageWrapperTemplateCode ;
103+
104+ // Inject the route and the path to the file we're wrapping into the template
105+ templateCode = templateCode . replace ( / _ _ R O U T E _ _ / g, parameterizedPagesRoute . replace ( / \\ / g, '\\\\' ) ) ;
106+ } else if ( wrappingTargetKind === 'edge-api-route' ) {
107+ if ( pagesDir === undefined ) {
108+ this . callback ( null , userCode , userModuleSourceMap ) ;
109+ return ;
110+ }
111+
112+ // Get the parameterized route name from this API route's filepath
113+ const parameterizedPagesRoute = path
114+ // Get the path of the file inside of the pages directory
115+ . relative ( pagesDir , this . resourcePath )
116+ // Replace all backslashes with forward slashes (windows)
117+ . replace ( / \\ / g, '/' )
118+ // Add a slash at the beginning
119+ . replace ( / ( .* ) / , '/$1' )
120+ // Pull off the file extension
121+ // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- not end user input
122+ . replace ( new RegExp ( `\\.(${ pageExtensionRegex } )` ) , '' )
123+ // Any page file named `index` corresponds to root of the directory its in, URL-wise, so turn `/xyz/index` into
124+ // just `/xyz`
125+ . replace ( / \/ i n d e x $ / , '' )
126+ // In case all of the above have left us with an empty string (which will happen if we're dealing with the
127+ // homepage), sub back in the root route
128+ . replace ( / ^ $ / , '/' ) ;
129+
130+ // Skip explicitly-ignored pages
131+ if ( stringMatchesSomePattern ( parameterizedPagesRoute , excludeServerRoutes , true ) ) {
132+ this . callback ( null , userCode , userModuleSourceMap ) ;
133+ return ;
111134 }
112135
113- templateCode = templateCode . replace ( / _ _ V E R C E L _ C R O N S _ C O N F I G U R A T I O N _ _ / g , JSON . stringify ( vercelCronsConfig ) ) ;
136+ templateCode = edgeApiWrapperTemplateCode ;
114137
115138 // Inject the route and the path to the file we're wrapping into the template
116139 templateCode = templateCode . replace ( / _ _ R O U T E _ _ / g, parameterizedPagesRoute . replace ( / \\ / g, '\\\\' ) ) ;
0 commit comments