Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
123 lines
4.6 KiB
Plaintext
123 lines
4.6 KiB
Plaintext
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
|
const core = require('@sentry/core');
|
|
|
|
/**
|
|
* Generates a random tunnel route path that's less likely to be blocked by ad-blockers
|
|
*/
|
|
function generateRandomTunnelRoute() {
|
|
// Generate a random 8-character alphanumeric string
|
|
const randomString = core._INTERNAL_safeMathRandom().toString(36).substring(2, 10);
|
|
return `/${randomString}`;
|
|
}
|
|
|
|
/**
|
|
* Resolves the tunnel route based on the user's configuration and the environment.
|
|
* @param tunnelRoute - The user-provided tunnel route option
|
|
*/
|
|
function resolveTunnelRoute(tunnelRoute) {
|
|
if (process.env.__SENTRY_TUNNEL_ROUTE__) {
|
|
// Reuse cached value from previous build (server/client)
|
|
return process.env.__SENTRY_TUNNEL_ROUTE__;
|
|
}
|
|
|
|
const resolvedTunnelRoute = typeof tunnelRoute === 'string' ? tunnelRoute : generateRandomTunnelRoute();
|
|
|
|
// Cache for subsequent builds (only during build time)
|
|
// Turbopack runs the config twice, so we need a shared context to avoid generating a new tunnel route for each build.
|
|
// env works well here
|
|
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
|
|
if (resolvedTunnelRoute) {
|
|
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;
|
|
}
|
|
|
|
return resolvedTunnelRoute;
|
|
}
|
|
|
|
/**
|
|
* Injects rewrite rules into the Next.js config provided by the user to tunnel
|
|
* requests from the `tunnelPath` to Sentry.
|
|
*
|
|
* See https://nextjs.org/docs/api-reference/next.config.js/rewrites.
|
|
*/
|
|
function setUpTunnelRewriteRules(userNextConfig, tunnelPath) {
|
|
const originalRewrites = userNextConfig.rewrites;
|
|
// Allow overriding the tunnel destination for E2E tests via environment variable
|
|
const destinationOverride = process.env._SENTRY_TUNNEL_DESTINATION_OVERRIDE;
|
|
|
|
// Make sure destinations are statically defined at build time
|
|
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';
|
|
|
|
// This function doesn't take any arguments at the time of writing but we future-proof
|
|
// here in case Next.js ever decides to pass some
|
|
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,
|
|
};
|
|
|
|
// Order of these is important, they get applied first to last.
|
|
const newRewrites = [tunnelRouteRewriteWithRegion, tunnelRouteRewrite];
|
|
|
|
if (typeof originalRewrites !== 'function') {
|
|
return newRewrites;
|
|
}
|
|
|
|
// @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);
|
|
|
|
if (Array.isArray(originalRewritesResult)) {
|
|
return [...newRewrites, ...originalRewritesResult];
|
|
} else {
|
|
return {
|
|
...originalRewritesResult,
|
|
beforeFiles: [...newRewrites, ...(originalRewritesResult.beforeFiles || [])],
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
exports.resolveTunnelRoute = resolveTunnelRoute;
|
|
exports.setUpTunnelRewriteRules = setUpTunnelRewriteRules;
|
|
//# sourceMappingURL=tunnel.js.map
|