@sentry/nextjs
Version:
Official Sentry SDK for Next.js
142 lines (138 loc) • 4.88 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const debugBuild = require('../../common/debug-build.js');
const globalWithInjectedManifest = core.GLOBAL_OBJ;
let cachedManifest = null;
let cachedManifestString = void 0;
const compiledRegexCache = /* @__PURE__ */ new Map();
const routeResultCache = /* @__PURE__ */ new Map();
const globalWithInjectedBasePath = core.GLOBAL_OBJ;
function stripTrailingSlash(pathname) {
return pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
}
function stripBasePath(pathname) {
const basePath = process.env._sentryBasePath ?? globalWithInjectedBasePath._sentryBasePath;
return basePath && (pathname === basePath || pathname.startsWith(`${basePath}/`)) ? pathname.slice(basePath.length) || "/" : pathname;
}
const SEGMENT_STATIC = 0;
const SEGMENT_DYNAMIC = 1;
const SEGMENT_END = 2;
const SEGMENT_CATCH_ALL = 3;
const SEGMENT_OPTIONAL_CATCH_ALL = 4;
function getSegmentSpecificity(segment) {
if (segment === void 0) {
return SEGMENT_END;
}
if (!segment.startsWith(":")) {
return SEGMENT_STATIC;
}
const paramName = segment.substring(1);
if (paramName.endsWith("*?")) {
return SEGMENT_OPTIONAL_CATCH_ALL;
}
if (paramName.endsWith("*")) {
return SEGMENT_CATCH_ALL;
}
return SEGMENT_DYNAMIC;
}
function compareRouteSpecificity(routePathA, routePathB) {
const segmentsA = routePathA.split("/").filter(Boolean);
const segmentsB = routePathB.split("/").filter(Boolean);
const comparedSegmentCount = Math.min(segmentsA.length, segmentsB.length) + 1;
for (let i = 0; i < comparedSegmentCount; i++) {
const difference = getSegmentSpecificity(segmentsA[i]) - getSegmentSpecificity(segmentsB[i]);
if (difference !== 0) {
return difference;
}
}
return 0;
}
function getCompiledRegex(regexString) {
if (compiledRegexCache.has(regexString)) {
return compiledRegexCache.get(regexString) ?? null;
}
try {
const regex = new RegExp(regexString);
compiledRegexCache.set(regexString, regex);
return regex;
} catch (error) {
debugBuild.DEBUG_BUILD && core.debug.warn("Could not compile regex", { regexString, error });
return null;
}
}
function getManifest() {
if (!globalWithInjectedManifest?._sentryRouteManifest || typeof globalWithInjectedManifest._sentryRouteManifest !== "string") {
return null;
}
const currentManifestString = globalWithInjectedManifest._sentryRouteManifest;
if (cachedManifest && cachedManifestString === currentManifestString) {
return cachedManifest;
}
compiledRegexCache.clear();
routeResultCache.clear();
let manifest = {
staticRoutes: [],
dynamicRoutes: []
};
try {
manifest = JSON.parse(currentManifestString);
if (!Array.isArray(manifest.staticRoutes) || !Array.isArray(manifest.dynamicRoutes)) {
return null;
}
cachedManifest = manifest;
cachedManifestString = currentManifestString;
return manifest;
} catch {
debugBuild.DEBUG_BUILD && core.debug.warn("Could not extract route manifest");
return null;
}
}
function findMatchingRoutes(route, staticRoutes, dynamicRoutes) {
const matches = [];
if (staticRoutes.some((r) => r.path === route)) {
return [route];
}
for (const dynamicRoute of dynamicRoutes) {
if (dynamicRoute.regex) {
const regex = getCompiledRegex(dynamicRoute.regex);
if (regex?.test(route)) {
matches.push(dynamicRoute.path);
}
}
}
if (!route.startsWith("/:")) {
for (const dynamicRoute of dynamicRoutes) {
if (dynamicRoute.hasOptionalPrefix && dynamicRoute.regex) {
const routeWithPrefix = route === "/" ? "/SENTRY_OPTIONAL_PREFIX" : `/SENTRY_OPTIONAL_PREFIX${route}`;
const regex = getCompiledRegex(dynamicRoute.regex);
if (regex?.test(routeWithPrefix)) {
matches.push(dynamicRoute.path);
}
}
}
}
return matches;
}
const maybeParameterizeRoute = (route) => {
const manifest = getManifest();
if (!manifest) {
return void 0;
}
const normalizedRoute = route.length > 1 && route.endsWith("/") ? route.slice(0, -1) : route;
if (routeResultCache.has(normalizedRoute)) {
return routeResultCache.get(normalizedRoute);
}
const { staticRoutes, dynamicRoutes } = manifest;
if (!Array.isArray(staticRoutes) || !Array.isArray(dynamicRoutes)) {
return void 0;
}
const matches = findMatchingRoutes(normalizedRoute, staticRoutes, dynamicRoutes);
const result = matches.sort(compareRouteSpecificity)[0];
routeResultCache.set(normalizedRoute, result);
return result;
};
exports.getManifest = getManifest;
exports.maybeParameterizeRoute = maybeParameterizeRoute;
exports.stripBasePath = stripBasePath;
exports.stripTrailingSlash = stripTrailingSlash;
//# sourceMappingURL=parameterization.js.map