@sentry/nextjs
Advanced tools
Comparing version 7.53.1 to 7.81.1
var { | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
@@ -14,11 +14,17 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const metadata = require('../common/metadata.js'); | ||
const performance = require('./performance.js'); | ||
const nextRoutingInstrumentation = require('./routing/nextRoutingInstrumentation.js'); | ||
const tunnelRoute = require('./tunnelRoute.js'); | ||
const _error = require('../common/_error.js'); | ||
const wrapGetInitialPropsWithSentry = require('./wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./wrapGetServerSidePropsWithSentry.js'); | ||
const wrapGetStaticPropsWithSentry = require('./wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetStaticPropsWithSentry = require('../common/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('../common/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('../common/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('../common/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('../common/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('../common/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('../common/wrapServerComponentWithSentry.js'); | ||
const wrapRouteHandlerWithSentry = require('../common/wrapRouteHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('../common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapMiddlewareWithSentry = require('../common/wrapMiddlewareWithSentry.js'); | ||
const wrapPageComponentWithSentry = require('../common/wrapPageComponentWithSentry.js'); | ||
const withServerActionInstrumentation = require('../common/withServerActionInstrumentation.js'); | ||
@@ -33,10 +39,13 @@ // Treeshakable guard to remove all code related to tracing | ||
function init(options) { | ||
tunnelRoute.applyTunnelRouteOption(options); | ||
metadata.buildMetadata(options, ['nextjs', 'react']); | ||
const opts = { | ||
environment: getVercelEnv.getVercelEnv(true) || process.env.NODE_ENV, | ||
...options, | ||
}; | ||
options.environment = options.environment || getVercelEnv.getVercelEnv(true) || process.env.NODE_ENV; | ||
tunnelRoute.applyTunnelRouteOption(opts); | ||
metadata.buildMetadata(opts, ['nextjs', 'react']); | ||
addClientIntegrations(options); | ||
addClientIntegrations(opts); | ||
react.init(options); | ||
react.init(opts); | ||
@@ -101,7 +110,7 @@ react.configureScope(scope => { | ||
tracingOrigins: [...react.defaultRequestInstrumentationOptions.tracingOrigins, /^(api\/)/], | ||
routingInstrumentation: performance.nextRouterInstrumentation, | ||
routingInstrumentation: nextRoutingInstrumentation.nextRouterInstrumentation, | ||
}); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultBrowserTracingIntegration, integrations$1, { | ||
'options.routingInstrumentation': performance.nextRouterInstrumentation, | ||
'options.routingInstrumentation': nextRoutingInstrumentation.nextRouterInstrumentation, | ||
}); | ||
@@ -123,4 +132,6 @@ } | ||
exports.Integrations = react.Integrations; | ||
exports.nextRouterInstrumentation = performance.nextRouterInstrumentation; | ||
exports.nextRouterInstrumentation = nextRoutingInstrumentation.nextRouterInstrumentation; | ||
exports.captureUnderscoreErrorException = _error.captureUnderscoreErrorException; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.withSentryServerSideGetInitialProps = wrapGetInitialPropsWithSentry.withSentryServerSideGetInitialProps; | ||
@@ -136,4 +147,8 @@ exports.wrapGetInitialPropsWithSentry = wrapGetInitialPropsWithSentry.wrapGetInitialPropsWithSentry; | ||
exports.wrapGetServerSidePropsWithSentry = wrapGetServerSidePropsWithSentry.wrapGetServerSidePropsWithSentry; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.wrapRouteHandlerWithSentry = wrapRouteHandlerWithSentry.wrapRouteHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapPageComponentWithSentry = wrapPageComponentWithSentry.wrapPageComponentWithSentry; | ||
exports.withServerActionInstrumentation = withServerActionInstrumentation.withServerActionInstrumentation; | ||
exports.init = init; | ||
@@ -140,0 +155,0 @@ exports.withSentryConfig = withSentryConfig; |
@@ -41,3 +41,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
type: 'instrument', | ||
handled: true, | ||
handled: false, | ||
data: { | ||
@@ -44,0 +44,0 @@ function: '_error.getInitialProps', |
var { | ||
_nullishCoalesce, | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const utils = require('@sentry/utils'); | ||
const stackTraceParser = require('stacktrace-parser'); | ||
const globalWithInjectedValues = utils.GLOBAL_OBJ | ||
; | ||
async function resolveStackFrame( | ||
@@ -28,2 +33,9 @@ frame, | ||
let basePath = _nullishCoalesce(globalWithInjectedValues.__sentryBasePath, () => ( '')); | ||
// Prefix the basepath with a slash if it doesn't have one | ||
if (basePath !== '' && !basePath.match(/^\//)) { | ||
basePath = `/${basePath}`; | ||
} | ||
const controller = new AbortController(); | ||
@@ -35,3 +47,3 @@ const timer = setTimeout(() => controller.abort(), 3000); | ||
typeof window === 'undefined' ? 'http://localhost:3000' : '' // TODO: handle the case where users define a different port | ||
}/__nextjs_original-stack-frame?${params.toString()}`, | ||
}${basePath}/__nextjs_original-stack-frame?${params.toString()}`, | ||
{ | ||
@@ -118,3 +130,3 @@ signal: controller.signal, | ||
const resolvedFrames = await Promise.all( | ||
frames.map(async frame => await resolveStackFrame(frame, hint.originalException )), | ||
frames.map(frame => resolveStackFrame(frame, hint.originalException )), | ||
); | ||
@@ -121,0 +133,0 @@ |
var { | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
@@ -12,2 +12,3 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function wrapApiHandlerWithSentryVercelCrons( | ||
@@ -18,2 +19,3 @@ handler, | ||
return new Proxy(handler, { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
apply: (originalFunction, thisArg, args) => { | ||
@@ -25,3 +27,4 @@ return core.runWithAsyncContext(() => { | ||
const [req] = args; | ||
core.addTracingExtensions(); | ||
const [req] = args ; | ||
@@ -28,0 +31,0 @@ let maybePromiseResult; |
@@ -18,3 +18,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
// Define some global proxy that works on server and on the browser. | ||
let injectedCode = 'var _sentryCollisionFreeGlobalObject = typeof window === "undefined" ? global : window;\n'; | ||
let injectedCode = | ||
'var _sentryCollisionFreeGlobalObject = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : {};\n'; | ||
@@ -21,0 +22,0 @@ Object.entries(values).forEach(([key, value]) => { |
@@ -0,1 +1,5 @@ | ||
var { | ||
_optionalChain | ||
} = require('@sentry/utils'); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
@@ -16,5 +20,2 @@ | ||
// Non-public API. Can be found here: https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts | ||
const NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH = 'next/dist/client/components/request-async-storage'; | ||
const apiWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'apiWrapperTemplate.js'); | ||
@@ -29,6 +30,7 @@ const apiWrapperTemplateCode = fs.readFileSync(apiWrapperTemplatePath, { encoding: 'utf8' }); | ||
const requestAsyncStorageShimPath = path.resolve(__dirname, '..', 'templates', 'requestAsyncStorageShim.js'); | ||
const requestAsyncStorageModuleExists = moduleExists(NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH); | ||
let showedMissingAsyncStorageModuleWarning = false; | ||
const sentryInitWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'sentryInitWrapperTemplate.js'); | ||
const sentryInitWrapperTemplateCode = fs.readFileSync(sentryInitWrapperTemplatePath, { encoding: 'utf8' }); | ||
const serverComponentWrapperTemplatePath = path.resolve( | ||
@@ -42,10 +44,4 @@ __dirname, | ||
function moduleExists(id) { | ||
try { | ||
require.resolve(id); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
const routeHandlerWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'routeHandlerWrapperTemplate.js'); | ||
const routeHandlerWrapperTemplateCode = fs.readFileSync(routeHandlerWrapperTemplatePath, { encoding: 'utf8' }); | ||
@@ -61,2 +57,3 @@ /** | ||
userCode, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
userModuleSourceMap, | ||
@@ -73,2 +70,3 @@ ) { | ||
vercelCronsConfig, | ||
nextjsRequestAsyncStorageModulePath, | ||
} = 'getOptions' in this ? this.getOptions() : this.query; | ||
@@ -80,10 +78,30 @@ | ||
if (wrappingTargetKind === 'page' || wrappingTargetKind === 'api-route') { | ||
if (wrappingTargetKind === 'sentry-init') { | ||
templateCode = sentryInitWrapperTemplateCode; | ||
// Absolute paths to the sentry config do not work with Windows: https://github.com/getsentry/sentry-javascript/issues/8133 | ||
// Se we need check whether `this.resourcePath` is absolute because there is no contract by webpack that says it is absolute. | ||
// Examples where `this.resourcePath` could possibly be non-absolute are virtual modules. | ||
if (sentryConfigFilePath && path.isAbsolute(this.resourcePath)) { | ||
const sentryConfigImportPath = path | ||
.relative(path.dirname(this.resourcePath), sentryConfigFilePath) | ||
.replace(/\\/g, '/'); | ||
// path.relative() may return something like `sentry.server.config.js` which is not allowed. Imports from the | ||
// current directory need to start with './'.This is why we prepend the path with './', which should always again | ||
// be a valid relative path. | ||
// https://github.com/getsentry/sentry-javascript/issues/8798 | ||
templateCode = templateCode.replace(/__SENTRY_CONFIG_IMPORT_PATH__/g, `./${sentryConfigImportPath}`); | ||
} else { | ||
// Bail without doing any wrapping | ||
this.callback(null, userCode, userModuleSourceMap); | ||
return; | ||
} | ||
} else if (wrappingTargetKind === 'page' || wrappingTargetKind === 'api-route') { | ||
// Get the parameterized route name from this page's filepath | ||
const parameterizedPagesRoute = path.posix | ||
.normalize( | ||
path | ||
// Get the path of the file insde of the pages directory | ||
.relative(pagesDir, this.resourcePath), | ||
) | ||
const parameterizedPagesRoute = path | ||
// Get the path of the file insde of the pages directory | ||
.relative(pagesDir, this.resourcePath) | ||
// Replace all backslashes with forward slashes (windows) | ||
.replace(/\\/g, '/') | ||
// Add a slash at the beginning | ||
@@ -118,10 +136,13 @@ .replace(/(.*)/, '/$1') | ||
templateCode = templateCode.replace(/__ROUTE__/g, parameterizedPagesRoute.replace(/\\/g, '\\\\')); | ||
} else if (wrappingTargetKind === 'server-component') { | ||
} else if (wrappingTargetKind === 'server-component' || wrappingTargetKind === 'route-handler') { | ||
// Get the parameterized route name from this page's filepath | ||
const parameterizedPagesRoute = path.posix | ||
.normalize(path.relative(appDir, this.resourcePath)) | ||
const parameterizedPagesRoute = path | ||
// Get the path of the file insde of the app directory | ||
.relative(appDir, this.resourcePath) | ||
// Replace all backslashes with forward slashes (windows) | ||
.replace(/\\/g, '/') | ||
// Add a slash at the beginning | ||
.replace(/(.*)/, '/$1') | ||
// Pull off the file name | ||
.replace(/\/[^/]+\.(js|jsx|tsx)$/, '') | ||
.replace(/\/[^/]+\.(js|ts|jsx|tsx)$/, '') | ||
// Remove routing groups: https://beta.nextjs.org/docs/routing/defining-routes#example-creating-multiple-root-layouts | ||
@@ -148,8 +169,12 @@ .replace(/\/(\(.*?\)\/)+/g, '/') | ||
templateCode = serverComponentWrapperTemplateCode; | ||
if (wrappingTargetKind === 'server-component') { | ||
templateCode = serverComponentWrapperTemplateCode; | ||
} else { | ||
templateCode = routeHandlerWrapperTemplateCode; | ||
} | ||
if (requestAsyncStorageModuleExists) { | ||
if (nextjsRequestAsyncStorageModulePath !== undefined) { | ||
templateCode = templateCode.replace( | ||
/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, | ||
NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH, | ||
nextjsRequestAsyncStorageModulePath, | ||
); | ||
@@ -166,3 +191,6 @@ } else { | ||
} | ||
templateCode = templateCode.replace(/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, requestAsyncStorageShimPath); | ||
templateCode = templateCode.replace( | ||
/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, | ||
'@sentry/nextjs/esm/config/templates/requestAsyncStorageShim.js', | ||
); | ||
} | ||
@@ -174,3 +202,3 @@ | ||
.normalize(path.relative(appDir, this.resourcePath)) | ||
.match(/\/?([^/]+)\.(?:js|jsx|tsx)$/); | ||
.match(/\/?([^/]+)\.(?:js|ts|jsx|tsx)$/); | ||
@@ -203,11 +231,2 @@ if (componentTypeMatch && componentTypeMatch[1]) { | ||
} | ||
// We check whether `this.resourcePath` is absolute because there is no contract by webpack that says it is absolute, | ||
// however we can only create relative paths to the sentry config from absolute paths.Examples where this could possibly be non - absolute are virtual modules. | ||
if (sentryConfigFilePath && path.isAbsolute(this.resourcePath)) { | ||
const sentryConfigImportPath = path | ||
.relative(path.dirname(this.resourcePath), sentryConfigFilePath) // Absolute paths do not work with Windows: https://github.com/getsentry/sentry-javascript/issues/8133 | ||
.replace(/\\/g, '/'); | ||
templateCode = `import "${sentryConfigImportPath}";\n`.concat(templateCode); | ||
} | ||
} else if (wrappingTargetKind === 'middleware') { | ||
@@ -254,83 +273,101 @@ templateCode = middlewareWrapperTemplateCode; | ||
userModuleCode, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
userModuleSourceMap, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
) { | ||
const rollupBuild = await rollup.rollup({ | ||
input: SENTRY_WRAPPER_MODULE_NAME, | ||
const wrap = (withDefaultExport) => | ||
rollup.rollup({ | ||
input: SENTRY_WRAPPER_MODULE_NAME, | ||
plugins: [ | ||
// We're using a simple custom plugin that virtualizes our wrapper module and the user module, so we don't have to | ||
// mess around with file paths and so that we can pass the original user module source map to rollup so that | ||
// rollup gives us a bundle with correct source mapping to the original file | ||
{ | ||
name: 'virtualize-sentry-wrapper-modules', | ||
resolveId: id => { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME || id === WRAPPING_TARGET_MODULE_NAME) { | ||
return id; | ||
} else { | ||
return null; | ||
} | ||
plugins: [ | ||
// We're using a simple custom plugin that virtualizes our wrapper module and the user module, so we don't have to | ||
// mess around with file paths and so that we can pass the original user module source map to rollup so that | ||
// rollup gives us a bundle with correct source mapping to the original file | ||
{ | ||
name: 'virtualize-sentry-wrapper-modules', | ||
resolveId: id => { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME || id === WRAPPING_TARGET_MODULE_NAME) { | ||
return id; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
load(id) { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME) { | ||
return withDefaultExport ? wrapperCode : wrapperCode.replace('export { default } from', 'export {} from'); | ||
} else if (id === WRAPPING_TARGET_MODULE_NAME) { | ||
return { | ||
code: userModuleCode, | ||
map: userModuleSourceMap, // give rollup acces to original user module source map | ||
}; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
}, | ||
load(id) { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME) { | ||
return wrapperCode; | ||
} else if (id === WRAPPING_TARGET_MODULE_NAME) { | ||
return { | ||
code: userModuleCode, | ||
map: userModuleSourceMap, // give rollup acces to original user module source map | ||
}; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
}, | ||
// People may use `module.exports` in their API routes or page files. Next.js allows that and we also need to | ||
// handle that correctly so we let a plugin to take care of bundling cjs exports for us. | ||
commonjs.default({ | ||
sourceMap: true, | ||
strictRequires: true, // Don't hoist require statements that users may define | ||
ignoreDynamicRequires: true, // Don't break dynamic requires and things like Webpack's `require.context` | ||
ignore() { | ||
// We want basically only want to use this plugin for handling the case where users export their handlers with module.exports. | ||
// This plugin would also be able to convert any `require` into something esm compatible but webpack does that anyways so we just skip that part of the plugin. | ||
// (Also, modifying require may break user code) | ||
return true; | ||
}, | ||
}), | ||
], | ||
// People may use `module.exports` in their API routes or page files. Next.js allows that and we also need to | ||
// handle that correctly so we let a plugin to take care of bundling cjs exports for us. | ||
commonjs.default({ | ||
sourceMap: true, | ||
strictRequires: true, // Don't hoist require statements that users may define | ||
ignoreDynamicRequires: true, // Don't break dynamic requires and things like Webpack's `require.context` | ||
ignore() { | ||
// We basically only want to use this plugin for handling the case where users export their handlers with module.exports. | ||
// This plugin would also be able to convert any `require` into something esm compatible but webpack does that anyways so we just skip that part of the plugin. | ||
// (Also, modifying require may break user code) | ||
return true; | ||
}, | ||
}), | ||
], | ||
// We only want to bundle our wrapper module and the wrappee module into one, so we mark everything else as external. | ||
external: sourceId => sourceId !== SENTRY_WRAPPER_MODULE_NAME && sourceId !== WRAPPING_TARGET_MODULE_NAME, | ||
// We only want to bundle our wrapper module and the wrappee module into one, so we mark everything else as external. | ||
external: sourceId => sourceId !== SENTRY_WRAPPER_MODULE_NAME && sourceId !== WRAPPING_TARGET_MODULE_NAME, | ||
// Prevent rollup from stressing out about TS's use of global `this` when polyfilling await. (TS will polyfill if the | ||
// user's tsconfig `target` is set to anything before `es2017`. See https://stackoverflow.com/a/72822340 and | ||
// https://stackoverflow.com/a/60347490.) | ||
context: 'this', | ||
// Prevent rollup from stressing out about TS's use of global `this` when polyfilling await. (TS will polyfill if the | ||
// user's tsconfig `target` is set to anything before `es2017`. See https://stackoverflow.com/a/72822340 and | ||
// https://stackoverflow.com/a/60347490.) | ||
context: 'this', | ||
// Rollup's path-resolution logic when handling re-exports can go wrong when wrapping pages which aren't at the root | ||
// level of the `pages` directory. This may be a bug, as it doesn't match the behavior described in the docs, but what | ||
// seems to happen is this: | ||
// | ||
// - We try to wrap `pages/xyz/userPage.js`, which contains `export { helperFunc } from '../../utils/helper'` | ||
// - Rollup converts '../../utils/helper' into an absolute path | ||
// - We mark the helper module as external | ||
// - Rollup then converts it back to a relative path, but relative to `pages/` rather than `pages/xyz/`. (This is | ||
// the part which doesn't match the docs. They say that Rollup will use the common ancestor of all modules in the | ||
// bundle as the basis for the relative path calculation, but both our temporary file and the page being wrapped | ||
// live in `pages/xyz/`, and they're the only two files in the bundle, so `pages/xyz/`` should be used as the | ||
// root. Unclear why it's not.) | ||
// - As a result of the miscalculation, our proxy module will include `export { helperFunc } from '../utils/helper'` | ||
// rather than the expected `export { helperFunc } from '../../utils/helper'`, thereby causing a build error in | ||
// nextjs.. | ||
// | ||
// Setting `makeAbsoluteExternalsRelative` to `false` prevents all of the above by causing Rollup to ignore imports of | ||
// externals entirely, with the result that their paths remain untouched (which is what we want). | ||
makeAbsoluteExternalsRelative: false, | ||
// Rollup's path-resolution logic when handling re-exports can go wrong when wrapping pages which aren't at the root | ||
// level of the `pages` directory. This may be a bug, as it doesn't match the behavior described in the docs, but what | ||
// seems to happen is this: | ||
// | ||
// - We try to wrap `pages/xyz/userPage.js`, which contains `export { helperFunc } from '../../utils/helper'` | ||
// - Rollup converts '../../utils/helper' into an absolute path | ||
// - We mark the helper module as external | ||
// - Rollup then converts it back to a relative path, but relative to `pages/` rather than `pages/xyz/`. (This is | ||
// the part which doesn't match the docs. They say that Rollup will use the common ancestor of all modules in the | ||
// bundle as the basis for the relative path calculation, but both our temporary file and the page being wrapped | ||
// live in `pages/xyz/`, and they're the only two files in the bundle, so `pages/xyz/`` should be used as the | ||
// root. Unclear why it's not.) | ||
// - As a result of the miscalculation, our proxy module will include `export { helperFunc } from '../utils/helper'` | ||
// rather than the expected `export { helperFunc } from '../../utils/helper'`, thereby causing a build error in | ||
// nextjs.. | ||
// | ||
// Setting `makeAbsoluteExternalsRelative` to `false` prevents all of the above by causing Rollup to ignore imports of | ||
// externals entirely, with the result that their paths remain untouched (which is what we want). | ||
makeAbsoluteExternalsRelative: false, | ||
onwarn: (_warning, _warn) => { | ||
// Suppress all warnings - we don't want to bother people with this output | ||
// Might be stuff like "you have unused imports" | ||
// _warn(_warning); // uncomment to debug | ||
}, | ||
}); | ||
onwarn: (_warning, _warn) => { | ||
// Suppress all warnings - we don't want to bother people with this output | ||
// Might be stuff like "you have unused imports" | ||
// _warn(_warning); // uncomment to debug | ||
}, | ||
}); | ||
// Next.js sometimes complains if you define a default export (e.g. in route handlers in dev mode). | ||
// This is why we want to avoid unnecessarily creating default exports, even if they're just `undefined`. | ||
// For this reason we try to bundle/wrap the user code once including a re-export of `default`. | ||
// If the user code didn't have a default export, rollup will throw. | ||
// We then try bundling/wrapping agian, but without including a re-export of `default`. | ||
let rollupBuild; | ||
try { | ||
rollupBuild = await wrap(true); | ||
} catch (e) { | ||
if (_optionalChain([(e ), 'optionalAccess', _ => _.code]) === 'MISSING_EXPORT') { | ||
rollupBuild = await wrap(false); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -337,0 +374,0 @@ const finalBundle = await rollupBuild.generate({ |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -13,3 +13,3 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userApiModule = origModule ; | ||
const userApiModule = routeModule ; | ||
@@ -16,0 +16,0 @@ // Default to undefined. It's possible for Next.js users to not define any exports/handlers in an API route. If that is |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -12,3 +12,3 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userApiModule = origModule ; | ||
const userApiModule = routeModule ; | ||
@@ -15,0 +15,0 @@ // Default to undefined. It's possible for Next.js users to not define any exports/handlers in an API route. If that is |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -13,10 +13,11 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userPageModule = origModule ; | ||
const userPageModule = routeModule ; | ||
const pageComponent = userPageModule.default; | ||
const pageComponent = userPageModule ? userPageModule.default : undefined; | ||
const origGetInitialProps = pageComponent.getInitialProps; | ||
const origGetStaticProps = userPageModule.getStaticProps; | ||
const origGetServerSideProps = userPageModule.getServerSideProps; | ||
const origGetInitialProps = pageComponent ? pageComponent.getInitialProps : undefined; | ||
const origGetStaticProps = userPageModule ? userPageModule.getStaticProps : undefined; | ||
const origGetServerSideProps = userPageModule ? userPageModule.getServerSideProps : undefined; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const getInitialPropsWrappers = { | ||
@@ -30,3 +31,3 @@ '/_app': Sentry.wrapAppGetInitialPropsWithSentry, | ||
if (typeof origGetInitialProps === 'function') { | ||
if (pageComponent && typeof origGetInitialProps === 'function') { | ||
pageComponent.getInitialProps = getInitialPropsWrapper(origGetInitialProps) ; | ||
@@ -44,2 +45,4 @@ } | ||
export { pageComponent as default, getServerSideProps, getStaticProps }; | ||
const pageWrapperTemplate = pageComponent ? Sentry.wrapPageComponentWithSentry(pageComponent ) : pageComponent; | ||
export { pageWrapperTemplate as default, getServerSideProps, getStaticProps }; |
@@ -1,7 +0,1 @@ | ||
const requestAsyncStorage = { | ||
getStore: () => { | ||
return undefined; | ||
}, | ||
}; | ||
export { requestAsyncStorage }; |
@@ -1,8 +0,8 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { requestAsyncStorage } from '__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__'; | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as Sentry from '@sentry/nextjs'; | ||
const serverComponent = origModule.default; | ||
const serverComponent = routeModule.default; | ||
@@ -19,3 +19,3 @@ let wrappedServerComponent; | ||
// We try-catch here just in case the API around `requestAsyncStorage` changes unexpectedly since it is not public API | ||
// We try-catch here just in `requestAsyncStorage` is undefined since it may not be defined | ||
try { | ||
@@ -22,0 +22,0 @@ const requestAsyncStore = requestAsyncStorage.getStore(); |
var { | ||
_nullishCoalesce, | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
@@ -10,6 +10,6 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const utils = require('@sentry/utils'); | ||
const SentryWebpackPlugin = require('@sentry/webpack-plugin'); | ||
const chalk = require('chalk'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const resolve = require('resolve'); | ||
@@ -30,2 +30,3 @@ /* eslint-disable complexity */ | ||
let showedHiddenSourceMapsWarningMsg = false; | ||
let showedMissingCliBinaryWarningMsg = false; | ||
@@ -76,3 +77,3 @@ // TODO: merge default SentryWebpackPlugin ignore with their SentryWebpackPlugin ignore or ignoreFile | ||
// Add a loader which will inject code that sets global values | ||
addValueInjectionLoader(newConfig, userNextConfig, userSentryOptions, buildContext); | ||
addValueInjectionLoader(newConfig, userNextConfig, userSentryOptions, buildContext, userSentryWebpackPluginOptions); | ||
@@ -107,3 +108,3 @@ newConfig.module.rules.push({ | ||
const apiRoutesPath = path.join(pagesDirPath, 'api', '/'); | ||
const apiRoutesPath = path.join(pagesDirPath, 'api'); | ||
@@ -124,2 +125,6 @@ const middlewareJsPath = path.join(pagesDirPath, '..', 'middleware.js'); | ||
sentryConfigFilePath: getUserConfigFilePath(projectDir, runtime), | ||
nextjsRequestAsyncStorageModulePath: getRequestAsyncStorageModuleLocation( | ||
projectDir, | ||
_optionalChain([rawNewConfig, 'access', _ => _.resolve, 'optionalAccess', _2 => _2.modules]), | ||
), | ||
}; | ||
@@ -139,2 +144,43 @@ | ||
const isPageResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(pagesDirPath + path.sep) && | ||
!normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}; | ||
const isApiRouteResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}; | ||
const isMiddlewareResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return normalizedAbsoluteResourcePath === middlewareJsPath || normalizedAbsoluteResourcePath === middlewareTsPath; | ||
}; | ||
const isServerComponentResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
// ".js, .jsx, or .tsx file extensions can be used for Pages" | ||
// https://beta.nextjs.org/docs/routing/pages-and-layouts#pages:~:text=.js%2C%20.jsx%2C%20or%20.tsx%20file%20extensions%20can%20be%20used%20for%20Pages. | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/](page|layout|loading|head|not-found)\.(js|jsx|tsx)$/) | ||
); | ||
}; | ||
const isRouteHandlerResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/]route\.(js|jsx|ts|tsx)$/) | ||
); | ||
}; | ||
if (isServer && userSentryOptions.autoInstrumentServerFunctions !== false) { | ||
@@ -145,10 +191,3 @@ // It is very important that we insert our loaders at the beginning of the array because we expect any sort of transformations/transpilations (e.g. TS -> JS) to already have happened. | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(pagesDirPath) && | ||
!normalizedAbsoluteResourcePath.startsWith(apiRoutesPath) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}, | ||
test: isPageResource, | ||
use: [ | ||
@@ -181,4 +220,3 @@ { | ||
} catch (e) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (e.code === 'ENOENT') ; else { | ||
if ((e ).code === 'ENOENT') ; else { | ||
// log but noop | ||
@@ -191,9 +229,3 @@ utils.logger.error(`${chalk.red('error')} - Sentry failed to read vercel.json`, e); | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(apiRoutesPath) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}, | ||
test: isApiRouteResource, | ||
use: [ | ||
@@ -212,9 +244,22 @@ { | ||
// Wrap middleware | ||
if (_nullishCoalesce(userSentryOptions.autoInstrumentMiddleware, () => ( true))) { | ||
newConfig.module.rules.unshift({ | ||
test: isMiddlewareResource, | ||
use: [ | ||
{ | ||
loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'), | ||
options: { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'middleware', | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
} | ||
if (isServer && userSentryOptions.autoInstrumentAppDirectory !== false) { | ||
// Wrap server components | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath === middlewareJsPath || normalizedAbsoluteResourcePath === middlewareTsPath | ||
); | ||
}, | ||
test: isServerComponentResource, | ||
use: [ | ||
@@ -225,3 +270,3 @@ { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'middleware', | ||
wrappingTargetKind: 'server-component', | ||
}, | ||
@@ -231,15 +276,28 @@ }, | ||
}); | ||
// Wrap route handlers | ||
newConfig.module.rules.unshift({ | ||
test: isRouteHandlerResource, | ||
use: [ | ||
{ | ||
loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'), | ||
options: { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'route-handler', | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
if (isServer && userSentryOptions.autoInstrumentAppDirectory !== false) { | ||
// Wrap page server components | ||
if (isServer) { | ||
// Import the Sentry config in every user file | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
// ".js, .jsx, or .tsx file extensions can be used for Pages" | ||
// https://beta.nextjs.org/docs/routing/pages-and-layouts#pages:~:text=.js%2C%20.jsx%2C%20or%20.tsx%20file%20extensions%20can%20be%20used%20for%20Pages. | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/](page|layout|loading|head|not-found)\.(js|jsx|tsx)$/) | ||
isPageResource(resourcePath) || | ||
isApiRouteResource(resourcePath) || | ||
isMiddlewareResource(resourcePath) || | ||
isServerComponentResource(resourcePath) || | ||
isRouteHandlerResource(resourcePath) | ||
); | ||
@@ -252,3 +310,3 @@ }, | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'server-component', | ||
wrappingTargetKind: 'sentry-init', | ||
}, | ||
@@ -264,5 +322,5 @@ }, | ||
// fairly massively. | ||
if (!isServer && _optionalChain([userSentryOptions, 'optionalAccess', _ => _.transpileClientSDK])) { | ||
if (!isServer && _optionalChain([userSentryOptions, 'optionalAccess', _3 => _3.transpileClientSDK])) { | ||
// Find all loaders which apply transpilation to user code | ||
const transpilationRules = findTranspilationRules(_optionalChain([newConfig, 'access', _2 => _2.module, 'optionalAccess', _3 => _3.rules]), projectDir); | ||
const transpilationRules = findTranspilationRules(_optionalChain([newConfig, 'access', _4 => _4.module, 'optionalAccess', _5 => _5.rules]), projectDir); | ||
@@ -320,8 +378,13 @@ // For each matching rule, wrap its `exclude` function so that it won't exclude SDK files, even though they're in | ||
newConfig.plugins = newConfig.plugins || []; | ||
newConfig.plugins.push( | ||
new SentryWebpackPlugin.default( | ||
getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions), | ||
), | ||
); | ||
const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin'); | ||
if (SentryWebpackPlugin) { | ||
newConfig.plugins = newConfig.plugins || []; | ||
newConfig.plugins.push(new SentryCliDownloadPlugin()); | ||
newConfig.plugins.push( | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know about it | ||
new SentryWebpackPlugin( | ||
getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions), | ||
), | ||
); | ||
} | ||
} | ||
@@ -372,3 +435,3 @@ } | ||
// 'next-babel-loader', so we can use the same regex to test for both. | ||
if (!useEntries.some(entry => _optionalChain([entry, 'optionalAccess', _4 => _4.loader]) && new RegExp('next.*(babel|swc).*loader').test(entry.loader))) { | ||
if (!useEntries.some(entry => _optionalChain([entry, 'optionalAccess', _6 => _6.loader]) && new RegExp('next.*(babel|swc).*loader').test(entry.loader))) { | ||
return false; | ||
@@ -430,3 +493,3 @@ } | ||
const { isServer, dir: projectDir, nextRuntime } = buildContext; | ||
const { isServer, dir: projectDir, nextRuntime, dev: isDevMode } = buildContext; | ||
const runtime = isServer ? (buildContext.nextRuntime === 'edge' ? 'edge' : 'node') : 'browser'; | ||
@@ -450,4 +513,4 @@ | ||
for (const entryPointName in newEntryProperty) { | ||
if (shouldAddSentryToEntryPoint(entryPointName, runtime, _nullishCoalesce(userSentryOptions.excludeServerRoutes, () => ( [])))) { | ||
addFilesToExistingEntryPoint(newEntryProperty, entryPointName, filesToInject); | ||
if (shouldAddSentryToEntryPoint(entryPointName, runtime)) { | ||
addFilesToExistingEntryPoint(newEntryProperty, entryPointName, filesToInject, isDevMode); | ||
} else { | ||
@@ -520,3 +583,3 @@ if ( | ||
* @param entryPointName The key where the file should be injected | ||
* @param filepaths An array of paths to the injected files | ||
* @param filesToInsert An array of paths to the injected files | ||
*/ | ||
@@ -526,4 +589,9 @@ function addFilesToExistingEntryPoint( | ||
entryPointName, | ||
filepaths, | ||
filesToInsert, | ||
isDevMode, | ||
) { | ||
// BIG FAT NOTE: Order of insertion seems to matter here. If we insert the new files before the `currentEntrypoint`s, | ||
// the Next.js dev server breaks. Because we generally still want the SDK to be initialized as early as possible we | ||
// still keep it at the start of the entrypoints if we are not in dev mode. | ||
// can be a string, array of strings, or object whose `import` property is one of those two | ||
@@ -533,6 +601,12 @@ const currentEntryPoint = entryProperty[entryPointName]; | ||
if (typeof currentEntryPoint === 'string') { | ||
newEntryPoint = [...filepaths, currentEntryPoint]; | ||
} else if (Array.isArray(currentEntryPoint)) { | ||
newEntryPoint = [...filepaths, ...currentEntryPoint]; | ||
if (typeof currentEntryPoint === 'string' || Array.isArray(currentEntryPoint)) { | ||
newEntryPoint = utils.arrayify(currentEntryPoint); | ||
if (isDevMode) { | ||
// Inserting at beginning breaks dev mode so we insert at the end | ||
newEntryPoint.push(...filesToInsert); | ||
} else { | ||
// In other modes we insert at the beginning so that the SDK initializes as early as possible | ||
newEntryPoint.unshift(...filesToInsert); | ||
} | ||
} | ||
@@ -542,8 +616,10 @@ // descriptor object (webpack 5+) | ||
const currentImportValue = currentEntryPoint.import; | ||
let newImportValue; | ||
const newImportValue = utils.arrayify(currentImportValue); | ||
if (typeof currentImportValue === 'string') { | ||
newImportValue = [...filepaths, currentImportValue]; | ||
if (isDevMode) { | ||
// Inserting at beginning breaks dev mode so we insert at the end | ||
newImportValue.push(...filesToInsert); | ||
} else { | ||
newImportValue = [...filepaths, ...currentImportValue]; | ||
// In other modes we insert at the beginning so that the SDK initializes as early as possible | ||
newImportValue.unshift(...filesToInsert); | ||
} | ||
@@ -603,35 +679,9 @@ | ||
*/ | ||
function shouldAddSentryToEntryPoint( | ||
entryPointName, | ||
runtime, | ||
excludeServerRoutes, | ||
) { | ||
// On the server side, by default we inject the `Sentry.init()` code into every page (with a few exceptions). | ||
if (runtime === 'node') { | ||
// User-specified pages to skip. (Note: For ease of use, `excludeServerRoutes` is specified in terms of routes, | ||
// which don't have the `pages` prefix.) | ||
const entryPointRoute = entryPointName.replace(/^pages/, ''); | ||
if (utils.stringMatchesSomePattern(entryPointRoute, excludeServerRoutes, true)) { | ||
return false; | ||
} | ||
// This expression will implicitly include `pages/_app` which is called for all serverside routes and pages | ||
// regardless whether or not the user has a`_app` file. | ||
return entryPointName.startsWith('pages/'); | ||
} else if (runtime === 'browser') { | ||
return ( | ||
// entrypoint for `/pages` pages - this is included on all clientside pages | ||
// It's important that we inject the SDK into this file and not into 'main' because in 'main' | ||
// some important Next.js code (like the setup code for getCongig()) is located and some users | ||
// may need this code inside their Sentry configs | ||
entryPointName === 'pages/_app' || | ||
function shouldAddSentryToEntryPoint(entryPointName, runtime) { | ||
return ( | ||
runtime === 'browser' && | ||
(entryPointName === 'pages/_app' || | ||
// entrypoint for `/app` pages | ||
entryPointName === 'main-app' | ||
); | ||
} else { | ||
// User-specified pages to skip. (Note: For ease of use, `excludeServerRoutes` is specified in terms of routes, | ||
// which don't have the `pages` prefix.) | ||
const entryPointRoute = entryPointName.replace(/^pages/, ''); | ||
return !utils.stringMatchesSomePattern(entryPointRoute, excludeServerRoutes, true); | ||
} | ||
entryPointName === 'main-app') | ||
); | ||
} | ||
@@ -652,3 +702,3 @@ | ||
) { | ||
const { buildId, isServer, webpack, config, dir: projectDir } = buildContext; | ||
const { buildId, isServer, config, dir: projectDir } = buildContext; | ||
const userNextConfig = config ; | ||
@@ -658,3 +708,2 @@ | ||
const isWebpack5 = webpack.version.startsWith('5'); | ||
const isServerless = userNextConfig.target === 'experimental-serverless-trace'; | ||
@@ -666,9 +715,6 @@ const hasSentryProperties = fs.existsSync(path.resolve(projectDir, 'sentry.properties')); | ||
? [{ paths: [`${distDirAbsPath}/serverless/`], urlPrefix: `${urlPrefix}/serverless` }] | ||
: [ | ||
{ paths: [`${distDirAbsPath}/server/pages/`], urlPrefix: `${urlPrefix}/server/pages` }, | ||
{ paths: [`${distDirAbsPath}/server/app/`], urlPrefix: `${urlPrefix}/server/app` }, | ||
].concat( | ||
isWebpack5 ? [{ paths: [`${distDirAbsPath}/server/chunks/`], urlPrefix: `${urlPrefix}/server/chunks` }] : [], | ||
); | ||
: [{ paths: [`${distDirAbsPath}/server/`], urlPrefix: `${urlPrefix}/server` }]; | ||
const serverIgnore = []; | ||
const clientInclude = userSentryOptions.widenClientFileUpload | ||
@@ -681,11 +727,12 @@ ? [{ paths: [`${distDirAbsPath}/static/chunks`], urlPrefix: `${urlPrefix}/static/chunks` }] | ||
// Widening the upload scope is necessarily going to lead to us uploading files we don't need to (ones which | ||
// don't include any user code). In order to lessen that where we can, exclude the internal nextjs files we know | ||
// will be there. | ||
const clientIgnore = userSentryOptions.widenClientFileUpload | ||
? ['framework-*', 'framework.*', 'main-*', 'polyfills-*', 'webpack-*'] | ||
: []; | ||
const defaultPluginOptions = utils.dropUndefinedKeys({ | ||
include: isServer ? serverInclude : clientInclude, | ||
ignore: | ||
isServer || !userSentryOptions.widenClientFileUpload | ||
? [] | ||
: // Widening the upload scope is necessarily going to lead to us uploading files we don't need to (ones which | ||
// don't include any user code). In order to lessen that where we can, exclude the internal nextjs files we know | ||
// will be there. | ||
['framework-*', 'framework.*', 'main-*', 'polyfills-*', 'webpack-*'], | ||
ignore: isServer ? serverIgnore : clientIgnore, | ||
url: process.env.SENTRY_URL, | ||
@@ -711,2 +758,15 @@ org: process.env.SENTRY_ORG, | ||
if (err.message.includes('ENOENT')) { | ||
if (!showedMissingCliBinaryWarningMsg) { | ||
// eslint-disable-next-line no-console | ||
console.error( | ||
`\n${errorMessagePrefix} ${chalk.bold( | ||
'The Sentry binary to upload sourcemaps could not be found.', | ||
)} Source maps will not be uploaded. Please check that post-install scripts are enabled in your package manager when installing your dependencies and please run your build once without any caching to avoid caching issues of dependencies.\n`, | ||
); | ||
showedMissingCliBinaryWarningMsg = true; | ||
} | ||
return; | ||
} | ||
// Hardcoded way to check for missing auth token until we have a better way of doing this. | ||
@@ -808,18 +868,2 @@ if (err.message.includes('Authentication credentials were not provided.')) { | ||
/** Non-negotiable */ | ||
// This check is necessary because currently, `@sentry/cli` uses a post-install script to download an | ||
// architecture-specific version of the `sentry-cli` binary. If `yarn install`, `npm install`, or `npm ci` are run | ||
// with the `--ignore-scripts` option, this will be blocked and the missing binary will cause an error when users | ||
// try to build their apps. | ||
if (!SentryWebpackPlugin.default.cliBinaryExists()) { | ||
// eslint-disable-next-line no-console | ||
console.error( | ||
`${chalk.red('error')} - ${chalk.bold('Sentry CLI binary not found.')} Source maps will not be uploaded.\n`, | ||
); | ||
return false; | ||
} | ||
/** User override */ | ||
if (isServer && disableServerWebpackPlugin !== undefined) { | ||
@@ -893,3 +937,3 @@ return !disableServerWebpackPlugin; | ||
...newConfig.module, | ||
rules: [...(_optionalChain([newConfig, 'access', _5 => _5.module, 'optionalAccess', _6 => _6.rules]) || [])], | ||
rules: [...(_optionalChain([newConfig, 'access', _7 => _7.module, 'optionalAccess', _8 => _8.rules]) || [])], | ||
}; | ||
@@ -909,2 +953,3 @@ // Surprising that we have to assert the type here, since we've demonstrably guaranteed the existence of | ||
buildContext, | ||
sentryWebpackPluginOptions, | ||
) { | ||
@@ -915,7 +960,13 @@ const assetPrefix = userNextConfig.assetPrefix || userNextConfig.basePath || ''; | ||
// `rewritesTunnel` set by the user in Next.js config | ||
__sentryRewritesTunnelPath__: userSentryOptions.tunnelRoute, | ||
__sentryRewritesTunnelPath__: | ||
userSentryOptions.tunnelRoute !== undefined && userNextConfig.output !== 'export' | ||
? `${_nullishCoalesce(userNextConfig.basePath, () => ( ''))}${userSentryOptions.tunnelRoute}` | ||
: undefined, | ||
// The webpack plugin's release injection breaks the `app` directory so we inject the release manually here instead. | ||
// Having a release defined in dev-mode spams releases in Sentry so we only set one in non-dev mode | ||
SENTRY_RELEASE: buildContext.dev ? undefined : { id: node.getSentryRelease(buildContext.buildId) }, | ||
SENTRY_RELEASE: buildContext.dev | ||
? undefined | ||
: { id: _nullishCoalesce(sentryWebpackPluginOptions.release, () => ( node.getSentryRelease(buildContext.buildId))) }, | ||
__sentryBasePath: buildContext.dev ? userNextConfig.basePath : undefined, | ||
}; | ||
@@ -927,3 +978,3 @@ | ||
// characters) | ||
__rewriteFramesDistDir__: _optionalChain([userNextConfig, 'access', _7 => _7.distDir, 'optionalAccess', _8 => _8.replace, 'call', _9 => _9(/\\/g, '\\\\')]) || '.next', | ||
__rewriteFramesDistDir__: _optionalChain([userNextConfig, 'access', _9 => _9.distDir, 'optionalAccess', _10 => _10.replace, 'call', _11 => _11(/\\/g, '\\\\')]) || '.next', | ||
}; | ||
@@ -942,3 +993,3 @@ | ||
{ | ||
test: /sentry\.server\.config\.(jsx?|tsx?)/, | ||
test: /sentry\.(server|edge)\.config\.(jsx?|tsx?)/, | ||
use: [ | ||
@@ -967,2 +1018,98 @@ { | ||
function resolveNextPackageDirFromDirectory(basedir) { | ||
try { | ||
return path.dirname(resolve.sync('next/package.json', { basedir })); | ||
} catch (e2) { | ||
// Should not happen in theory | ||
return undefined; | ||
} | ||
} | ||
const POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS = [ | ||
// Original location of RequestAsyncStorage | ||
// https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts | ||
'next/dist/client/components/request-async-storage.js', | ||
// Introduced in Next.js 13.4.20 | ||
// https://github.com/vercel/next.js/blob/e1bc270830f2fc2df3542d4ef4c61b916c802df3/packages/next/src/client/components/request-async-storage.external.ts | ||
'next/dist/client/components/request-async-storage.external.js', | ||
]; | ||
function getRequestAsyncStorageModuleLocation( | ||
webpackContextDir, | ||
webpackResolvableModuleLocations, | ||
) { | ||
if (webpackResolvableModuleLocations === undefined) { | ||
return undefined; | ||
} | ||
const absoluteWebpackResolvableModuleLocations = webpackResolvableModuleLocations.map(loc => | ||
path.resolve(webpackContextDir, loc), | ||
); | ||
for (const webpackResolvableLocation of absoluteWebpackResolvableModuleLocations) { | ||
const nextPackageDir = resolveNextPackageDirFromDirectory(webpackResolvableLocation); | ||
if (nextPackageDir) { | ||
const asyncLocalStorageLocation = POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS.find(loc => | ||
fs.existsSync(path.join(nextPackageDir, '..', loc)), | ||
); | ||
if (asyncLocalStorageLocation) { | ||
return asyncLocalStorageLocation; | ||
} | ||
} | ||
} | ||
return undefined; | ||
} | ||
let downloadingCliAttempted = false; | ||
class SentryCliDownloadPlugin { | ||
apply(compiler) { | ||
compiler.hooks.beforeRun.tapAsync('SentryCliDownloadPlugin', (compiler, callback) => { | ||
const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin'); | ||
if (!SentryWebpackPlugin) { | ||
// Pretty much an invariant. | ||
return callback(); | ||
} | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know it | ||
if (SentryWebpackPlugin.cliBinaryExists()) { | ||
return callback(); | ||
} | ||
if (!downloadingCliAttempted) { | ||
downloadingCliAttempted = true; | ||
// eslint-disable-next-line no-console | ||
console.log( | ||
`\n${chalk.cyan('info')} - ${chalk.bold( | ||
'Sentry binary to upload source maps not found.', | ||
)} Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`, | ||
); | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know it | ||
const cliDownloadPromise = SentryWebpackPlugin.downloadCliBinary({ | ||
log: () => { | ||
// No logs from directly from CLI | ||
}, | ||
}); | ||
cliDownloadPromise.then( | ||
() => { | ||
// eslint-disable-next-line no-console | ||
console.log(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`); | ||
return callback(); | ||
}, | ||
e => { | ||
// eslint-disable-next-line no-console | ||
console.error(`${chalk.red('error')} - Sentry binary download failed:`, e); | ||
return callback(); | ||
}, | ||
); | ||
} else { | ||
return callback(); | ||
} | ||
}); | ||
} | ||
} | ||
exports.constructWebpackConfigFunction = constructWebpackConfigFunction; | ||
@@ -969,0 +1116,0 @@ exports.getUserConfigFile = getUserConfigFile; |
var { | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const utils = require('@sentry/utils'); | ||
const webpack = require('./webpack.js'); | ||
let showedExportModeTunnelWarning = false; | ||
/** | ||
@@ -24,3 +27,3 @@ * Add Sentry options to the config to be exported from the user's `next.config.js` file. | ||
return function ( ...webpackConfigFunctionArgs) { | ||
const userNextConfigObject = exportedUserNextConfig.apply( | ||
const maybeUserNextConfigObject = exportedUserNextConfig.apply( | ||
this, | ||
@@ -30,2 +33,11 @@ webpackConfigFunctionArgs, | ||
if (utils.isThenable(maybeUserNextConfigObject)) { | ||
return maybeUserNextConfigObject.then(function (userNextConfigObject) { | ||
const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; | ||
return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); | ||
}); | ||
} | ||
// Reassign for naming-consistency sake. | ||
const userNextConfigObject = maybeUserNextConfigObject; | ||
const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; | ||
@@ -51,3 +63,13 @@ return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); | ||
if (_optionalChain([userSentryOptions, 'optionalAccess', _ => _.tunnelRoute])) { | ||
setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute); | ||
if (incomingUserNextConfigObject.output === 'export') { | ||
if (!showedExportModeTunnelWarning) { | ||
showedExportModeTunnelWarning = true; | ||
// eslint-disable-next-line no-console | ||
console.warn( | ||
'[@sentry/nextjs] The Sentry Next.js SDK `tunnelRoute` option will not work in combination with Next.js static exports. The `tunnelRoute` option uses serverside features that cannot be accessed in export mode. If you still want to tunnel Sentry events, set up your own tunnel: https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option', | ||
); | ||
} | ||
} else { | ||
setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute); | ||
} | ||
} | ||
@@ -85,3 +107,3 @@ | ||
key: 'o', // short for orgId - we keep it short so matching is harder for ad-blockers | ||
value: '(?<orgid>.*)', | ||
value: '(?<orgid>\\d*)', | ||
}, | ||
@@ -91,6 +113,6 @@ { | ||
key: 'p', // short for projectId - we keep it short so matching is harder for ad-blockers | ||
value: '(?<projectid>.*)', | ||
value: '(?<projectid>\\d*)', | ||
}, | ||
], | ||
destination: 'https://o:orgid.ingest.sentry.io/api/:projectid/envelope/', | ||
destination: 'https://o:orgid.ingest.sentry.io/api/:projectid/envelope/?hsts=0', | ||
}; | ||
@@ -102,3 +124,3 @@ | ||
// @ts-ignore Expected 0 arguments but got 1 - this is from the future-proofing mentioned above, so we don't care about it | ||
// @ts-expect-error Expected 0 arguments but got 1 - this is from the future-proofing mentioned above, so we don't care about it | ||
const originalRewritesResult = await originalRewrites(...args); | ||
@@ -105,0 +127,0 @@ |
@@ -0,124 +1,79 @@ | ||
var { | ||
_optionalChain | ||
} = require('@sentry/utils'); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const core = require('@sentry/core'); | ||
const integrations = require('@sentry/integrations'); | ||
const utils = require('@sentry/utils'); | ||
const getVercelEnv = require('../common/getVercelEnv.js'); | ||
const edgeclient = require('./edgeclient.js'); | ||
const transport = require('./transport.js'); | ||
const flush = require('./utils/flush.js'); | ||
const vercelEdge = require('@sentry/vercel-edge'); | ||
const isBuild = require('../common/utils/isBuild.js'); | ||
const wrapGetStaticPropsWithSentry = require('../common/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('../common/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('../common/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('../common/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('../common/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('../common/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('../common/wrapServerComponentWithSentry.js'); | ||
const wrapRouteHandlerWithSentry = require('../common/wrapRouteHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('../common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapMiddlewareWithSentry = require('../common/wrapMiddlewareWithSentry.js'); | ||
const wrapPageComponentWithSentry = require('../common/wrapPageComponentWithSentry.js'); | ||
const withServerActionInstrumentation = require('../common/withServerActionInstrumentation.js'); | ||
const wrapApiHandlerWithSentry = require('./wrapApiHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('../common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapMiddlewareWithSentry = require('./wrapMiddlewareWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('./wrapServerComponentWithSentry.js'); | ||
const nodeStackParser = utils.createStackParser(utils.nodeStackLineParser()); | ||
const globalWithInjectedValues = utils.GLOBAL_OBJ | ||
const defaultIntegrations = [new core.Integrations.InboundFilters(), new core.Integrations.FunctionToString()]; | ||
; | ||
/** Inits the Sentry NextJS SDK on the Edge Runtime. */ | ||
function init(options = {}) { | ||
if (options.defaultIntegrations === undefined) { | ||
options.defaultIntegrations = defaultIntegrations; | ||
} | ||
core.addTracingExtensions(); | ||
if (options.dsn === undefined && process.env.SENTRY_DSN) { | ||
options.dsn = process.env.SENTRY_DSN; | ||
if (isBuild.isBuild()) { | ||
return; | ||
} | ||
if (options.tracesSampleRate === undefined && process.env.SENTRY_TRACES_SAMPLE_RATE) { | ||
const tracesSampleRate = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE); | ||
if (isFinite(tracesSampleRate)) { | ||
options.tracesSampleRate = tracesSampleRate; | ||
} | ||
} | ||
if (options.release === undefined) { | ||
const detectedRelease = getSentryRelease(); | ||
if (detectedRelease !== undefined) { | ||
options.release = detectedRelease; | ||
} else { | ||
// If release is not provided, then we should disable autoSessionTracking | ||
options.autoSessionTracking = false; | ||
} | ||
} | ||
options.environment = | ||
options.environment || process.env.SENTRY_ENVIRONMENT || getVercelEnv.getVercelEnv(false) || process.env.NODE_ENV; | ||
if (options.autoSessionTracking === undefined && options.dsn !== undefined) { | ||
options.autoSessionTracking = true; | ||
} | ||
if (options.instrumenter === undefined) { | ||
options.instrumenter = 'sentry'; | ||
} | ||
const clientOptions = { | ||
const opts = { | ||
_metadata: {} , | ||
...options, | ||
stackParser: utils.stackParserFromStackParserOptions(options.stackParser || nodeStackParser), | ||
integrations: core.getIntegrationsToSetup(options), | ||
transport: options.transport || transport.makeEdgeTransport, | ||
}; | ||
core.initAndBind(edgeclient.EdgeClient, clientOptions); | ||
opts._metadata.sdk = opts._metadata.sdk || { | ||
name: 'sentry.javascript.nextjs', | ||
packages: [ | ||
{ | ||
name: 'npm:@sentry/nextjs', | ||
version: core.SDK_VERSION, | ||
}, | ||
], | ||
version: core.SDK_VERSION, | ||
}; | ||
// TODO?: Sessiontracking | ||
} | ||
let integrations$1 = opts.integrations || []; | ||
/** | ||
* Returns a release dynamically from environment variables. | ||
*/ | ||
function getSentryRelease(fallback) { | ||
// Always read first as Sentry takes this as precedence | ||
if (process.env.SENTRY_RELEASE) { | ||
return process.env.SENTRY_RELEASE; | ||
} | ||
// This value is injected at build time, based on the output directory specified in the build config. Though a default | ||
// is set there, we set it here as well, just in case something has gone wrong with the injection. | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__; | ||
if (distDirName) { | ||
const distDirAbsPath = distDirName.replace(/(\/|\\)$/, ''); // We strip trailing slashes because "app:///_next" also doesn't have one | ||
// This supports the variable that sentry-webpack-plugin injects | ||
if (utils.GLOBAL_OBJ.SENTRY_RELEASE && utils.GLOBAL_OBJ.SENTRY_RELEASE.id) { | ||
return utils.GLOBAL_OBJ.SENTRY_RELEASE.id; | ||
} | ||
// Normally we would use `path.resolve` to obtain the absolute path we will strip from the stack frame to align with | ||
// the uploaded artifacts, however we don't have access to that API in edge so we need to be a bit more lax. | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(`.*${utils.escapeStringForRegex(distDirAbsPath)}`); | ||
return ( | ||
// GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables | ||
process.env.GITHUB_SHA || | ||
// Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata | ||
process.env.COMMIT_REF || | ||
// Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables | ||
process.env.VERCEL_GIT_COMMIT_SHA || | ||
process.env.VERCEL_GITHUB_COMMIT_SHA || | ||
process.env.VERCEL_GITLAB_COMMIT_SHA || | ||
process.env.VERCEL_BITBUCKET_COMMIT_SHA || | ||
// Zeit (now known as Vercel) | ||
process.env.ZEIT_GITHUB_COMMIT_SHA || | ||
process.env.ZEIT_GITLAB_COMMIT_SHA || | ||
process.env.ZEIT_BITBUCKET_COMMIT_SHA || | ||
fallback | ||
); | ||
} | ||
const defaultRewriteFramesIntegration = new integrations.RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
/** | ||
* Call `close()` on the current client, if there is one. See {@link Client.close}. | ||
* | ||
* @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this | ||
* parameter will cause the client to wait until all events are sent before disabling itself. | ||
* @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it | ||
* doesn't (or if there's no client defined). | ||
*/ | ||
async function close(timeout) { | ||
const client = core.getCurrentHub().getClient(); | ||
if (client) { | ||
return client.close(timeout); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations$1); | ||
} | ||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && utils.logger.warn('Cannot flush events and disable SDK. No client defined.'); | ||
return Promise.resolve(false); | ||
} | ||
/** | ||
* This is the getter for lastEventId. | ||
* | ||
* @returns The last event id of a captured event. | ||
*/ | ||
function lastEventId() { | ||
return core.getCurrentHub().lastEventId(); | ||
opts.integrations = integrations$1; | ||
vercelEdge.init(opts); | ||
} | ||
@@ -133,17 +88,29 @@ | ||
exports.flush = flush.flush; | ||
exports.Span = core.Span; | ||
exports.Transaction = core.Transaction; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.withSentryServerSideGetInitialProps = wrapGetInitialPropsWithSentry.withSentryServerSideGetInitialProps; | ||
exports.wrapGetInitialPropsWithSentry = wrapGetInitialPropsWithSentry.wrapGetInitialPropsWithSentry; | ||
exports.withSentryServerSideAppGetInitialProps = wrapAppGetInitialPropsWithSentry.withSentryServerSideAppGetInitialProps; | ||
exports.wrapAppGetInitialPropsWithSentry = wrapAppGetInitialPropsWithSentry.wrapAppGetInitialPropsWithSentry; | ||
exports.withSentryServerSideDocumentGetInitialProps = wrapDocumentGetInitialPropsWithSentry.withSentryServerSideDocumentGetInitialProps; | ||
exports.wrapDocumentGetInitialPropsWithSentry = wrapDocumentGetInitialPropsWithSentry.wrapDocumentGetInitialPropsWithSentry; | ||
exports.withSentryServerSideErrorGetInitialProps = wrapErrorGetInitialPropsWithSentry.withSentryServerSideErrorGetInitialProps; | ||
exports.wrapErrorGetInitialPropsWithSentry = wrapErrorGetInitialPropsWithSentry.wrapErrorGetInitialPropsWithSentry; | ||
exports.withSentryGetServerSideProps = wrapGetServerSidePropsWithSentry.withSentryGetServerSideProps; | ||
exports.wrapGetServerSidePropsWithSentry = wrapGetServerSidePropsWithSentry.wrapGetServerSidePropsWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.wrapRouteHandlerWithSentry = wrapRouteHandlerWithSentry.wrapRouteHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapPageComponentWithSentry = wrapPageComponentWithSentry.wrapPageComponentWithSentry; | ||
exports.withServerActionInstrumentation = withServerActionInstrumentation.withServerActionInstrumentation; | ||
exports.withSentryAPI = wrapApiHandlerWithSentry.withSentryAPI; | ||
exports.wrapApiHandlerWithSentry = wrapApiHandlerWithSentry.wrapApiHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.close = close; | ||
exports.defaultIntegrations = defaultIntegrations; | ||
exports.getSentryRelease = getSentryRelease; | ||
exports.init = init; | ||
exports.lastEventId = lastEventId; | ||
exports.withSentryConfig = withSentryConfig; | ||
for (const k in core) { | ||
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = core[k]; | ||
for (const k in vercelEdge) { | ||
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = vercelEdge[k]; | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -1,9 +0,5 @@ | ||
var { | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const core = require('@sentry/core'); | ||
const edgeWrapperUtils = require('./utils/edgeWrapperUtils.js'); | ||
const edgeWrapperUtils = require('../common/utils/edgeWrapperUtils.js'); | ||
@@ -18,6 +14,6 @@ /** | ||
return new Proxy(handler, { | ||
apply: async (wrappingTarget, thisArg, args) => { | ||
apply: (wrappingTarget, thisArg, args) => { | ||
const req = args[0]; | ||
const activeSpan = !!_optionalChain([core.getCurrentHub, 'call', _ => _(), 'access', _2 => _2.getScope, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getSpan, 'call', _5 => _5()]); | ||
const activeSpan = core.getCurrentHub().getScope().getSpan(); | ||
@@ -33,3 +29,3 @@ const wrappedHandler = edgeWrapperUtils.withEdgeWrapping(wrappingTarget, { | ||
return await wrappedHandler.apply(thisArg, args); | ||
return wrappedHandler.apply(thisArg, args); | ||
}, | ||
@@ -36,0 +32,0 @@ }); |
Object.defineProperty(exports, '__esModule', { value: true }); | ||
const index = require('./client/index.js'); | ||
const performance = require('./client/performance.js'); | ||
const nextRoutingInstrumentation = require('./client/routing/nextRoutingInstrumentation.js'); | ||
const _error = require('./common/_error.js'); | ||
const wrapGetInitialPropsWithSentry = require('./client/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./client/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./client/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./client/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./client/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapGetStaticPropsWithSentry = require('./client/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetStaticPropsWithSentry = require('./common/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('./common/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./common/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./common/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./common/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./common/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('./common/wrapServerComponentWithSentry.js'); | ||
const wrapRouteHandlerWithSentry = require('./common/wrapRouteHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('./common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapMiddlewareWithSentry = require('./common/wrapMiddlewareWithSentry.js'); | ||
const wrapPageComponentWithSentry = require('./common/wrapPageComponentWithSentry.js'); | ||
const withServerActionInstrumentation = require('./common/withServerActionInstrumentation.js'); | ||
const react = require('@sentry/react'); | ||
@@ -25,4 +31,6 @@ | ||
exports.withSentryConfig = index.withSentryConfig; | ||
exports.nextRouterInstrumentation = performance.nextRouterInstrumentation; | ||
exports.nextRouterInstrumentation = nextRoutingInstrumentation.nextRouterInstrumentation; | ||
exports.captureUnderscoreErrorException = _error.captureUnderscoreErrorException; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.withSentryServerSideGetInitialProps = wrapGetInitialPropsWithSentry.withSentryServerSideGetInitialProps; | ||
@@ -38,4 +46,8 @@ exports.wrapGetInitialPropsWithSentry = wrapGetInitialPropsWithSentry.wrapGetInitialPropsWithSentry; | ||
exports.wrapGetServerSidePropsWithSentry = wrapGetServerSidePropsWithSentry.wrapGetServerSidePropsWithSentry; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.wrapRouteHandlerWithSentry = wrapRouteHandlerWithSentry.wrapRouteHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapPageComponentWithSentry = wrapPageComponentWithSentry.wrapPageComponentWithSentry; | ||
exports.withServerActionInstrumentation = withServerActionInstrumentation.withServerActionInstrumentation; | ||
exports.BrowserTracing = react.BrowserTracing; | ||
@@ -42,0 +54,0 @@ exports.Integrations = react.Integrations; |
@@ -6,11 +6,15 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const _error = require('./common/_error.js'); | ||
const wrapApiHandlerWithSentry = require('./common/wrapApiHandlerWithSentry.js'); | ||
const wrapGetStaticPropsWithSentry = require('./common/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('./common/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./common/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./common/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./common/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./common/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('./common/wrapServerComponentWithSentry.js'); | ||
const wrapRouteHandlerWithSentry = require('./common/wrapRouteHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('./common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapGetStaticPropsWithSentry = require('./server/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('./server/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./server/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./server/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./server/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./server/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapApiHandlerWithSentry = require('./server/wrapApiHandlerWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('./server/wrapServerComponentWithSentry.js'); | ||
const wrapMiddlewareWithSentry = require('./common/wrapMiddlewareWithSentry.js'); | ||
const wrapPageComponentWithSentry = require('./common/wrapPageComponentWithSentry.js'); | ||
const withServerActionInstrumentation = require('./common/withServerActionInstrumentation.js'); | ||
const node = require('@sentry/node'); | ||
@@ -34,3 +38,5 @@ | ||
exports.captureUnderscoreErrorException = _error.captureUnderscoreErrorException; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.withSentry = wrapApiHandlerWithSentry.withSentry; | ||
exports.withSentryAPI = wrapApiHandlerWithSentry.withSentryAPI; | ||
exports.wrapApiHandlerWithSentry = wrapApiHandlerWithSentry.wrapApiHandlerWithSentry; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
@@ -48,6 +54,8 @@ exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.wrapGetServerSidePropsWithSentry = wrapGetServerSidePropsWithSentry.wrapGetServerSidePropsWithSentry; | ||
exports.withSentry = wrapApiHandlerWithSentry.withSentry; | ||
exports.withSentryAPI = wrapApiHandlerWithSentry.withSentryAPI; | ||
exports.wrapApiHandlerWithSentry = wrapApiHandlerWithSentry.wrapApiHandlerWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.wrapRouteHandlerWithSentry = wrapRouteHandlerWithSentry.wrapRouteHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapPageComponentWithSentry = wrapPageComponentWithSentry.wrapPageComponentWithSentry; | ||
exports.withServerActionInstrumentation = withServerActionInstrumentation.withServerActionInstrumentation; | ||
exports._SENTRY_SDK_MULTIPLEXER = _SENTRY_SDK_MULTIPLEXER; | ||
@@ -54,0 +62,0 @@ for (const k in node) { |
var { | ||
_optionalChain | ||
} = require('@sentry/utils/cjs/buildPolyfills'); | ||
} = require('@sentry/utils'); | ||
@@ -15,13 +15,17 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
const metadata = require('../common/metadata.js'); | ||
const isBuild = require('./utils/isBuild.js'); | ||
const isBuild = require('../common/utils/isBuild.js'); | ||
const _error = require('../common/_error.js'); | ||
const wrapGetStaticPropsWithSentry = require('../common/wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('../common/wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('../common/wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('../common/wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('../common/wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('../common/wrapGetServerSidePropsWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('../common/wrapServerComponentWithSentry.js'); | ||
const wrapRouteHandlerWithSentry = require('../common/wrapRouteHandlerWithSentry.js'); | ||
const wrapApiHandlerWithSentryVercelCrons = require('../common/wrapApiHandlerWithSentryVercelCrons.js'); | ||
const wrapGetStaticPropsWithSentry = require('./wrapGetStaticPropsWithSentry.js'); | ||
const wrapGetInitialPropsWithSentry = require('./wrapGetInitialPropsWithSentry.js'); | ||
const wrapAppGetInitialPropsWithSentry = require('./wrapAppGetInitialPropsWithSentry.js'); | ||
const wrapDocumentGetInitialPropsWithSentry = require('./wrapDocumentGetInitialPropsWithSentry.js'); | ||
const wrapErrorGetInitialPropsWithSentry = require('./wrapErrorGetInitialPropsWithSentry.js'); | ||
const wrapGetServerSidePropsWithSentry = require('./wrapGetServerSidePropsWithSentry.js'); | ||
const wrapApiHandlerWithSentry = require('./wrapApiHandlerWithSentry.js'); | ||
const wrapServerComponentWithSentry = require('./wrapServerComponentWithSentry.js'); | ||
const wrapMiddlewareWithSentry = require('../common/wrapMiddlewareWithSentry.js'); | ||
const wrapPageComponentWithSentry = require('../common/wrapPageComponentWithSentry.js'); | ||
const withServerActionInstrumentation = require('../common/withServerActionInstrumentation.js'); | ||
const wrapApiHandlerWithSentry = require('../common/wrapApiHandlerWithSentry.js'); | ||
@@ -49,2 +53,3 @@ /** | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function withErrorBoundary( | ||
@@ -77,3 +82,16 @@ WrappedComponent, | ||
function init(options) { | ||
if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && options.debug) { | ||
core.addTracingExtensions(); | ||
if (isBuild.isBuild()) { | ||
return; | ||
} | ||
const opts = { | ||
environment: process.env.SENTRY_ENVIRONMENT || getVercelEnv.getVercelEnv(false) || process.env.NODE_ENV, | ||
...options, | ||
// Right now we only capture frontend sessions for Next.js | ||
autoSessionTracking: false, | ||
}; | ||
if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && opts.debug) { | ||
utils.logger.enable(); | ||
@@ -89,13 +107,8 @@ } | ||
metadata.buildMetadata(options, ['nextjs', 'node']); | ||
metadata.buildMetadata(opts, ['nextjs', 'node']); | ||
options.environment = | ||
options.environment || process.env.SENTRY_ENVIRONMENT || getVercelEnv.getVercelEnv(false) || process.env.NODE_ENV; | ||
addServerIntegrations(opts); | ||
addServerIntegrations(options); | ||
// Right now we only capture frontend sessions for Next.js | ||
options.autoSessionTracking = false; | ||
node.init(opts); | ||
node.init(options); | ||
const filterTransactions = event => { | ||
@@ -133,15 +146,17 @@ return event.type === 'transaction' && event.transaction === '/404' ? null : event; | ||
// is set there, we set it here as well, just in case something has gone wrong with the injection. | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__ || '.next'; | ||
// nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so | ||
// we can read in the project directory from the currently running process | ||
const distDirAbsPath = path.resolve(process.cwd(), distDirName); | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(utils.escapeStringForRegex(distDirAbsPath)); | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__; | ||
if (distDirName) { | ||
// nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so | ||
// we can read in the project directory from the currently running process | ||
const distDirAbsPath = path.resolve(distDirName).replace(/(\/|\\)$/, ''); // We strip trailing slashes because "app:///_next" also doesn't have one | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(utils.escapeStringForRegex(distDirAbsPath)); | ||
const defaultRewriteFramesIntegration = new integrations.RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations$1); | ||
const defaultRewriteFramesIntegration = new integrations.RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations$1); | ||
} | ||
@@ -156,8 +171,6 @@ const defaultOnUncaughtExceptionIntegration = new node.Integrations.OnUncaughtException({ | ||
if (core.hasTracingEnabled(options)) { | ||
const defaultHttpTracingIntegration = new node.Integrations.Http({ tracing: true }); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultHttpTracingIntegration, integrations$1, { | ||
_tracing: {}, | ||
}); | ||
} | ||
const defaultHttpTracingIntegration = new node.Integrations.Http({ tracing: true }); | ||
integrations$1 = utils.addOrUpdateIntegration(defaultHttpTracingIntegration, integrations$1, { | ||
_tracing: {}, | ||
}); | ||
@@ -174,3 +187,2 @@ options.integrations = integrations$1; | ||
exports.captureUnderscoreErrorException = _error.captureUnderscoreErrorException; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.withSentryGetStaticProps = wrapGetStaticPropsWithSentry.withSentryGetStaticProps; | ||
@@ -188,6 +200,11 @@ exports.wrapGetStaticPropsWithSentry = wrapGetStaticPropsWithSentry.wrapGetStaticPropsWithSentry; | ||
exports.wrapGetServerSidePropsWithSentry = wrapGetServerSidePropsWithSentry.wrapGetServerSidePropsWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.wrapRouteHandlerWithSentry = wrapRouteHandlerWithSentry.wrapRouteHandlerWithSentry; | ||
exports.wrapApiHandlerWithSentryVercelCrons = wrapApiHandlerWithSentryVercelCrons.wrapApiHandlerWithSentryVercelCrons; | ||
exports.wrapMiddlewareWithSentry = wrapMiddlewareWithSentry.wrapMiddlewareWithSentry; | ||
exports.wrapPageComponentWithSentry = wrapPageComponentWithSentry.wrapPageComponentWithSentry; | ||
exports.withServerActionInstrumentation = withServerActionInstrumentation.withServerActionInstrumentation; | ||
exports.withSentry = wrapApiHandlerWithSentry.withSentry; | ||
exports.withSentryAPI = wrapApiHandlerWithSentry.withSentryAPI; | ||
exports.wrapApiHandlerWithSentry = wrapApiHandlerWithSentry.wrapApiHandlerWithSentry; | ||
exports.wrapServerComponentWithSentry = wrapServerComponentWithSentry.wrapServerComponentWithSentry; | ||
exports.ErrorBoundary = ErrorBoundary; | ||
@@ -194,0 +211,0 @@ exports.IS_BUILD = IS_BUILD; |
@@ -1,2 +0,2 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { hasTracingEnabled } from '@sentry/core'; | ||
@@ -11,12 +11,18 @@ import { RewriteFrames } from '@sentry/integrations'; | ||
import { buildMetadata } from '../common/metadata.js'; | ||
import { nextRouterInstrumentation } from './performance.js'; | ||
export { nextRouterInstrumentation } from './performance.js'; | ||
import { nextRouterInstrumentation } from './routing/nextRoutingInstrumentation.js'; | ||
export { nextRouterInstrumentation } from './routing/nextRoutingInstrumentation.js'; | ||
import { applyTunnelRouteOption } from './tunnelRoute.js'; | ||
export { captureUnderscoreErrorException } from '../common/_error.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './wrapGetServerSidePropsWithSentry.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from '../common/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from '../common/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from '../common/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from '../common/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from '../common/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from '../common/wrapGetServerSidePropsWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from '../common/wrapServerComponentWithSentry.js'; | ||
export { wrapRouteHandlerWithSentry } from '../common/wrapRouteHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { wrapMiddlewareWithSentry } from '../common/wrapMiddlewareWithSentry.js'; | ||
export { wrapPageComponentWithSentry } from '../common/wrapPageComponentWithSentry.js'; | ||
export { withServerActionInstrumentation } from '../common/withServerActionInstrumentation.js'; | ||
@@ -31,10 +37,13 @@ // Treeshakable guard to remove all code related to tracing | ||
function init(options) { | ||
applyTunnelRouteOption(options); | ||
buildMetadata(options, ['nextjs', 'react']); | ||
const opts = { | ||
environment: getVercelEnv(true) || process.env.NODE_ENV, | ||
...options, | ||
}; | ||
options.environment = options.environment || getVercelEnv(true) || process.env.NODE_ENV; | ||
applyTunnelRouteOption(opts); | ||
buildMetadata(opts, ['nextjs', 'react']); | ||
addClientIntegrations(options); | ||
addClientIntegrations(opts); | ||
init$1(options); | ||
init$1(opts); | ||
@@ -41,0 +50,0 @@ configureScope(scope => { |
@@ -39,3 +39,3 @@ import { withScope, captureException, getCurrentHub } from '@sentry/core'; | ||
type: 'instrument', | ||
handled: true, | ||
handled: false, | ||
data: { | ||
@@ -42,0 +42,0 @@ function: '_error.getInitialProps', |
@@ -1,4 +0,9 @@ | ||
import { _nullishCoalesce, _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _nullishCoalesce, _optionalChain } from '@sentry/utils'; | ||
import { GLOBAL_OBJ } from '@sentry/utils'; | ||
import * as stackTraceParser from 'stacktrace-parser'; | ||
const globalWithInjectedValues = GLOBAL_OBJ | ||
; | ||
async function resolveStackFrame( | ||
@@ -22,2 +27,9 @@ frame, | ||
let basePath = _nullishCoalesce(globalWithInjectedValues.__sentryBasePath, () => ( '')); | ||
// Prefix the basepath with a slash if it doesn't have one | ||
if (basePath !== '' && !basePath.match(/^\//)) { | ||
basePath = `/${basePath}`; | ||
} | ||
const controller = new AbortController(); | ||
@@ -29,3 +41,3 @@ const timer = setTimeout(() => controller.abort(), 3000); | ||
typeof window === 'undefined' ? 'http://localhost:3000' : '' // TODO: handle the case where users define a different port | ||
}/__nextjs_original-stack-frame?${params.toString()}`, | ||
}${basePath}/__nextjs_original-stack-frame?${params.toString()}`, | ||
{ | ||
@@ -112,3 +124,3 @@ signal: controller.signal, | ||
const resolvedFrames = await Promise.all( | ||
frames.map(async frame => await resolveStackFrame(frame, hint.originalException )), | ||
frames.map(frame => resolveStackFrame(frame, hint.originalException )), | ||
); | ||
@@ -115,0 +127,0 @@ |
@@ -1,3 +0,3 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { runWithAsyncContext, captureCheckIn } from '@sentry/core'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { runWithAsyncContext, addTracingExtensions, captureCheckIn } from '@sentry/core'; | ||
@@ -7,2 +7,3 @@ /** | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function wrapApiHandlerWithSentryVercelCrons( | ||
@@ -13,2 +14,3 @@ handler, | ||
return new Proxy(handler, { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
apply: (originalFunction, thisArg, args) => { | ||
@@ -20,3 +22,4 @@ return runWithAsyncContext(() => { | ||
const [req] = args; | ||
addTracingExtensions(); | ||
const [req] = args ; | ||
@@ -23,0 +26,0 @@ let maybePromiseResult; |
@@ -16,3 +16,4 @@ /** | ||
// Define some global proxy that works on server and on the browser. | ||
let injectedCode = 'var _sentryCollisionFreeGlobalObject = typeof window === "undefined" ? global : window;\n'; | ||
let injectedCode = | ||
'var _sentryCollisionFreeGlobalObject = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : {};\n'; | ||
@@ -19,0 +20,0 @@ Object.entries(values).forEach(([key, value]) => { |
@@ -0,1 +1,2 @@ | ||
import { _optionalChain } from '@sentry/utils'; | ||
import commonjs from '@rollup/plugin-commonjs'; | ||
@@ -14,5 +15,2 @@ import { stringMatchesSomePattern } from '@sentry/utils'; | ||
// Non-public API. Can be found here: https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts | ||
const NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH = 'next/dist/client/components/request-async-storage'; | ||
const apiWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'apiWrapperTemplate.js'); | ||
@@ -27,6 +25,7 @@ const apiWrapperTemplateCode = fs.readFileSync(apiWrapperTemplatePath, { encoding: 'utf8' }); | ||
const requestAsyncStorageShimPath = path.resolve(__dirname, '..', 'templates', 'requestAsyncStorageShim.js'); | ||
const requestAsyncStorageModuleExists = moduleExists(NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH); | ||
let showedMissingAsyncStorageModuleWarning = false; | ||
const sentryInitWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'sentryInitWrapperTemplate.js'); | ||
const sentryInitWrapperTemplateCode = fs.readFileSync(sentryInitWrapperTemplatePath, { encoding: 'utf8' }); | ||
const serverComponentWrapperTemplatePath = path.resolve( | ||
@@ -40,10 +39,4 @@ __dirname, | ||
function moduleExists(id) { | ||
try { | ||
require.resolve(id); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
const routeHandlerWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'routeHandlerWrapperTemplate.js'); | ||
const routeHandlerWrapperTemplateCode = fs.readFileSync(routeHandlerWrapperTemplatePath, { encoding: 'utf8' }); | ||
@@ -59,2 +52,3 @@ /** | ||
userCode, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
userModuleSourceMap, | ||
@@ -71,2 +65,3 @@ ) { | ||
vercelCronsConfig, | ||
nextjsRequestAsyncStorageModulePath, | ||
} = 'getOptions' in this ? this.getOptions() : this.query; | ||
@@ -78,10 +73,30 @@ | ||
if (wrappingTargetKind === 'page' || wrappingTargetKind === 'api-route') { | ||
if (wrappingTargetKind === 'sentry-init') { | ||
templateCode = sentryInitWrapperTemplateCode; | ||
// Absolute paths to the sentry config do not work with Windows: https://github.com/getsentry/sentry-javascript/issues/8133 | ||
// Se we need check whether `this.resourcePath` is absolute because there is no contract by webpack that says it is absolute. | ||
// Examples where `this.resourcePath` could possibly be non-absolute are virtual modules. | ||
if (sentryConfigFilePath && path.isAbsolute(this.resourcePath)) { | ||
const sentryConfigImportPath = path | ||
.relative(path.dirname(this.resourcePath), sentryConfigFilePath) | ||
.replace(/\\/g, '/'); | ||
// path.relative() may return something like `sentry.server.config.js` which is not allowed. Imports from the | ||
// current directory need to start with './'.This is why we prepend the path with './', which should always again | ||
// be a valid relative path. | ||
// https://github.com/getsentry/sentry-javascript/issues/8798 | ||
templateCode = templateCode.replace(/__SENTRY_CONFIG_IMPORT_PATH__/g, `./${sentryConfigImportPath}`); | ||
} else { | ||
// Bail without doing any wrapping | ||
this.callback(null, userCode, userModuleSourceMap); | ||
return; | ||
} | ||
} else if (wrappingTargetKind === 'page' || wrappingTargetKind === 'api-route') { | ||
// Get the parameterized route name from this page's filepath | ||
const parameterizedPagesRoute = path.posix | ||
.normalize( | ||
path | ||
// Get the path of the file insde of the pages directory | ||
.relative(pagesDir, this.resourcePath), | ||
) | ||
const parameterizedPagesRoute = path | ||
// Get the path of the file insde of the pages directory | ||
.relative(pagesDir, this.resourcePath) | ||
// Replace all backslashes with forward slashes (windows) | ||
.replace(/\\/g, '/') | ||
// Add a slash at the beginning | ||
@@ -116,10 +131,13 @@ .replace(/(.*)/, '/$1') | ||
templateCode = templateCode.replace(/__ROUTE__/g, parameterizedPagesRoute.replace(/\\/g, '\\\\')); | ||
} else if (wrappingTargetKind === 'server-component') { | ||
} else if (wrappingTargetKind === 'server-component' || wrappingTargetKind === 'route-handler') { | ||
// Get the parameterized route name from this page's filepath | ||
const parameterizedPagesRoute = path.posix | ||
.normalize(path.relative(appDir, this.resourcePath)) | ||
const parameterizedPagesRoute = path | ||
// Get the path of the file insde of the app directory | ||
.relative(appDir, this.resourcePath) | ||
// Replace all backslashes with forward slashes (windows) | ||
.replace(/\\/g, '/') | ||
// Add a slash at the beginning | ||
.replace(/(.*)/, '/$1') | ||
// Pull off the file name | ||
.replace(/\/[^/]+\.(js|jsx|tsx)$/, '') | ||
.replace(/\/[^/]+\.(js|ts|jsx|tsx)$/, '') | ||
// Remove routing groups: https://beta.nextjs.org/docs/routing/defining-routes#example-creating-multiple-root-layouts | ||
@@ -146,8 +164,12 @@ .replace(/\/(\(.*?\)\/)+/g, '/') | ||
templateCode = serverComponentWrapperTemplateCode; | ||
if (wrappingTargetKind === 'server-component') { | ||
templateCode = serverComponentWrapperTemplateCode; | ||
} else { | ||
templateCode = routeHandlerWrapperTemplateCode; | ||
} | ||
if (requestAsyncStorageModuleExists) { | ||
if (nextjsRequestAsyncStorageModulePath !== undefined) { | ||
templateCode = templateCode.replace( | ||
/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, | ||
NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH, | ||
nextjsRequestAsyncStorageModulePath, | ||
); | ||
@@ -164,3 +186,6 @@ } else { | ||
} | ||
templateCode = templateCode.replace(/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, requestAsyncStorageShimPath); | ||
templateCode = templateCode.replace( | ||
/__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, | ||
'@sentry/nextjs/esm/config/templates/requestAsyncStorageShim.js', | ||
); | ||
} | ||
@@ -172,3 +197,3 @@ | ||
.normalize(path.relative(appDir, this.resourcePath)) | ||
.match(/\/?([^/]+)\.(?:js|jsx|tsx)$/); | ||
.match(/\/?([^/]+)\.(?:js|ts|jsx|tsx)$/); | ||
@@ -201,11 +226,2 @@ if (componentTypeMatch && componentTypeMatch[1]) { | ||
} | ||
// We check whether `this.resourcePath` is absolute because there is no contract by webpack that says it is absolute, | ||
// however we can only create relative paths to the sentry config from absolute paths.Examples where this could possibly be non - absolute are virtual modules. | ||
if (sentryConfigFilePath && path.isAbsolute(this.resourcePath)) { | ||
const sentryConfigImportPath = path | ||
.relative(path.dirname(this.resourcePath), sentryConfigFilePath) // Absolute paths do not work with Windows: https://github.com/getsentry/sentry-javascript/issues/8133 | ||
.replace(/\\/g, '/'); | ||
templateCode = `import "${sentryConfigImportPath}";\n`.concat(templateCode); | ||
} | ||
} else if (wrappingTargetKind === 'middleware') { | ||
@@ -252,83 +268,101 @@ templateCode = middlewareWrapperTemplateCode; | ||
userModuleCode, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
userModuleSourceMap, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
) { | ||
const rollupBuild = await rollup({ | ||
input: SENTRY_WRAPPER_MODULE_NAME, | ||
const wrap = (withDefaultExport) => | ||
rollup({ | ||
input: SENTRY_WRAPPER_MODULE_NAME, | ||
plugins: [ | ||
// We're using a simple custom plugin that virtualizes our wrapper module and the user module, so we don't have to | ||
// mess around with file paths and so that we can pass the original user module source map to rollup so that | ||
// rollup gives us a bundle with correct source mapping to the original file | ||
{ | ||
name: 'virtualize-sentry-wrapper-modules', | ||
resolveId: id => { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME || id === WRAPPING_TARGET_MODULE_NAME) { | ||
return id; | ||
} else { | ||
return null; | ||
} | ||
plugins: [ | ||
// We're using a simple custom plugin that virtualizes our wrapper module and the user module, so we don't have to | ||
// mess around with file paths and so that we can pass the original user module source map to rollup so that | ||
// rollup gives us a bundle with correct source mapping to the original file | ||
{ | ||
name: 'virtualize-sentry-wrapper-modules', | ||
resolveId: id => { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME || id === WRAPPING_TARGET_MODULE_NAME) { | ||
return id; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
load(id) { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME) { | ||
return withDefaultExport ? wrapperCode : wrapperCode.replace('export { default } from', 'export {} from'); | ||
} else if (id === WRAPPING_TARGET_MODULE_NAME) { | ||
return { | ||
code: userModuleCode, | ||
map: userModuleSourceMap, // give rollup acces to original user module source map | ||
}; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
}, | ||
load(id) { | ||
if (id === SENTRY_WRAPPER_MODULE_NAME) { | ||
return wrapperCode; | ||
} else if (id === WRAPPING_TARGET_MODULE_NAME) { | ||
return { | ||
code: userModuleCode, | ||
map: userModuleSourceMap, // give rollup acces to original user module source map | ||
}; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
}, | ||
// People may use `module.exports` in their API routes or page files. Next.js allows that and we also need to | ||
// handle that correctly so we let a plugin to take care of bundling cjs exports for us. | ||
commonjs({ | ||
sourceMap: true, | ||
strictRequires: true, // Don't hoist require statements that users may define | ||
ignoreDynamicRequires: true, // Don't break dynamic requires and things like Webpack's `require.context` | ||
ignore() { | ||
// We want basically only want to use this plugin for handling the case where users export their handlers with module.exports. | ||
// This plugin would also be able to convert any `require` into something esm compatible but webpack does that anyways so we just skip that part of the plugin. | ||
// (Also, modifying require may break user code) | ||
return true; | ||
}, | ||
}), | ||
], | ||
// People may use `module.exports` in their API routes or page files. Next.js allows that and we also need to | ||
// handle that correctly so we let a plugin to take care of bundling cjs exports for us. | ||
commonjs({ | ||
sourceMap: true, | ||
strictRequires: true, // Don't hoist require statements that users may define | ||
ignoreDynamicRequires: true, // Don't break dynamic requires and things like Webpack's `require.context` | ||
ignore() { | ||
// We basically only want to use this plugin for handling the case where users export their handlers with module.exports. | ||
// This plugin would also be able to convert any `require` into something esm compatible but webpack does that anyways so we just skip that part of the plugin. | ||
// (Also, modifying require may break user code) | ||
return true; | ||
}, | ||
}), | ||
], | ||
// We only want to bundle our wrapper module and the wrappee module into one, so we mark everything else as external. | ||
external: sourceId => sourceId !== SENTRY_WRAPPER_MODULE_NAME && sourceId !== WRAPPING_TARGET_MODULE_NAME, | ||
// We only want to bundle our wrapper module and the wrappee module into one, so we mark everything else as external. | ||
external: sourceId => sourceId !== SENTRY_WRAPPER_MODULE_NAME && sourceId !== WRAPPING_TARGET_MODULE_NAME, | ||
// Prevent rollup from stressing out about TS's use of global `this` when polyfilling await. (TS will polyfill if the | ||
// user's tsconfig `target` is set to anything before `es2017`. See https://stackoverflow.com/a/72822340 and | ||
// https://stackoverflow.com/a/60347490.) | ||
context: 'this', | ||
// Prevent rollup from stressing out about TS's use of global `this` when polyfilling await. (TS will polyfill if the | ||
// user's tsconfig `target` is set to anything before `es2017`. See https://stackoverflow.com/a/72822340 and | ||
// https://stackoverflow.com/a/60347490.) | ||
context: 'this', | ||
// Rollup's path-resolution logic when handling re-exports can go wrong when wrapping pages which aren't at the root | ||
// level of the `pages` directory. This may be a bug, as it doesn't match the behavior described in the docs, but what | ||
// seems to happen is this: | ||
// | ||
// - We try to wrap `pages/xyz/userPage.js`, which contains `export { helperFunc } from '../../utils/helper'` | ||
// - Rollup converts '../../utils/helper' into an absolute path | ||
// - We mark the helper module as external | ||
// - Rollup then converts it back to a relative path, but relative to `pages/` rather than `pages/xyz/`. (This is | ||
// the part which doesn't match the docs. They say that Rollup will use the common ancestor of all modules in the | ||
// bundle as the basis for the relative path calculation, but both our temporary file and the page being wrapped | ||
// live in `pages/xyz/`, and they're the only two files in the bundle, so `pages/xyz/`` should be used as the | ||
// root. Unclear why it's not.) | ||
// - As a result of the miscalculation, our proxy module will include `export { helperFunc } from '../utils/helper'` | ||
// rather than the expected `export { helperFunc } from '../../utils/helper'`, thereby causing a build error in | ||
// nextjs.. | ||
// | ||
// Setting `makeAbsoluteExternalsRelative` to `false` prevents all of the above by causing Rollup to ignore imports of | ||
// externals entirely, with the result that their paths remain untouched (which is what we want). | ||
makeAbsoluteExternalsRelative: false, | ||
// Rollup's path-resolution logic when handling re-exports can go wrong when wrapping pages which aren't at the root | ||
// level of the `pages` directory. This may be a bug, as it doesn't match the behavior described in the docs, but what | ||
// seems to happen is this: | ||
// | ||
// - We try to wrap `pages/xyz/userPage.js`, which contains `export { helperFunc } from '../../utils/helper'` | ||
// - Rollup converts '../../utils/helper' into an absolute path | ||
// - We mark the helper module as external | ||
// - Rollup then converts it back to a relative path, but relative to `pages/` rather than `pages/xyz/`. (This is | ||
// the part which doesn't match the docs. They say that Rollup will use the common ancestor of all modules in the | ||
// bundle as the basis for the relative path calculation, but both our temporary file and the page being wrapped | ||
// live in `pages/xyz/`, and they're the only two files in the bundle, so `pages/xyz/`` should be used as the | ||
// root. Unclear why it's not.) | ||
// - As a result of the miscalculation, our proxy module will include `export { helperFunc } from '../utils/helper'` | ||
// rather than the expected `export { helperFunc } from '../../utils/helper'`, thereby causing a build error in | ||
// nextjs.. | ||
// | ||
// Setting `makeAbsoluteExternalsRelative` to `false` prevents all of the above by causing Rollup to ignore imports of | ||
// externals entirely, with the result that their paths remain untouched (which is what we want). | ||
makeAbsoluteExternalsRelative: false, | ||
onwarn: (_warning, _warn) => { | ||
// Suppress all warnings - we don't want to bother people with this output | ||
// Might be stuff like "you have unused imports" | ||
// _warn(_warning); // uncomment to debug | ||
}, | ||
}); | ||
onwarn: (_warning, _warn) => { | ||
// Suppress all warnings - we don't want to bother people with this output | ||
// Might be stuff like "you have unused imports" | ||
// _warn(_warning); // uncomment to debug | ||
}, | ||
}); | ||
// Next.js sometimes complains if you define a default export (e.g. in route handlers in dev mode). | ||
// This is why we want to avoid unnecessarily creating default exports, even if they're just `undefined`. | ||
// For this reason we try to bundle/wrap the user code once including a re-export of `default`. | ||
// If the user code didn't have a default export, rollup will throw. | ||
// We then try bundling/wrapping agian, but without including a re-export of `default`. | ||
let rollupBuild; | ||
try { | ||
rollupBuild = await wrap(true); | ||
} catch (e) { | ||
if (_optionalChain([(e ), 'optionalAccess', _ => _.code]) === 'MISSING_EXPORT') { | ||
rollupBuild = await wrap(false); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -335,0 +369,0 @@ const finalBundle = await rollupBuild.generate({ |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -13,3 +13,3 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userApiModule = origModule ; | ||
const userApiModule = routeModule ; | ||
@@ -16,0 +16,0 @@ // Default to undefined. It's possible for Next.js users to not define any exports/handlers in an API route. If that is |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -12,3 +12,3 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userApiModule = origModule ; | ||
const userApiModule = routeModule ; | ||
@@ -15,0 +15,0 @@ // Default to undefined. It's possible for Next.js users to not define any exports/handlers in an API route. If that is |
@@ -1,2 +0,2 @@ | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
@@ -13,10 +13,11 @@ import * as Sentry from '@sentry/nextjs'; | ||
const userPageModule = origModule ; | ||
const userPageModule = routeModule ; | ||
const pageComponent = userPageModule.default; | ||
const pageComponent = userPageModule ? userPageModule.default : undefined; | ||
const origGetInitialProps = pageComponent.getInitialProps; | ||
const origGetStaticProps = userPageModule.getStaticProps; | ||
const origGetServerSideProps = userPageModule.getServerSideProps; | ||
const origGetInitialProps = pageComponent ? pageComponent.getInitialProps : undefined; | ||
const origGetStaticProps = userPageModule ? userPageModule.getStaticProps : undefined; | ||
const origGetServerSideProps = userPageModule ? userPageModule.getServerSideProps : undefined; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const getInitialPropsWrappers = { | ||
@@ -30,3 +31,3 @@ '/_app': Sentry.wrapAppGetInitialPropsWithSentry, | ||
if (typeof origGetInitialProps === 'function') { | ||
if (pageComponent && typeof origGetInitialProps === 'function') { | ||
pageComponent.getInitialProps = getInitialPropsWrapper(origGetInitialProps) ; | ||
@@ -44,2 +45,4 @@ } | ||
export { pageComponent as default, getServerSideProps, getStaticProps }; | ||
const pageWrapperTemplate = pageComponent ? Sentry.wrapPageComponentWithSentry(pageComponent ) : pageComponent; | ||
export { pageWrapperTemplate as default, getServerSideProps, getStaticProps }; |
@@ -1,7 +0,1 @@ | ||
const requestAsyncStorage = { | ||
getStore: () => { | ||
return undefined; | ||
}, | ||
}; | ||
export { requestAsyncStorage }; |
@@ -1,8 +0,8 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { requestAsyncStorage } from '__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__'; | ||
import * as origModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as routeModule from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
export * from '__SENTRY_WRAPPING_TARGET_FILE__'; | ||
import * as Sentry from '@sentry/nextjs'; | ||
const serverComponent = origModule.default; | ||
const serverComponent = routeModule.default; | ||
@@ -19,3 +19,3 @@ let wrappedServerComponent; | ||
// We try-catch here just in case the API around `requestAsyncStorage` changes unexpectedly since it is not public API | ||
// We try-catch here just in `requestAsyncStorage` is undefined since it may not be defined | ||
try { | ||
@@ -22,0 +22,0 @@ const requestAsyncStore = requestAsyncStorage.getStore(); |
@@ -1,8 +0,8 @@ | ||
import { _nullishCoalesce, _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _nullishCoalesce, _optionalChain } from '@sentry/utils'; | ||
import { getSentryRelease } from '@sentry/node'; | ||
import { escapeStringForRegex, logger, stringMatchesSomePattern, dropUndefinedKeys, arrayify } from '@sentry/utils'; | ||
import SentryWebpackPlugin from '@sentry/webpack-plugin'; | ||
import { escapeStringForRegex, logger, loadModule, arrayify, dropUndefinedKeys } from '@sentry/utils'; | ||
import * as chalk from 'chalk'; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import { sync } from 'resolve'; | ||
@@ -23,2 +23,3 @@ /* eslint-disable complexity */ | ||
let showedHiddenSourceMapsWarningMsg = false; | ||
let showedMissingCliBinaryWarningMsg = false; | ||
@@ -69,3 +70,3 @@ // TODO: merge default SentryWebpackPlugin ignore with their SentryWebpackPlugin ignore or ignoreFile | ||
// Add a loader which will inject code that sets global values | ||
addValueInjectionLoader(newConfig, userNextConfig, userSentryOptions, buildContext); | ||
addValueInjectionLoader(newConfig, userNextConfig, userSentryOptions, buildContext, userSentryWebpackPluginOptions); | ||
@@ -100,3 +101,3 @@ newConfig.module.rules.push({ | ||
const apiRoutesPath = path.join(pagesDirPath, 'api', '/'); | ||
const apiRoutesPath = path.join(pagesDirPath, 'api'); | ||
@@ -117,2 +118,6 @@ const middlewareJsPath = path.join(pagesDirPath, '..', 'middleware.js'); | ||
sentryConfigFilePath: getUserConfigFilePath(projectDir, runtime), | ||
nextjsRequestAsyncStorageModulePath: getRequestAsyncStorageModuleLocation( | ||
projectDir, | ||
_optionalChain([rawNewConfig, 'access', _ => _.resolve, 'optionalAccess', _2 => _2.modules]), | ||
), | ||
}; | ||
@@ -132,2 +137,43 @@ | ||
const isPageResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(pagesDirPath + path.sep) && | ||
!normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}; | ||
const isApiRouteResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(apiRoutesPath + path.sep) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}; | ||
const isMiddlewareResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return normalizedAbsoluteResourcePath === middlewareJsPath || normalizedAbsoluteResourcePath === middlewareTsPath; | ||
}; | ||
const isServerComponentResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
// ".js, .jsx, or .tsx file extensions can be used for Pages" | ||
// https://beta.nextjs.org/docs/routing/pages-and-layouts#pages:~:text=.js%2C%20.jsx%2C%20or%20.tsx%20file%20extensions%20can%20be%20used%20for%20Pages. | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/](page|layout|loading|head|not-found)\.(js|jsx|tsx)$/) | ||
); | ||
}; | ||
const isRouteHandlerResource = (resourcePath) => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath + path.sep) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/]route\.(js|jsx|ts|tsx)$/) | ||
); | ||
}; | ||
if (isServer && userSentryOptions.autoInstrumentServerFunctions !== false) { | ||
@@ -138,10 +184,3 @@ // It is very important that we insert our loaders at the beginning of the array because we expect any sort of transformations/transpilations (e.g. TS -> JS) to already have happened. | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(pagesDirPath) && | ||
!normalizedAbsoluteResourcePath.startsWith(apiRoutesPath) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}, | ||
test: isPageResource, | ||
use: [ | ||
@@ -174,4 +213,3 @@ { | ||
} catch (e) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (e.code === 'ENOENT') ; else { | ||
if ((e ).code === 'ENOENT') ; else { | ||
// log but noop | ||
@@ -184,9 +222,3 @@ logger.error(`${chalk.red('error')} - Sentry failed to read vercel.json`, e); | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(apiRoutesPath) && | ||
dotPrefixedPageExtensions.some(ext => normalizedAbsoluteResourcePath.endsWith(ext)) | ||
); | ||
}, | ||
test: isApiRouteResource, | ||
use: [ | ||
@@ -205,9 +237,22 @@ { | ||
// Wrap middleware | ||
if (_nullishCoalesce(userSentryOptions.autoInstrumentMiddleware, () => ( true))) { | ||
newConfig.module.rules.unshift({ | ||
test: isMiddlewareResource, | ||
use: [ | ||
{ | ||
loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'), | ||
options: { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'middleware', | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
} | ||
if (isServer && userSentryOptions.autoInstrumentAppDirectory !== false) { | ||
// Wrap server components | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
return ( | ||
normalizedAbsoluteResourcePath === middlewareJsPath || normalizedAbsoluteResourcePath === middlewareTsPath | ||
); | ||
}, | ||
test: isServerComponentResource, | ||
use: [ | ||
@@ -218,3 +263,3 @@ { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'middleware', | ||
wrappingTargetKind: 'server-component', | ||
}, | ||
@@ -224,15 +269,28 @@ }, | ||
}); | ||
// Wrap route handlers | ||
newConfig.module.rules.unshift({ | ||
test: isRouteHandlerResource, | ||
use: [ | ||
{ | ||
loader: path.resolve(__dirname, 'loaders', 'wrappingLoader.js'), | ||
options: { | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'route-handler', | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
if (isServer && userSentryOptions.autoInstrumentAppDirectory !== false) { | ||
// Wrap page server components | ||
if (isServer) { | ||
// Import the Sentry config in every user file | ||
newConfig.module.rules.unshift({ | ||
test: resourcePath => { | ||
const normalizedAbsoluteResourcePath = normalizeLoaderResourcePath(resourcePath); | ||
// ".js, .jsx, or .tsx file extensions can be used for Pages" | ||
// https://beta.nextjs.org/docs/routing/pages-and-layouts#pages:~:text=.js%2C%20.jsx%2C%20or%20.tsx%20file%20extensions%20can%20be%20used%20for%20Pages. | ||
return ( | ||
normalizedAbsoluteResourcePath.startsWith(appDirPath) && | ||
!!normalizedAbsoluteResourcePath.match(/[\\/](page|layout|loading|head|not-found)\.(js|jsx|tsx)$/) | ||
isPageResource(resourcePath) || | ||
isApiRouteResource(resourcePath) || | ||
isMiddlewareResource(resourcePath) || | ||
isServerComponentResource(resourcePath) || | ||
isRouteHandlerResource(resourcePath) | ||
); | ||
@@ -245,3 +303,3 @@ }, | ||
...staticWrappingLoaderOptions, | ||
wrappingTargetKind: 'server-component', | ||
wrappingTargetKind: 'sentry-init', | ||
}, | ||
@@ -257,5 +315,5 @@ }, | ||
// fairly massively. | ||
if (!isServer && _optionalChain([userSentryOptions, 'optionalAccess', _ => _.transpileClientSDK])) { | ||
if (!isServer && _optionalChain([userSentryOptions, 'optionalAccess', _3 => _3.transpileClientSDK])) { | ||
// Find all loaders which apply transpilation to user code | ||
const transpilationRules = findTranspilationRules(_optionalChain([newConfig, 'access', _2 => _2.module, 'optionalAccess', _3 => _3.rules]), projectDir); | ||
const transpilationRules = findTranspilationRules(_optionalChain([newConfig, 'access', _4 => _4.module, 'optionalAccess', _5 => _5.rules]), projectDir); | ||
@@ -313,8 +371,13 @@ // For each matching rule, wrap its `exclude` function so that it won't exclude SDK files, even though they're in | ||
newConfig.plugins = newConfig.plugins || []; | ||
newConfig.plugins.push( | ||
new SentryWebpackPlugin( | ||
getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions), | ||
), | ||
); | ||
const SentryWebpackPlugin = loadModule('@sentry/webpack-plugin'); | ||
if (SentryWebpackPlugin) { | ||
newConfig.plugins = newConfig.plugins || []; | ||
newConfig.plugins.push(new SentryCliDownloadPlugin()); | ||
newConfig.plugins.push( | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know about it | ||
new SentryWebpackPlugin( | ||
getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions), | ||
), | ||
); | ||
} | ||
} | ||
@@ -365,3 +428,3 @@ } | ||
// 'next-babel-loader', so we can use the same regex to test for both. | ||
if (!useEntries.some(entry => _optionalChain([entry, 'optionalAccess', _4 => _4.loader]) && new RegExp('next.*(babel|swc).*loader').test(entry.loader))) { | ||
if (!useEntries.some(entry => _optionalChain([entry, 'optionalAccess', _6 => _6.loader]) && new RegExp('next.*(babel|swc).*loader').test(entry.loader))) { | ||
return false; | ||
@@ -423,3 +486,3 @@ } | ||
const { isServer, dir: projectDir, nextRuntime } = buildContext; | ||
const { isServer, dir: projectDir, nextRuntime, dev: isDevMode } = buildContext; | ||
const runtime = isServer ? (buildContext.nextRuntime === 'edge' ? 'edge' : 'node') : 'browser'; | ||
@@ -443,4 +506,4 @@ | ||
for (const entryPointName in newEntryProperty) { | ||
if (shouldAddSentryToEntryPoint(entryPointName, runtime, _nullishCoalesce(userSentryOptions.excludeServerRoutes, () => ( [])))) { | ||
addFilesToExistingEntryPoint(newEntryProperty, entryPointName, filesToInject); | ||
if (shouldAddSentryToEntryPoint(entryPointName, runtime)) { | ||
addFilesToExistingEntryPoint(newEntryProperty, entryPointName, filesToInject, isDevMode); | ||
} else { | ||
@@ -513,3 +576,3 @@ if ( | ||
* @param entryPointName The key where the file should be injected | ||
* @param filepaths An array of paths to the injected files | ||
* @param filesToInsert An array of paths to the injected files | ||
*/ | ||
@@ -519,4 +582,9 @@ function addFilesToExistingEntryPoint( | ||
entryPointName, | ||
filepaths, | ||
filesToInsert, | ||
isDevMode, | ||
) { | ||
// BIG FAT NOTE: Order of insertion seems to matter here. If we insert the new files before the `currentEntrypoint`s, | ||
// the Next.js dev server breaks. Because we generally still want the SDK to be initialized as early as possible we | ||
// still keep it at the start of the entrypoints if we are not in dev mode. | ||
// can be a string, array of strings, or object whose `import` property is one of those two | ||
@@ -526,6 +594,12 @@ const currentEntryPoint = entryProperty[entryPointName]; | ||
if (typeof currentEntryPoint === 'string') { | ||
newEntryPoint = [...filepaths, currentEntryPoint]; | ||
} else if (Array.isArray(currentEntryPoint)) { | ||
newEntryPoint = [...filepaths, ...currentEntryPoint]; | ||
if (typeof currentEntryPoint === 'string' || Array.isArray(currentEntryPoint)) { | ||
newEntryPoint = arrayify(currentEntryPoint); | ||
if (isDevMode) { | ||
// Inserting at beginning breaks dev mode so we insert at the end | ||
newEntryPoint.push(...filesToInsert); | ||
} else { | ||
// In other modes we insert at the beginning so that the SDK initializes as early as possible | ||
newEntryPoint.unshift(...filesToInsert); | ||
} | ||
} | ||
@@ -535,8 +609,10 @@ // descriptor object (webpack 5+) | ||
const currentImportValue = currentEntryPoint.import; | ||
let newImportValue; | ||
const newImportValue = arrayify(currentImportValue); | ||
if (typeof currentImportValue === 'string') { | ||
newImportValue = [...filepaths, currentImportValue]; | ||
if (isDevMode) { | ||
// Inserting at beginning breaks dev mode so we insert at the end | ||
newImportValue.push(...filesToInsert); | ||
} else { | ||
newImportValue = [...filepaths, ...currentImportValue]; | ||
// In other modes we insert at the beginning so that the SDK initializes as early as possible | ||
newImportValue.unshift(...filesToInsert); | ||
} | ||
@@ -596,35 +672,9 @@ | ||
*/ | ||
function shouldAddSentryToEntryPoint( | ||
entryPointName, | ||
runtime, | ||
excludeServerRoutes, | ||
) { | ||
// On the server side, by default we inject the `Sentry.init()` code into every page (with a few exceptions). | ||
if (runtime === 'node') { | ||
// User-specified pages to skip. (Note: For ease of use, `excludeServerRoutes` is specified in terms of routes, | ||
// which don't have the `pages` prefix.) | ||
const entryPointRoute = entryPointName.replace(/^pages/, ''); | ||
if (stringMatchesSomePattern(entryPointRoute, excludeServerRoutes, true)) { | ||
return false; | ||
} | ||
// This expression will implicitly include `pages/_app` which is called for all serverside routes and pages | ||
// regardless whether or not the user has a`_app` file. | ||
return entryPointName.startsWith('pages/'); | ||
} else if (runtime === 'browser') { | ||
return ( | ||
// entrypoint for `/pages` pages - this is included on all clientside pages | ||
// It's important that we inject the SDK into this file and not into 'main' because in 'main' | ||
// some important Next.js code (like the setup code for getCongig()) is located and some users | ||
// may need this code inside their Sentry configs | ||
entryPointName === 'pages/_app' || | ||
function shouldAddSentryToEntryPoint(entryPointName, runtime) { | ||
return ( | ||
runtime === 'browser' && | ||
(entryPointName === 'pages/_app' || | ||
// entrypoint for `/app` pages | ||
entryPointName === 'main-app' | ||
); | ||
} else { | ||
// User-specified pages to skip. (Note: For ease of use, `excludeServerRoutes` is specified in terms of routes, | ||
// which don't have the `pages` prefix.) | ||
const entryPointRoute = entryPointName.replace(/^pages/, ''); | ||
return !stringMatchesSomePattern(entryPointRoute, excludeServerRoutes, true); | ||
} | ||
entryPointName === 'main-app') | ||
); | ||
} | ||
@@ -645,3 +695,3 @@ | ||
) { | ||
const { buildId, isServer, webpack, config, dir: projectDir } = buildContext; | ||
const { buildId, isServer, config, dir: projectDir } = buildContext; | ||
const userNextConfig = config ; | ||
@@ -651,3 +701,2 @@ | ||
const isWebpack5 = webpack.version.startsWith('5'); | ||
const isServerless = userNextConfig.target === 'experimental-serverless-trace'; | ||
@@ -659,9 +708,6 @@ const hasSentryProperties = fs.existsSync(path.resolve(projectDir, 'sentry.properties')); | ||
? [{ paths: [`${distDirAbsPath}/serverless/`], urlPrefix: `${urlPrefix}/serverless` }] | ||
: [ | ||
{ paths: [`${distDirAbsPath}/server/pages/`], urlPrefix: `${urlPrefix}/server/pages` }, | ||
{ paths: [`${distDirAbsPath}/server/app/`], urlPrefix: `${urlPrefix}/server/app` }, | ||
].concat( | ||
isWebpack5 ? [{ paths: [`${distDirAbsPath}/server/chunks/`], urlPrefix: `${urlPrefix}/server/chunks` }] : [], | ||
); | ||
: [{ paths: [`${distDirAbsPath}/server/`], urlPrefix: `${urlPrefix}/server` }]; | ||
const serverIgnore = []; | ||
const clientInclude = userSentryOptions.widenClientFileUpload | ||
@@ -674,11 +720,12 @@ ? [{ paths: [`${distDirAbsPath}/static/chunks`], urlPrefix: `${urlPrefix}/static/chunks` }] | ||
// Widening the upload scope is necessarily going to lead to us uploading files we don't need to (ones which | ||
// don't include any user code). In order to lessen that where we can, exclude the internal nextjs files we know | ||
// will be there. | ||
const clientIgnore = userSentryOptions.widenClientFileUpload | ||
? ['framework-*', 'framework.*', 'main-*', 'polyfills-*', 'webpack-*'] | ||
: []; | ||
const defaultPluginOptions = dropUndefinedKeys({ | ||
include: isServer ? serverInclude : clientInclude, | ||
ignore: | ||
isServer || !userSentryOptions.widenClientFileUpload | ||
? [] | ||
: // Widening the upload scope is necessarily going to lead to us uploading files we don't need to (ones which | ||
// don't include any user code). In order to lessen that where we can, exclude the internal nextjs files we know | ||
// will be there. | ||
['framework-*', 'framework.*', 'main-*', 'polyfills-*', 'webpack-*'], | ||
ignore: isServer ? serverIgnore : clientIgnore, | ||
url: process.env.SENTRY_URL, | ||
@@ -704,2 +751,15 @@ org: process.env.SENTRY_ORG, | ||
if (err.message.includes('ENOENT')) { | ||
if (!showedMissingCliBinaryWarningMsg) { | ||
// eslint-disable-next-line no-console | ||
console.error( | ||
`\n${errorMessagePrefix} ${chalk.bold( | ||
'The Sentry binary to upload sourcemaps could not be found.', | ||
)} Source maps will not be uploaded. Please check that post-install scripts are enabled in your package manager when installing your dependencies and please run your build once without any caching to avoid caching issues of dependencies.\n`, | ||
); | ||
showedMissingCliBinaryWarningMsg = true; | ||
} | ||
return; | ||
} | ||
// Hardcoded way to check for missing auth token until we have a better way of doing this. | ||
@@ -801,18 +861,2 @@ if (err.message.includes('Authentication credentials were not provided.')) { | ||
/** Non-negotiable */ | ||
// This check is necessary because currently, `@sentry/cli` uses a post-install script to download an | ||
// architecture-specific version of the `sentry-cli` binary. If `yarn install`, `npm install`, or `npm ci` are run | ||
// with the `--ignore-scripts` option, this will be blocked and the missing binary will cause an error when users | ||
// try to build their apps. | ||
if (!SentryWebpackPlugin.cliBinaryExists()) { | ||
// eslint-disable-next-line no-console | ||
console.error( | ||
`${chalk.red('error')} - ${chalk.bold('Sentry CLI binary not found.')} Source maps will not be uploaded.\n`, | ||
); | ||
return false; | ||
} | ||
/** User override */ | ||
if (isServer && disableServerWebpackPlugin !== undefined) { | ||
@@ -886,3 +930,3 @@ return !disableServerWebpackPlugin; | ||
...newConfig.module, | ||
rules: [...(_optionalChain([newConfig, 'access', _5 => _5.module, 'optionalAccess', _6 => _6.rules]) || [])], | ||
rules: [...(_optionalChain([newConfig, 'access', _7 => _7.module, 'optionalAccess', _8 => _8.rules]) || [])], | ||
}; | ||
@@ -902,2 +946,3 @@ // Surprising that we have to assert the type here, since we've demonstrably guaranteed the existence of | ||
buildContext, | ||
sentryWebpackPluginOptions, | ||
) { | ||
@@ -908,7 +953,13 @@ const assetPrefix = userNextConfig.assetPrefix || userNextConfig.basePath || ''; | ||
// `rewritesTunnel` set by the user in Next.js config | ||
__sentryRewritesTunnelPath__: userSentryOptions.tunnelRoute, | ||
__sentryRewritesTunnelPath__: | ||
userSentryOptions.tunnelRoute !== undefined && userNextConfig.output !== 'export' | ||
? `${_nullishCoalesce(userNextConfig.basePath, () => ( ''))}${userSentryOptions.tunnelRoute}` | ||
: undefined, | ||
// The webpack plugin's release injection breaks the `app` directory so we inject the release manually here instead. | ||
// Having a release defined in dev-mode spams releases in Sentry so we only set one in non-dev mode | ||
SENTRY_RELEASE: buildContext.dev ? undefined : { id: getSentryRelease(buildContext.buildId) }, | ||
SENTRY_RELEASE: buildContext.dev | ||
? undefined | ||
: { id: _nullishCoalesce(sentryWebpackPluginOptions.release, () => ( getSentryRelease(buildContext.buildId))) }, | ||
__sentryBasePath: buildContext.dev ? userNextConfig.basePath : undefined, | ||
}; | ||
@@ -920,3 +971,3 @@ | ||
// characters) | ||
__rewriteFramesDistDir__: _optionalChain([userNextConfig, 'access', _7 => _7.distDir, 'optionalAccess', _8 => _8.replace, 'call', _9 => _9(/\\/g, '\\\\')]) || '.next', | ||
__rewriteFramesDistDir__: _optionalChain([userNextConfig, 'access', _9 => _9.distDir, 'optionalAccess', _10 => _10.replace, 'call', _11 => _11(/\\/g, '\\\\')]) || '.next', | ||
}; | ||
@@ -935,3 +986,3 @@ | ||
{ | ||
test: /sentry\.server\.config\.(jsx?|tsx?)/, | ||
test: /sentry\.(server|edge)\.config\.(jsx?|tsx?)/, | ||
use: [ | ||
@@ -960,3 +1011,99 @@ { | ||
function resolveNextPackageDirFromDirectory(basedir) { | ||
try { | ||
return path.dirname(sync('next/package.json', { basedir })); | ||
} catch (e2) { | ||
// Should not happen in theory | ||
return undefined; | ||
} | ||
} | ||
const POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS = [ | ||
// Original location of RequestAsyncStorage | ||
// https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts | ||
'next/dist/client/components/request-async-storage.js', | ||
// Introduced in Next.js 13.4.20 | ||
// https://github.com/vercel/next.js/blob/e1bc270830f2fc2df3542d4ef4c61b916c802df3/packages/next/src/client/components/request-async-storage.external.ts | ||
'next/dist/client/components/request-async-storage.external.js', | ||
]; | ||
function getRequestAsyncStorageModuleLocation( | ||
webpackContextDir, | ||
webpackResolvableModuleLocations, | ||
) { | ||
if (webpackResolvableModuleLocations === undefined) { | ||
return undefined; | ||
} | ||
const absoluteWebpackResolvableModuleLocations = webpackResolvableModuleLocations.map(loc => | ||
path.resolve(webpackContextDir, loc), | ||
); | ||
for (const webpackResolvableLocation of absoluteWebpackResolvableModuleLocations) { | ||
const nextPackageDir = resolveNextPackageDirFromDirectory(webpackResolvableLocation); | ||
if (nextPackageDir) { | ||
const asyncLocalStorageLocation = POTENTIAL_REQUEST_ASNYC_STORAGE_LOCATIONS.find(loc => | ||
fs.existsSync(path.join(nextPackageDir, '..', loc)), | ||
); | ||
if (asyncLocalStorageLocation) { | ||
return asyncLocalStorageLocation; | ||
} | ||
} | ||
} | ||
return undefined; | ||
} | ||
let downloadingCliAttempted = false; | ||
class SentryCliDownloadPlugin { | ||
apply(compiler) { | ||
compiler.hooks.beforeRun.tapAsync('SentryCliDownloadPlugin', (compiler, callback) => { | ||
const SentryWebpackPlugin = loadModule('@sentry/webpack-plugin'); | ||
if (!SentryWebpackPlugin) { | ||
// Pretty much an invariant. | ||
return callback(); | ||
} | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know it | ||
if (SentryWebpackPlugin.cliBinaryExists()) { | ||
return callback(); | ||
} | ||
if (!downloadingCliAttempted) { | ||
downloadingCliAttempted = true; | ||
// eslint-disable-next-line no-console | ||
console.log( | ||
`\n${chalk.cyan('info')} - ${chalk.bold( | ||
'Sentry binary to upload source maps not found.', | ||
)} Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`, | ||
); | ||
// @ts-expect-error - this exists, the dynamic import just doesn't know it | ||
const cliDownloadPromise = SentryWebpackPlugin.downloadCliBinary({ | ||
log: () => { | ||
// No logs from directly from CLI | ||
}, | ||
}); | ||
cliDownloadPromise.then( | ||
() => { | ||
// eslint-disable-next-line no-console | ||
console.log(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`); | ||
return callback(); | ||
}, | ||
e => { | ||
// eslint-disable-next-line no-console | ||
console.error(`${chalk.red('error')} - Sentry binary download failed:`, e); | ||
return callback(); | ||
}, | ||
); | ||
} else { | ||
return callback(); | ||
} | ||
}); | ||
} | ||
} | ||
export { constructWebpackConfigFunction, getUserConfigFile, getUserConfigFilePath, getWebpackPluginOptions }; | ||
//# sourceMappingURL=webpack.js.map |
@@ -1,4 +0,7 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { isThenable } from '@sentry/utils'; | ||
import { constructWebpackConfigFunction } from './webpack.js'; | ||
let showedExportModeTunnelWarning = false; | ||
/** | ||
@@ -19,3 +22,3 @@ * Add Sentry options to the config to be exported from the user's `next.config.js` file. | ||
return function ( ...webpackConfigFunctionArgs) { | ||
const userNextConfigObject = exportedUserNextConfig.apply( | ||
const maybeUserNextConfigObject = exportedUserNextConfig.apply( | ||
this, | ||
@@ -25,2 +28,11 @@ webpackConfigFunctionArgs, | ||
if (isThenable(maybeUserNextConfigObject)) { | ||
return maybeUserNextConfigObject.then(function (userNextConfigObject) { | ||
const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; | ||
return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); | ||
}); | ||
} | ||
// Reassign for naming-consistency sake. | ||
const userNextConfigObject = maybeUserNextConfigObject; | ||
const userSentryOptions = { ...userNextConfigObject.sentry, ...sentryOptions }; | ||
@@ -46,3 +58,13 @@ return getFinalConfigObject(userNextConfigObject, userSentryOptions, userSentryWebpackPluginOptions); | ||
if (_optionalChain([userSentryOptions, 'optionalAccess', _ => _.tunnelRoute])) { | ||
setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute); | ||
if (incomingUserNextConfigObject.output === 'export') { | ||
if (!showedExportModeTunnelWarning) { | ||
showedExportModeTunnelWarning = true; | ||
// eslint-disable-next-line no-console | ||
console.warn( | ||
'[@sentry/nextjs] The Sentry Next.js SDK `tunnelRoute` option will not work in combination with Next.js static exports. The `tunnelRoute` option uses serverside features that cannot be accessed in export mode. If you still want to tunnel Sentry events, set up your own tunnel: https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option', | ||
); | ||
} | ||
} else { | ||
setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute); | ||
} | ||
} | ||
@@ -80,3 +102,3 @@ | ||
key: 'o', // short for orgId - we keep it short so matching is harder for ad-blockers | ||
value: '(?<orgid>.*)', | ||
value: '(?<orgid>\\d*)', | ||
}, | ||
@@ -86,6 +108,6 @@ { | ||
key: 'p', // short for projectId - we keep it short so matching is harder for ad-blockers | ||
value: '(?<projectid>.*)', | ||
value: '(?<projectid>\\d*)', | ||
}, | ||
], | ||
destination: 'https://o:orgid.ingest.sentry.io/api/:projectid/envelope/', | ||
destination: 'https://o:orgid.ingest.sentry.io/api/:projectid/envelope/?hsts=0', | ||
}; | ||
@@ -97,3 +119,3 @@ | ||
// @ts-ignore Expected 0 arguments but got 1 - this is from the future-proofing mentioned above, so we don't care about it | ||
// @ts-expect-error Expected 0 arguments but got 1 - this is from the future-proofing mentioned above, so we don't care about it | ||
const originalRewritesResult = await originalRewrites(...args); | ||
@@ -100,0 +122,0 @@ |
@@ -1,123 +0,76 @@ | ||
import { Integrations, getIntegrationsToSetup, initAndBind, getCurrentHub } from '@sentry/core'; | ||
export * from '@sentry/core'; | ||
import { createStackParser, nodeStackLineParser, stackParserFromStackParserOptions, GLOBAL_OBJ, logger } from '@sentry/utils'; | ||
import { getVercelEnv } from '../common/getVercelEnv.js'; | ||
import { EdgeClient } from './edgeclient.js'; | ||
import { makeEdgeTransport } from './transport.js'; | ||
export { flush } from './utils/flush.js'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { addTracingExtensions, SDK_VERSION } from '@sentry/core'; | ||
export { Span, Transaction } from '@sentry/core'; | ||
import { RewriteFrames } from '@sentry/integrations'; | ||
import { escapeStringForRegex, addOrUpdateIntegration, GLOBAL_OBJ } from '@sentry/utils'; | ||
import { init as init$1 } from '@sentry/vercel-edge'; | ||
export * from '@sentry/vercel-edge'; | ||
import { isBuild } from '../common/utils/isBuild.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from '../common/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from '../common/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from '../common/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from '../common/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from '../common/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from '../common/wrapGetServerSidePropsWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from '../common/wrapServerComponentWithSentry.js'; | ||
export { wrapRouteHandlerWithSentry } from '../common/wrapRouteHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { wrapMiddlewareWithSentry } from '../common/wrapMiddlewareWithSentry.js'; | ||
export { wrapPageComponentWithSentry } from '../common/wrapPageComponentWithSentry.js'; | ||
export { withServerActionInstrumentation } from '../common/withServerActionInstrumentation.js'; | ||
export { withSentryAPI, wrapApiHandlerWithSentry } from './wrapApiHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { wrapMiddlewareWithSentry } from './wrapMiddlewareWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from './wrapServerComponentWithSentry.js'; | ||
const nodeStackParser = createStackParser(nodeStackLineParser()); | ||
const globalWithInjectedValues = GLOBAL_OBJ | ||
const defaultIntegrations = [new Integrations.InboundFilters(), new Integrations.FunctionToString()]; | ||
; | ||
/** Inits the Sentry NextJS SDK on the Edge Runtime. */ | ||
function init(options = {}) { | ||
if (options.defaultIntegrations === undefined) { | ||
options.defaultIntegrations = defaultIntegrations; | ||
} | ||
addTracingExtensions(); | ||
if (options.dsn === undefined && process.env.SENTRY_DSN) { | ||
options.dsn = process.env.SENTRY_DSN; | ||
if (isBuild()) { | ||
return; | ||
} | ||
if (options.tracesSampleRate === undefined && process.env.SENTRY_TRACES_SAMPLE_RATE) { | ||
const tracesSampleRate = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE); | ||
if (isFinite(tracesSampleRate)) { | ||
options.tracesSampleRate = tracesSampleRate; | ||
} | ||
} | ||
if (options.release === undefined) { | ||
const detectedRelease = getSentryRelease(); | ||
if (detectedRelease !== undefined) { | ||
options.release = detectedRelease; | ||
} else { | ||
// If release is not provided, then we should disable autoSessionTracking | ||
options.autoSessionTracking = false; | ||
} | ||
} | ||
options.environment = | ||
options.environment || process.env.SENTRY_ENVIRONMENT || getVercelEnv(false) || process.env.NODE_ENV; | ||
if (options.autoSessionTracking === undefined && options.dsn !== undefined) { | ||
options.autoSessionTracking = true; | ||
} | ||
if (options.instrumenter === undefined) { | ||
options.instrumenter = 'sentry'; | ||
} | ||
const clientOptions = { | ||
const opts = { | ||
_metadata: {} , | ||
...options, | ||
stackParser: stackParserFromStackParserOptions(options.stackParser || nodeStackParser), | ||
integrations: getIntegrationsToSetup(options), | ||
transport: options.transport || makeEdgeTransport, | ||
}; | ||
initAndBind(EdgeClient, clientOptions); | ||
opts._metadata.sdk = opts._metadata.sdk || { | ||
name: 'sentry.javascript.nextjs', | ||
packages: [ | ||
{ | ||
name: 'npm:@sentry/nextjs', | ||
version: SDK_VERSION, | ||
}, | ||
], | ||
version: SDK_VERSION, | ||
}; | ||
// TODO?: Sessiontracking | ||
} | ||
let integrations = opts.integrations || []; | ||
/** | ||
* Returns a release dynamically from environment variables. | ||
*/ | ||
function getSentryRelease(fallback) { | ||
// Always read first as Sentry takes this as precedence | ||
if (process.env.SENTRY_RELEASE) { | ||
return process.env.SENTRY_RELEASE; | ||
} | ||
// This value is injected at build time, based on the output directory specified in the build config. Though a default | ||
// is set there, we set it here as well, just in case something has gone wrong with the injection. | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__; | ||
if (distDirName) { | ||
const distDirAbsPath = distDirName.replace(/(\/|\\)$/, ''); // We strip trailing slashes because "app:///_next" also doesn't have one | ||
// This supports the variable that sentry-webpack-plugin injects | ||
if (GLOBAL_OBJ.SENTRY_RELEASE && GLOBAL_OBJ.SENTRY_RELEASE.id) { | ||
return GLOBAL_OBJ.SENTRY_RELEASE.id; | ||
} | ||
// Normally we would use `path.resolve` to obtain the absolute path we will strip from the stack frame to align with | ||
// the uploaded artifacts, however we don't have access to that API in edge so we need to be a bit more lax. | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(`.*${escapeStringForRegex(distDirAbsPath)}`); | ||
return ( | ||
// GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables | ||
process.env.GITHUB_SHA || | ||
// Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata | ||
process.env.COMMIT_REF || | ||
// Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables | ||
process.env.VERCEL_GIT_COMMIT_SHA || | ||
process.env.VERCEL_GITHUB_COMMIT_SHA || | ||
process.env.VERCEL_GITLAB_COMMIT_SHA || | ||
process.env.VERCEL_BITBUCKET_COMMIT_SHA || | ||
// Zeit (now known as Vercel) | ||
process.env.ZEIT_GITHUB_COMMIT_SHA || | ||
process.env.ZEIT_GITLAB_COMMIT_SHA || | ||
process.env.ZEIT_BITBUCKET_COMMIT_SHA || | ||
fallback | ||
); | ||
} | ||
const defaultRewriteFramesIntegration = new RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
/** | ||
* Call `close()` on the current client, if there is one. See {@link Client.close}. | ||
* | ||
* @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this | ||
* parameter will cause the client to wait until all events are sent before disabling itself. | ||
* @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it | ||
* doesn't (or if there's no client defined). | ||
*/ | ||
async function close(timeout) { | ||
const client = getCurrentHub().getClient(); | ||
if (client) { | ||
return client.close(timeout); | ||
integrations = addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations); | ||
} | ||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Cannot flush events and disable SDK. No client defined.'); | ||
return Promise.resolve(false); | ||
} | ||
/** | ||
* This is the getter for lastEventId. | ||
* | ||
* @returns The last event id of a captured event. | ||
*/ | ||
function lastEventId() { | ||
return getCurrentHub().lastEventId(); | ||
opts.integrations = integrations; | ||
init$1(opts); | ||
} | ||
@@ -132,3 +85,3 @@ | ||
export { close, defaultIntegrations, getSentryRelease, init, lastEventId, withSentryConfig }; | ||
export { init, withSentryConfig }; | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,3 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { getCurrentHub } from '@sentry/core'; | ||
import { withEdgeWrapping } from './utils/edgeWrapperUtils.js'; | ||
import { withEdgeWrapping } from '../common/utils/edgeWrapperUtils.js'; | ||
@@ -13,6 +12,6 @@ /** | ||
return new Proxy(handler, { | ||
apply: async (wrappingTarget, thisArg, args) => { | ||
apply: (wrappingTarget, thisArg, args) => { | ||
const req = args[0]; | ||
const activeSpan = !!_optionalChain([getCurrentHub, 'call', _ => _(), 'access', _2 => _2.getScope, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getSpan, 'call', _5 => _5()]); | ||
const activeSpan = getCurrentHub().getScope().getSpan(); | ||
@@ -28,3 +27,3 @@ const wrappedHandler = withEdgeWrapping(wrappingTarget, { | ||
return await wrappedHandler.apply(thisArg, args); | ||
return wrappedHandler.apply(thisArg, args); | ||
}, | ||
@@ -31,0 +30,0 @@ }); |
export { init, withSentryConfig } from './client/index.js'; | ||
export { nextRouterInstrumentation } from './client/performance.js'; | ||
export { nextRouterInstrumentation } from './client/routing/nextRoutingInstrumentation.js'; | ||
export { captureUnderscoreErrorException } from './common/_error.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './client/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './client/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './client/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './client/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './client/wrapGetServerSidePropsWithSentry.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './client/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './common/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './common/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './common/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './common/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './common/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './common/wrapGetServerSidePropsWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from './common/wrapServerComponentWithSentry.js'; | ||
export { wrapRouteHandlerWithSentry } from './common/wrapRouteHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from './common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { wrapMiddlewareWithSentry } from './common/wrapMiddlewareWithSentry.js'; | ||
export { wrapPageComponentWithSentry } from './common/wrapPageComponentWithSentry.js'; | ||
export { withServerActionInstrumentation } from './common/withServerActionInstrumentation.js'; | ||
export * from '@sentry/react'; | ||
@@ -11,0 +17,0 @@ export { BrowserTracing, Integrations } from '@sentry/react'; |
export { ErrorBoundary, IS_BUILD, init, isBuild, showReportDialog, withErrorBoundary } from './server/index.js'; | ||
export { withSentryConfig } from './config/withSentryConfig.js'; | ||
export { captureUnderscoreErrorException } from './common/_error.js'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry } from './common/wrapApiHandlerWithSentry.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './common/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './common/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './common/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './common/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './common/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './common/wrapGetServerSidePropsWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from './common/wrapServerComponentWithSentry.js'; | ||
export { wrapRouteHandlerWithSentry } from './common/wrapRouteHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from './common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './server/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './server/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './server/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './server/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './server/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './server/wrapGetServerSidePropsWithSentry.js'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry } from './server/wrapApiHandlerWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from './server/wrapServerComponentWithSentry.js'; | ||
export { wrapMiddlewareWithSentry } from './common/wrapMiddlewareWithSentry.js'; | ||
export { wrapPageComponentWithSentry } from './common/wrapPageComponentWithSentry.js'; | ||
export { withServerActionInstrumentation } from './common/withServerActionInstrumentation.js'; | ||
export * from '@sentry/node'; | ||
@@ -14,0 +18,0 @@ |
@@ -1,3 +0,3 @@ | ||
import { _optionalChain } from '@sentry/utils/esm/buildPolyfills'; | ||
import { hasTracingEnabled } from '@sentry/core'; | ||
import { _optionalChain } from '@sentry/utils'; | ||
import { addTracingExtensions } from '@sentry/core'; | ||
import { RewriteFrames } from '@sentry/integrations'; | ||
@@ -11,13 +11,17 @@ import { init as init$1, configureScope, getCurrentHub, Integrations } from '@sentry/node'; | ||
import { buildMetadata } from '../common/metadata.js'; | ||
import { isBuild } from './utils/isBuild.js'; | ||
import { isBuild } from '../common/utils/isBuild.js'; | ||
export { captureUnderscoreErrorException } from '../common/_error.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from '../common/wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from '../common/wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from '../common/wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from '../common/wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from '../common/wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from '../common/wrapGetServerSidePropsWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from '../common/wrapServerComponentWithSentry.js'; | ||
export { wrapRouteHandlerWithSentry } from '../common/wrapRouteHandlerWithSentry.js'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons.js'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry } from './wrapGetStaticPropsWithSentry.js'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry } from './wrapGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry } from './wrapAppGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry } from './wrapDocumentGetInitialPropsWithSentry.js'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry } from './wrapErrorGetInitialPropsWithSentry.js'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry } from './wrapGetServerSidePropsWithSentry.js'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry } from './wrapApiHandlerWithSentry.js'; | ||
export { wrapServerComponentWithSentry } from './wrapServerComponentWithSentry.js'; | ||
export { wrapMiddlewareWithSentry } from '../common/wrapMiddlewareWithSentry.js'; | ||
export { wrapPageComponentWithSentry } from '../common/wrapPageComponentWithSentry.js'; | ||
export { withServerActionInstrumentation } from '../common/withServerActionInstrumentation.js'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry } from '../common/wrapApiHandlerWithSentry.js'; | ||
@@ -45,2 +49,3 @@ /** | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function withErrorBoundary( | ||
@@ -73,3 +78,16 @@ WrappedComponent, | ||
function init(options) { | ||
if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && options.debug) { | ||
addTracingExtensions(); | ||
if (isBuild()) { | ||
return; | ||
} | ||
const opts = { | ||
environment: process.env.SENTRY_ENVIRONMENT || getVercelEnv(false) || process.env.NODE_ENV, | ||
...options, | ||
// Right now we only capture frontend sessions for Next.js | ||
autoSessionTracking: false, | ||
}; | ||
if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && opts.debug) { | ||
logger.enable(); | ||
@@ -85,13 +103,8 @@ } | ||
buildMetadata(options, ['nextjs', 'node']); | ||
buildMetadata(opts, ['nextjs', 'node']); | ||
options.environment = | ||
options.environment || process.env.SENTRY_ENVIRONMENT || getVercelEnv(false) || process.env.NODE_ENV; | ||
addServerIntegrations(opts); | ||
addServerIntegrations(options); | ||
// Right now we only capture frontend sessions for Next.js | ||
options.autoSessionTracking = false; | ||
init$1(opts); | ||
init$1(options); | ||
const filterTransactions = event => { | ||
@@ -129,15 +142,17 @@ return event.type === 'transaction' && event.transaction === '/404' ? null : event; | ||
// is set there, we set it here as well, just in case something has gone wrong with the injection. | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__ || '.next'; | ||
// nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so | ||
// we can read in the project directory from the currently running process | ||
const distDirAbsPath = path.resolve(process.cwd(), distDirName); | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(escapeStringForRegex(distDirAbsPath)); | ||
const distDirName = globalWithInjectedValues.__rewriteFramesDistDir__; | ||
if (distDirName) { | ||
// nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so | ||
// we can read in the project directory from the currently running process | ||
const distDirAbsPath = path.resolve(distDirName).replace(/(\/|\\)$/, ''); // We strip trailing slashes because "app:///_next" also doesn't have one | ||
const SOURCEMAP_FILENAME_REGEX = new RegExp(escapeStringForRegex(distDirAbsPath)); | ||
const defaultRewriteFramesIntegration = new RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
integrations = addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations); | ||
const defaultRewriteFramesIntegration = new RewriteFrames({ | ||
iteratee: frame => { | ||
frame.filename = _optionalChain([frame, 'access', _ => _.filename, 'optionalAccess', _2 => _2.replace, 'call', _3 => _3(SOURCEMAP_FILENAME_REGEX, 'app:///_next')]); | ||
return frame; | ||
}, | ||
}); | ||
integrations = addOrUpdateIntegration(defaultRewriteFramesIntegration, integrations); | ||
} | ||
@@ -152,8 +167,6 @@ const defaultOnUncaughtExceptionIntegration = new Integrations.OnUncaughtException({ | ||
if (hasTracingEnabled(options)) { | ||
const defaultHttpTracingIntegration = new Integrations.Http({ tracing: true }); | ||
integrations = addOrUpdateIntegration(defaultHttpTracingIntegration, integrations, { | ||
_tracing: {}, | ||
}); | ||
} | ||
const defaultHttpTracingIntegration = new Integrations.Http({ tracing: true }); | ||
integrations = addOrUpdateIntegration(defaultHttpTracingIntegration, integrations, { | ||
_tracing: {}, | ||
}); | ||
@@ -160,0 +173,0 @@ options.integrations = integrations; |
{ | ||
"name": "@sentry/nextjs", | ||
"version": "7.53.1", | ||
"version": "7.81.1", | ||
"description": "Official Sentry SDK for Next.js", | ||
@@ -16,2 +16,9 @@ "repository": "git://github.com/getsentry/sentry-javascript.git", | ||
"types": "types/index.types.d.ts", | ||
"typesVersions": { | ||
"<4.9": { | ||
"npm/types/index.d.ts": [ | ||
"npm/types-ts3.8/index.d.ts" | ||
] | ||
} | ||
}, | ||
"publishConfig": { | ||
@@ -22,15 +29,17 @@ "access": "public" | ||
"@rollup/plugin-commonjs": "24.0.0", | ||
"@sentry/core": "7.53.1", | ||
"@sentry/integrations": "7.53.1", | ||
"@sentry/node": "7.53.1", | ||
"@sentry/react": "7.53.1", | ||
"@sentry/types": "7.53.1", | ||
"@sentry/utils": "7.53.1", | ||
"@sentry/webpack-plugin": "1.20.0", | ||
"@sentry/core": "7.81.1", | ||
"@sentry/integrations": "7.81.1", | ||
"@sentry/node": "7.81.1", | ||
"@sentry/react": "7.81.1", | ||
"@sentry/types": "7.81.1", | ||
"@sentry/utils": "7.81.1", | ||
"@sentry/vercel-edge": "7.81.1", | ||
"@sentry/webpack-plugin": "1.21.0", | ||
"chalk": "3.0.0", | ||
"resolve": "1.22.8", | ||
"rollup": "2.78.0", | ||
"stacktrace-parser": "^0.1.10", | ||
"tslib": "^1.9.3" | ||
"stacktrace-parser": "^0.1.10" | ||
}, | ||
"devDependencies": { | ||
"@types/resolve": "1.20.3", | ||
"@types/webpack": "^4.41.31", | ||
@@ -41,3 +50,3 @@ "eslint-plugin-react": "^7.31.11", | ||
"peerDependencies": { | ||
"next": "^10.0.8 || ^11.0 || ^12.0 || ^13.0", | ||
"next": "^10.0.8 || ^11.0 || ^12.0 || ^13.0 || ^14.0", | ||
"react": "16.x || 17.x || 18.x", | ||
@@ -44,0 +53,0 @@ "webpack": ">= 4.0.0" |
import type { BrowserOptions } from '@sentry/react'; | ||
import { BrowserTracing, Integrations } from '@sentry/react'; | ||
export * from '@sentry/react'; | ||
export { nextRouterInstrumentation } from './performance'; | ||
export { nextRouterInstrumentation } from './routing/nextRoutingInstrumentation'; | ||
export { captureUnderscoreErrorException } from '../common/_error'; | ||
@@ -14,8 +14,3 @@ export { Integrations }; | ||
export declare function withSentryConfig<T>(exportedUserNextConfig: T): T; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry, } from './wrapGetInitialPropsWithSentry'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry, } from './wrapAppGetInitialPropsWithSentry'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry, } from './wrapDocumentGetInitialPropsWithSentry'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry, } from './wrapErrorGetInitialPropsWithSentry'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry, } from './wrapGetServerSidePropsWithSentry'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry, } from './wrapGetStaticPropsWithSentry'; | ||
export * from '../common'; | ||
//# sourceMappingURL=index.d.ts.map |
import type { NextPageContext } from 'next'; | ||
declare type ContextOrProps = { | ||
type ContextOrProps = { | ||
req?: NextPageContext['req']; | ||
@@ -4,0 +4,0 @@ res?: NextPageContext['res']; |
@@ -1,2 +0,4 @@ | ||
export declare type ServerComponentContext = { | ||
import type { Transaction, WrappedFunction } from '@sentry/types'; | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
export type ServerComponentContext = { | ||
componentRoute: string; | ||
@@ -7,6 +9,33 @@ componentType: string; | ||
}; | ||
export declare type VercelCronsConfig = { | ||
export interface RouteHandlerContext { | ||
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'; | ||
parameterizedRoute: string; | ||
sentryTraceHeader?: string; | ||
baggageHeader?: string; | ||
} | ||
export type VercelCronsConfig = { | ||
path?: string; | ||
schedule?: string; | ||
}[] | undefined; | ||
export type NextApiHandler = { | ||
(req: NextApiRequest, res: NextApiResponse): void | Promise<void> | unknown | Promise<unknown>; | ||
__sentry_route__?: string; | ||
/** | ||
* A property we set in our integration tests to simulate running an API route on platforms that don't support streaming. | ||
*/ | ||
__sentry_test_doesnt_support_streaming__?: true; | ||
}; | ||
export type WrappedNextApiHandler = { | ||
(req: NextApiRequest, res: NextApiResponse): Promise<void> | Promise<unknown>; | ||
__sentry_route__?: string; | ||
__sentry_wrapped__?: boolean; | ||
}; | ||
export type AugmentedNextApiRequest = NextApiRequest & { | ||
__withSentry_applied__?: boolean; | ||
}; | ||
export type AugmentedNextApiResponse = NextApiResponse & { | ||
__sentryTransaction?: Transaction; | ||
}; | ||
export type ResponseEndMethod = AugmentedNextApiResponse['end']; | ||
export type WrappedResponseEndMethod = AugmentedNextApiResponse['end'] & WrappedFunction; | ||
//# sourceMappingURL=types.d.ts.map |
import type { LoaderThis } from './types'; | ||
declare type LoaderOptions = { | ||
type LoaderOptions = { | ||
templatePrefix: string; | ||
@@ -4,0 +4,0 @@ replacements: Array<[string, string]>; |
import type { LoaderThis } from './types'; | ||
declare type LoaderOptions = { | ||
type LoaderOptions = { | ||
importTarget: string; | ||
@@ -4,0 +4,0 @@ }; |
import type webpack from 'webpack'; | ||
export declare type LoaderThis<Options> = { | ||
export type LoaderThis<Options> = { | ||
/** | ||
@@ -10,8 +10,2 @@ * Path to the file being loaded | ||
/** | ||
* Query at the end of resolved file name ("../some-folder/some-module?foobar" -> resourceQuery: "?foobar") | ||
* | ||
* https://webpack.js.org/api/loaders/#thisresourcequery | ||
*/ | ||
resourceQuery: string; | ||
/** | ||
* Function to add outside file used by loader to `watch` process | ||
@@ -18,0 +12,0 @@ * |
import type { LoaderThis } from './types'; | ||
declare type LoaderOptions = { | ||
type LoaderOptions = { | ||
values: Record<string, unknown>; | ||
@@ -4,0 +4,0 @@ }; |
import type { VercelCronsConfig } from '../../common/types'; | ||
import type { LoaderThis } from './types'; | ||
declare type LoaderOptions = { | ||
export type WrappingLoaderOptions = { | ||
pagesDir: string; | ||
@@ -8,5 +8,6 @@ appDir: string; | ||
excludeServerRoutes: Array<RegExp | string>; | ||
wrappingTargetKind: 'page' | 'api-route' | 'middleware' | 'server-component'; | ||
wrappingTargetKind: 'page' | 'api-route' | 'middleware' | 'server-component' | 'sentry-init' | 'route-handler'; | ||
sentryConfigFilePath?: string; | ||
vercelCronsConfig?: VercelCronsConfig; | ||
nextjsRequestAsyncStorageModulePath?: string; | ||
}; | ||
@@ -18,4 +19,3 @@ /** | ||
*/ | ||
export default function wrappingLoader(this: LoaderThis<LoaderOptions>, userCode: string, userModuleSourceMap: any): void; | ||
export {}; | ||
export default function wrappingLoader(this: LoaderThis<WrappingLoaderOptions>, userCode: string, userModuleSourceMap: any): void; | ||
//# sourceMappingURL=wrappingLoader.d.ts.map |
import type { GLOBAL_OBJ } from '@sentry/utils'; | ||
import type { SentryCliPluginOptions } from '@sentry/webpack-plugin'; | ||
import type { DefinePlugin, WebpackPluginInstance } from 'webpack'; | ||
export declare type SentryWebpackPluginOptions = SentryCliPluginOptions; | ||
export declare type SentryWebpackPlugin = WebpackPluginInstance & { | ||
export type SentryWebpackPluginOptions = SentryCliPluginOptions; | ||
export type SentryWebpackPlugin = WebpackPluginInstance & { | ||
options: SentryWebpackPluginOptions; | ||
@@ -12,14 +12,14 @@ }; | ||
*/ | ||
export declare type ExportedNextConfig = NextConfigObjectWithSentry | NextConfigFunctionWithSentry; | ||
export declare type NextConfigObjectWithSentry = NextConfigObject & { | ||
export type ExportedNextConfig = NextConfigObjectWithSentry | NextConfigFunctionWithSentry; | ||
export type NextConfigObjectWithSentry = NextConfigObject & { | ||
sentry?: UserSentryOptions; | ||
}; | ||
export declare type NextConfigFunctionWithSentry = (phase: string, defaults: { | ||
export type NextConfigFunctionWithSentry = (phase: string, defaults: { | ||
defaultConfig: NextConfigObject; | ||
}) => NextConfigObjectWithSentry; | ||
declare type NextRewrite = { | ||
}) => NextConfigObjectWithSentry | PromiseLike<NextConfigObjectWithSentry>; | ||
type NextRewrite = { | ||
source: string; | ||
destination: string; | ||
}; | ||
export declare type NextConfigObject = { | ||
export type NextConfigObject = { | ||
webpack?: WebpackConfigFunction | null; | ||
@@ -34,2 +34,3 @@ target?: 'server' | 'experimental-serverless-trace'; | ||
pageExtensions?: string[]; | ||
output?: string; | ||
rewrites?: () => Promise<NextRewrite[] | { | ||
@@ -41,3 +42,3 @@ beforeFiles?: NextRewrite[]; | ||
}; | ||
export declare type UserSentryOptions = { | ||
export type UserSentryOptions = { | ||
/** | ||
@@ -110,10 +111,10 @@ * Override the SDK's default decision about whether or not to enable to the Sentry webpack plugin for server files. | ||
}; | ||
export declare type NextConfigFunction = (phase: string, defaults: { | ||
export type NextConfigFunction = (phase: string, defaults: { | ||
defaultConfig: NextConfigObject; | ||
}) => NextConfigObject; | ||
}) => NextConfigObject | PromiseLike<NextConfigObject>; | ||
/** | ||
* Webpack config | ||
*/ | ||
export declare type WebpackConfigFunction = (config: WebpackConfigObject, options: BuildContext) => WebpackConfigObject; | ||
export declare type WebpackConfigObject = { | ||
export type WebpackConfigFunction = (config: WebpackConfigObject, options: BuildContext) => WebpackConfigObject; | ||
export type WebpackConfigObject = { | ||
devtool?: string; | ||
@@ -129,2 +130,3 @@ plugins?: Array<WebpackPluginInstance | SentryWebpackPlugin>; | ||
resolve?: { | ||
modules?: string[]; | ||
alias?: { | ||
@@ -140,4 +142,4 @@ [key: string]: string | boolean; | ||
}; | ||
export declare type WebpackConfigObjectWithModuleRules = WebpackConfigObject & Required<Pick<WebpackConfigObject, 'module'>>; | ||
export declare type BuildContext = { | ||
export type WebpackConfigObjectWithModuleRules = WebpackConfigObject & Required<Pick<WebpackConfigObject, 'module'>>; | ||
export type BuildContext = { | ||
dev: boolean; | ||
@@ -159,9 +161,9 @@ isServer: boolean; | ||
*/ | ||
export declare type WebpackEntryProperty = EntryPropertyObject | EntryPropertyFunction; | ||
export declare type EntryPropertyObject = { | ||
export type WebpackEntryProperty = EntryPropertyObject | EntryPropertyFunction; | ||
export type EntryPropertyObject = { | ||
[key: string]: EntryPointValue; | ||
}; | ||
export declare type EntryPropertyFunction = () => Promise<EntryPropertyObject>; | ||
export declare type EntryPointValue = string | Array<string> | EntryPointObject; | ||
export declare type EntryPointObject = { | ||
export type EntryPropertyFunction = () => Promise<EntryPropertyObject>; | ||
export type EntryPointValue = string | Array<string> | EntryPointObject; | ||
export type EntryPointObject = { | ||
import: string | Array<string>; | ||
@@ -172,3 +174,3 @@ }; | ||
*/ | ||
export declare type WebpackModuleRule = { | ||
export type WebpackModuleRule = { | ||
test?: string | RegExp | ((resourcePath: string) => boolean); | ||
@@ -180,3 +182,3 @@ include?: Array<string | RegExp> | RegExp; | ||
}; | ||
export declare type ModuleRuleUseProperty = { | ||
export type ModuleRuleUseProperty = { | ||
loader?: string; | ||
@@ -188,3 +190,3 @@ options?: Record<string, unknown>; | ||
*/ | ||
export declare type EnhancedGlobal = typeof GLOBAL_OBJ & { | ||
export type EnhancedGlobal = typeof GLOBAL_OBJ & { | ||
__rewriteFramesDistDir__?: string; | ||
@@ -191,0 +193,0 @@ SENTRY_RELEASE?: { |
@@ -1,36 +0,13 @@ | ||
import { Integrations as CoreIntegrations } from '@sentry/core'; | ||
import type { Options } from '@sentry/types'; | ||
export declare const defaultIntegrations: (CoreIntegrations.InboundFilters | CoreIntegrations.FunctionToString)[]; | ||
export declare type EdgeOptions = Options; | ||
import type { VercelEdgeOptions } from '@sentry/vercel-edge'; | ||
export type EdgeOptions = VercelEdgeOptions; | ||
/** Inits the Sentry NextJS SDK on the Edge Runtime. */ | ||
export declare function init(options?: EdgeOptions): void; | ||
export declare function init(options?: VercelEdgeOptions): void; | ||
/** | ||
* Returns a release dynamically from environment variables. | ||
*/ | ||
export declare function getSentryRelease(fallback?: string): string | undefined; | ||
/** | ||
* Call `close()` on the current client, if there is one. See {@link Client.close}. | ||
* | ||
* @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this | ||
* parameter will cause the client to wait until all events are sent before disabling itself. | ||
* @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it | ||
* doesn't (or if there's no client defined). | ||
*/ | ||
export declare function close(timeout?: number): Promise<boolean>; | ||
/** | ||
* This is the getter for lastEventId. | ||
* | ||
* @returns The last event id of a captured event. | ||
*/ | ||
export declare function lastEventId(): string | undefined; | ||
/** | ||
* Just a passthrough in case this is imported from the client. | ||
*/ | ||
export declare function withSentryConfig<T>(exportedUserNextConfig: T): T; | ||
export { flush } from './utils/flush'; | ||
export * from '@sentry/core'; | ||
export * from '@sentry/vercel-edge'; | ||
export { Span, Transaction } from '@sentry/core'; | ||
export * from '../common'; | ||
export { withSentryAPI, wrapApiHandlerWithSentry, } from './wrapApiHandlerWithSentry'; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons'; | ||
export { wrapMiddlewareWithSentry } from './wrapMiddlewareWithSentry'; | ||
export { wrapServerComponentWithSentry } from './wrapServerComponentWithSentry'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -15,5 +15,2 @@ export * from './config'; | ||
export declare const defaultStackParser: StackParser; | ||
export declare function close(timeout?: number | undefined): PromiseLike<boolean>; | ||
export declare function flush(timeout?: number | undefined): PromiseLike<boolean>; | ||
export declare function lastEventId(): string | undefined; | ||
export declare function getSentryRelease(fallback?: string): string | undefined; | ||
@@ -114,2 +111,6 @@ export declare const ErrorBoundary: typeof clientSdk.ErrorBoundary; | ||
export declare function wrapApiHandlerWithSentryVercelCrons<F extends (...args: any[]) => any>(WrappingTarget: F, vercelCronsConfig: VercelCronsConfig): F; | ||
/** | ||
* Wraps a page component with Sentry error instrumentation. | ||
*/ | ||
export declare function wrapPageComponentWithSentry<C>(WrappingTarget: C): C; | ||
//# sourceMappingURL=index.types.d.ts.map |
/// <reference types="react" /> | ||
/// <reference types="next" /> | ||
import type { NodeOptions } from '@sentry/node'; | ||
@@ -10,5 +9,3 @@ export * from '@sentry/node'; | ||
*/ | ||
export declare const ErrorBoundary: (props: { | ||
children?: import("react").ReactNode; | ||
}) => import("react").ReactNode; | ||
export declare const ErrorBoundary: (props: React.PropsWithChildren<unknown>) => React.ReactNode; | ||
/** | ||
@@ -34,11 +31,4 @@ * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch | ||
export { deprecatedIsBuild as isBuild }; | ||
export { wrapApiHandlerWithSentryVercelCrons } from '../common/wrapApiHandlerWithSentryVercelCrons'; | ||
export { withSentryGetStaticProps, wrapGetStaticPropsWithSentry, } from './wrapGetStaticPropsWithSentry'; | ||
export { withSentryServerSideGetInitialProps, wrapGetInitialPropsWithSentry, } from './wrapGetInitialPropsWithSentry'; | ||
export { withSentryServerSideAppGetInitialProps, wrapAppGetInitialPropsWithSentry, } from './wrapAppGetInitialPropsWithSentry'; | ||
export { withSentryServerSideDocumentGetInitialProps, wrapDocumentGetInitialPropsWithSentry, } from './wrapDocumentGetInitialPropsWithSentry'; | ||
export { withSentryServerSideErrorGetInitialProps, wrapErrorGetInitialPropsWithSentry, } from './wrapErrorGetInitialPropsWithSentry'; | ||
export { withSentryGetServerSideProps, wrapGetServerSidePropsWithSentry, } from './wrapGetServerSidePropsWithSentry'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry, } from './wrapApiHandlerWithSentry'; | ||
export { wrapServerComponentWithSentry } from './wrapServerComponentWithSentry'; | ||
export * from '../common'; | ||
export { withSentry, withSentryAPI, wrapApiHandlerWithSentry, } from '../common/wrapApiHandlerWithSentry'; | ||
//# sourceMappingURL=index.d.ts.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 13 instances in 1 package
1843687
322
10131
47
2
16
4
+ Added@sentry/vercel-edge@7.81.1
+ Addedresolve@1.22.8
+ Added@next/env@14.2.11(transitive)
+ Added@next/swc-darwin-arm64@14.2.11(transitive)
+ Added@next/swc-darwin-x64@14.2.11(transitive)
+ Added@next/swc-linux-arm64-gnu@14.2.11(transitive)
+ Added@next/swc-linux-arm64-musl@14.2.11(transitive)
+ Added@next/swc-linux-x64-gnu@14.2.11(transitive)
+ Added@next/swc-linux-x64-musl@14.2.11(transitive)
+ Added@next/swc-win32-arm64-msvc@14.2.11(transitive)
+ Added@next/swc-win32-ia32-msvc@14.2.11(transitive)
+ Added@next/swc-win32-x64-msvc@14.2.11(transitive)
+ Added@sentry-internal/tracing@7.81.1(transitive)
+ Added@sentry/browser@7.81.1(transitive)
+ Added@sentry/core@7.81.1(transitive)
+ Added@sentry/integrations@7.81.1(transitive)
+ Added@sentry/node@7.81.1(transitive)
+ Added@sentry/react@7.81.1(transitive)
+ Added@sentry/replay@7.81.1(transitive)
+ Added@sentry/types@7.81.1(transitive)
+ Added@sentry/utils@7.81.1(transitive)
+ Added@sentry/vercel-edge@7.81.1(transitive)
+ Added@sentry/webpack-plugin@1.21.0(transitive)
+ Added@swc/counter@0.1.3(transitive)
+ Added@swc/helpers@0.5.5(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedis-core-module@2.15.1(transitive)
+ Addednext@14.2.11(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedresolve@1.22.8(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedtslib@^1.9.3
- Removed@next/env@13.5.7(transitive)
- Removed@next/swc-darwin-arm64@13.5.7(transitive)
- Removed@next/swc-darwin-x64@13.5.7(transitive)
- Removed@next/swc-linux-arm64-gnu@13.5.7(transitive)
- Removed@next/swc-linux-arm64-musl@13.5.7(transitive)
- Removed@next/swc-linux-x64-gnu@13.5.7(transitive)
- Removed@next/swc-linux-x64-musl@13.5.7(transitive)
- Removed@next/swc-win32-arm64-msvc@13.5.7(transitive)
- Removed@next/swc-win32-ia32-msvc@13.5.7(transitive)
- Removed@next/swc-win32-x64-msvc@13.5.7(transitive)
- Removed@sentry-internal/tracing@7.53.1(transitive)
- Removed@sentry/browser@7.53.1(transitive)
- Removed@sentry/core@7.53.1(transitive)
- Removed@sentry/integrations@7.53.1(transitive)
- Removed@sentry/node@7.53.1(transitive)
- Removed@sentry/react@7.53.1(transitive)
- Removed@sentry/replay@7.53.1(transitive)
- Removed@sentry/types@7.53.1(transitive)
- Removed@sentry/utils@7.53.1(transitive)
- Removed@sentry/webpack-plugin@1.20.0(transitive)
- Removed@swc/helpers@0.5.2(transitive)
- Removedcookie@0.4.2(transitive)
- Removedlru_map@0.3.3(transitive)
- Removednext@13.5.7(transitive)
- Removedtslib@1.14.1(transitive)
- Removedwatchpack@2.4.0(transitive)
Updated@sentry/core@7.81.1
Updated@sentry/integrations@7.81.1
Updated@sentry/node@7.81.1
Updated@sentry/react@7.81.1
Updated@sentry/types@7.81.1
Updated@sentry/utils@7.81.1