@sentry/remix
Version:
Official Sentry SDK for Remix
151 lines (147 loc) • 4.78 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const fs = require('fs');
const path = require('path');
let manifestCache = null;
let lastAppDirPath = null;
function isRouteFile(filename) {
return filename.endsWith(".tsx") || filename.endsWith(".ts") || filename.endsWith(".jsx") || filename.endsWith(".js");
}
function convertRemixRouteToPath(filename) {
const basename = filename.replace(/\.(tsx?|jsx?)$/, "");
if (basename === "_index") {
return { path: "/", isDynamic: false };
}
const normalizedBasename = basename.replace(/[/\\]/g, ".");
const segments = normalizedBasename.split(".");
const pathSegments = [];
let isDynamic = false;
let isIndexRoute = false;
for (let i = 0; i < segments.length; i++) {
const segment = segments[i];
if (!segment) {
continue;
}
if (segment.startsWith("_") && segment !== "_index") {
continue;
}
if (segment === "_index" && i === segments.length - 1) {
isIndexRoute = true;
continue;
}
const pathSegment = segment.endsWith("_") ? segment.slice(0, -1) : segment;
if (pathSegment === "$") {
pathSegments.push(":*");
isDynamic = true;
continue;
}
if (pathSegment.startsWith("$")) {
const paramName = pathSegment.substring(1);
pathSegments.push(`:${paramName}`);
isDynamic = true;
} else {
pathSegments.push(pathSegment);
}
}
if (pathSegments.length === 0 && !isIndexRoute) {
return null;
}
const path2 = pathSegments.length > 0 ? `/${pathSegments.join("/")}` : "/";
return { path: path2, isDynamic };
}
function buildRegexForDynamicRoute(routePath) {
const segments = routePath.split("/").filter(Boolean);
const regexSegments = [];
const paramNames = [];
for (const segment of segments) {
if (segment.startsWith(":")) {
const paramName = segment.substring(1);
if (paramName.endsWith("*")) {
const cleanParamName = paramName.slice(0, -1);
paramNames.push(cleanParamName);
regexSegments.push("(.+)");
} else {
paramNames.push(paramName);
regexSegments.push("([^/]+)");
}
} else {
regexSegments.push(segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
}
}
const pattern = `^/${regexSegments.join("/")}$`;
return { regex: pattern, paramNames };
}
function scanRoutesDirectory(routesDir, prefix = "") {
const dynamicRoutes = [];
const staticRoutes = [];
try {
if (!fs.existsSync(routesDir)) {
return { dynamicRoutes, staticRoutes };
}
const entries = fs.readdirSync(routesDir);
for (const entry of entries) {
const fullPath = path.join(routesDir, entry);
const stat = fs.lstatSync(fullPath);
if (stat.isDirectory()) {
const nestedPrefix = prefix ? `${prefix}/${entry}` : entry;
const nested = scanRoutesDirectory(fullPath, nestedPrefix);
dynamicRoutes.push(...nested.dynamicRoutes);
staticRoutes.push(...nested.staticRoutes);
} else if (stat.isFile() && isRouteFile(entry)) {
const routeName = prefix ? `${prefix}/${entry}` : entry;
const result = convertRemixRouteToPath(routeName);
if (result === null) {
continue;
}
const { path: routePath, isDynamic } = result;
if (isDynamic) {
const { regex, paramNames } = buildRegexForDynamicRoute(routePath);
dynamicRoutes.push({
path: routePath,
regex,
paramNames
});
} else {
staticRoutes.push({
path: routePath
});
}
}
}
} catch (error) {
console.warn("Error building Remix route manifest:", error);
}
return { dynamicRoutes, staticRoutes };
}
function createRemixRouteManifest(options) {
const rootDir = options?.rootDir || process.cwd();
let appDirPath;
if (options?.appDirPath) {
appDirPath = options.appDirPath;
} else {
const maybeAppDirPath = path.join(rootDir, "app");
if (fs.existsSync(maybeAppDirPath) && fs.lstatSync(maybeAppDirPath).isDirectory()) {
appDirPath = maybeAppDirPath;
}
}
if (!appDirPath) {
return {
dynamicRoutes: [],
staticRoutes: []
};
}
if (manifestCache && lastAppDirPath === appDirPath) {
return manifestCache;
}
const routesDir = path.join(appDirPath, "routes");
const { dynamicRoutes, staticRoutes } = scanRoutesDirectory(routesDir);
const manifest = {
dynamicRoutes,
staticRoutes
};
manifestCache = manifest;
lastAppDirPath = appDirPath;
return manifest;
}
exports.convertRemixRouteToPath = convertRemixRouteToPath;
exports.createRemixRouteManifest = createRemixRouteManifest;
//# sourceMappingURL=createRemixRouteManifest.js.map