@sentry/remix
Version:
Official Sentry SDK for Remix
109 lines (106 loc) • 3.45 kB
JavaScript
import { GLOBAL_OBJ, debug } from '@sentry/core';
import { DEBUG_BUILD } from '../utils/debug-build.js';
const globalWithInjectedManifest = GLOBAL_OBJ;
let cachedManifest = null;
let cachedManifestString = void 0;
const compiledRegexCache = /* @__PURE__ */ new Map();
const routeResultCache = /* @__PURE__ */ new Map();
const SEGMENT_STATIC = 0;
const SEGMENT_DYNAMIC = 1;
const SEGMENT_END = 2;
const SEGMENT_SPLAT = 3;
function getSegmentSpecificity(segment) {
if (segment === void 0) {
return SEGMENT_END;
}
if (!segment.startsWith(":")) {
return SEGMENT_STATIC;
}
return segment.substring(1).endsWith("*") ? SEGMENT_SPLAT : 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) {
DEBUG_BUILD && debug.warn("Could not compile regex", { regexString, error });
return null;
}
}
function getManifest() {
if (!globalWithInjectedManifest?._sentryRemixRouteManifest || typeof globalWithInjectedManifest._sentryRemixRouteManifest !== "string") {
return null;
}
const currentManifestString = globalWithInjectedManifest._sentryRemixRouteManifest;
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 {
DEBUG_BUILD && 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);
}
}
}
return matches;
}
function hasManifest() {
return getManifest() !== null;
}
const maybeParameterizeRemixRoute = (route) => {
const manifest = getManifest();
if (!manifest) {
return void 0;
}
if (routeResultCache.has(route)) {
return routeResultCache.get(route);
}
const { staticRoutes, dynamicRoutes } = manifest;
const matches = findMatchingRoutes(route, staticRoutes, dynamicRoutes);
const result = matches.sort(compareRouteSpecificity)[0];
routeResultCache.set(route, result);
return result;
};
export { hasManifest, maybeParameterizeRemixRoute };
//# sourceMappingURL=remixRouteParameterization.js.map