@sentry/nextjs
Version:
Official Sentry SDK for Next.js
135 lines (131 loc) • 5.42 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const fs = require('fs');
const path = require('path');
const tunnelPathnameMatch = require('../../common/utils/tunnelPathnameMatch.js');
const util = require('../util.js');
function generateRandomTunnelRoute() {
const randomString = core._INTERNAL_safeMathRandom().toString(36).substring(2, 10);
return `/${randomString}`;
}
function resolveTunnelRoute(tunnelRoute) {
if (process.env.__SENTRY_TUNNEL_ROUTE__) {
return process.env.__SENTRY_TUNNEL_ROUTE__;
}
const resolvedTunnelRoute = typeof tunnelRoute === "string" ? tunnelRoute : generateRandomTunnelRoute();
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;
}
return resolvedTunnelRoute;
}
function setUpTunnelRewriteRules(userNextConfig, tunnelPath) {
const originalRewrites = userNextConfig.rewrites;
const destinationOverride = process.env._SENTRY_TUNNEL_DESTINATION_OVERRIDE;
const destination = destinationOverride || "https://o:orgid.ingest.sentry.io/api/:projectid/envelope/?hsts=0";
const destinationWithRegion = destinationOverride || "https://o:orgid.ingest.:region.sentry.io/api/:projectid/envelope/?hsts=0";
userNextConfig.rewrites = async (...args) => {
const tunnelRouteRewrite = {
// Matched rewrite routes will look like the following: `[tunnelPath]?o=[orgid]&p=[projectid]`
// Nextjs will automatically convert `source` into a regex for us
source: `${tunnelPath}(/?)`,
has: [
{
type: "query",
key: "o",
// short for orgId - we keep it short so matching is harder for ad-blockers
value: "(?<orgid>\\d*)"
},
{
type: "query",
key: "p",
// short for projectId - we keep it short so matching is harder for ad-blockers
value: "(?<projectid>\\d*)"
}
],
destination
};
const tunnelRouteRewriteWithRegion = {
// Matched rewrite routes will look like the following: `[tunnelPath]?o=[orgid]&p=[projectid]?r=[region]`
// Nextjs will automatically convert `source` into a regex for us
source: `${tunnelPath}(/?)`,
has: [
{
type: "query",
key: "o",
// short for orgId - we keep it short so matching is harder for ad-blockers
value: "(?<orgid>\\d*)"
},
{
type: "query",
key: "p",
// short for projectId - we keep it short so matching is harder for ad-blockers
value: "(?<projectid>\\d*)"
},
{
type: "query",
key: "r",
// short for region - we keep it short so matching is harder for ad-blockers
value: "(?<region>[a-z]{2})"
}
],
destination: destinationWithRegion
};
const newRewrites = [tunnelRouteRewriteWithRegion, tunnelRouteRewrite];
if (typeof originalRewrites !== "function") {
return newRewrites;
}
const originalRewritesResult = await originalRewrites(...args);
if (Array.isArray(originalRewritesResult)) {
return [...newRewrites, ...originalRewritesResult];
} else {
return {
...originalRewritesResult,
beforeFiles: [...newRewrites, ...originalRewritesResult.beforeFiles || []]
};
}
};
}
function setUpTunnelHandlerRewrite(userNextConfig, tunnelPath) {
const originalRewrites = userNextConfig.rewrites;
const handlerRewrite = { source: tunnelPath, destination: tunnelPathnameMatch.TUNNEL_ROUTE_HANDLER_PATH };
userNextConfig.rewrites = async () => {
const originalRewritesResult = typeof originalRewrites === "function" ? await originalRewrites() : [];
if (Array.isArray(originalRewritesResult)) {
return { beforeFiles: [handlerRewrite], afterFiles: originalRewritesResult };
}
return {
...originalRewritesResult,
beforeFiles: [handlerRewrite, ...originalRewritesResult.beforeFiles || []]
};
};
}
function findTunnelRouteHandlerFile(pageExtensions = util.DEFAULT_PAGE_EXTENSIONS, projectDir = process.cwd()) {
const appDir = ["app", "src/app"].find((dir) => getStats(path.join(projectDir, dir))?.isDirectory());
if (!appDir) {
return void 0;
}
return pageExtensions.map((extension) => `${appDir}${tunnelPathnameMatch.TUNNEL_ROUTE_HANDLER_PATH}/route.${extension}`).find((file) => getStats(path.join(projectDir, file))?.isFile());
}
function getStats(filePath) {
try {
return fs.statSync(filePath);
} catch {
return void 0;
}
}
function getTunnelRouteInjectedValues(userNextConfig, userSentryOptions, projectDir = process.cwd()) {
const tunnelRoute = userSentryOptions?.tunnelRoute;
if (typeof tunnelRoute !== "string" || !tunnelRoute || userNextConfig.output === "export") {
return {};
}
return {
_sentryRewritesTunnelPath: `${userNextConfig.basePath ?? ""}${tunnelRoute}`,
_sentryTunnelRouteMode: findTunnelRouteHandlerFile(userNextConfig.pageExtensions, projectDir) ? "handler" : "rewrite"
};
}
exports.findTunnelRouteHandlerFile = findTunnelRouteHandlerFile;
exports.getTunnelRouteInjectedValues = getTunnelRouteInjectedValues;
exports.resolveTunnelRoute = resolveTunnelRoute;
exports.setUpTunnelHandlerRewrite = setUpTunnelHandlerRewrite;
exports.setUpTunnelRewriteRules = setUpTunnelRewriteRules;
//# sourceMappingURL=tunnel.js.map