@sentry/nextjs
Version:
Official Sentry SDK for Next.js
180 lines (176 loc) • 6.09 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const fs = require('fs');
const path = require('path');
let manifestCache = null;
let lastAppDirPath = null;
let lastIncludeRouteGroups = void 0;
function isPageFile(filename) {
return filename === "page.tsx" || filename === "page.jsx" || filename === "page.ts" || filename === "page.js";
}
function isRouteGroup(name) {
return name.startsWith("(") && name.endsWith(")");
}
function normalizeRouteGroupPath(routePath) {
return routePath.replace(/\/\((?=[^)/]*\))[^)/]+\)/g, "");
}
function getDynamicRouteSegment(name) {
if (name.startsWith("[[...") && name.endsWith("]]")) {
const paramName = name.slice(5, -2);
return `:${paramName}*?`;
} else if (name.startsWith("[...") && name.endsWith("]")) {
const paramName = name.slice(4, -1);
return `:${paramName}*`;
}
return `:${name.slice(1, -1)}`;
}
function buildRegexForDynamicRoute(routePath) {
const segments = routePath.split("/").filter(Boolean);
const regexSegments = [];
const paramNames = [];
let hasOptionalCatchall = false;
for (const segment of segments) {
if (segment.startsWith(":")) {
const paramName = segment.substring(1);
if (paramName.endsWith("*?")) {
const cleanParamName = paramName.slice(0, -2);
paramNames.push(cleanParamName);
hasOptionalCatchall = true;
} else 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, "\\$&"));
}
}
let pattern;
if (hasOptionalCatchall) {
if (regexSegments.length === 0) {
pattern = "^/(.*)$";
} else {
const staticParts = regexSegments.join("/");
pattern = `^/${staticParts}(?:/(.*))?$`;
}
} else {
pattern = `^/${regexSegments.join("/")}$`;
}
return { regex: pattern, paramNames, hasOptionalPrefix: hasOptionalPrefix(paramNames) };
}
function hasOptionalPrefix(paramNames) {
const firstParam = paramNames[0];
if (firstParam === void 0) {
return false;
}
return firstParam === "locale" || firstParam === "lang" || firstParam === "language";
}
function checkForGenerateStaticParams(pageFilePath) {
try {
const content = fs.readFileSync(pageFilePath, "utf8");
return /export\s+(async\s+)?function\s+generateStaticParams|export\s+const\s+generateStaticParams/.test(content);
} catch {
return false;
}
}
function scanAppDirectory(dir, basePath = "", includeRouteGroups = false) {
const dynamicRoutes = [];
const staticRoutes = [];
const isrRoutes = [];
try {
const entries = fs.readdirSync(dir, { withFileTypes: true });
const pageFile = entries.find((entry) => isPageFile(entry.name));
if (pageFile) {
const routePath = includeRouteGroups ? basePath || "/" : normalizeRouteGroupPath(basePath || "/");
const isDynamic = routePath.includes(":");
const pageFilePath = path.join(dir, pageFile.name);
const hasGenerateStaticParams = checkForGenerateStaticParams(pageFilePath);
if (hasGenerateStaticParams) {
isrRoutes.push(routePath);
}
if (isDynamic) {
const { regex, paramNames, hasOptionalPrefix: hasOptionalPrefix2 } = buildRegexForDynamicRoute(routePath);
dynamicRoutes.push({
path: routePath,
regex,
paramNames,
hasOptionalPrefix: hasOptionalPrefix2
});
} else {
staticRoutes.push({
path: routePath
});
}
}
for (const entry of entries) {
if (entry.isDirectory()) {
const fullPath = path.join(dir, entry.name);
let routeSegment;
const isDynamic = entry.name.startsWith("[") && entry.name.endsWith("]");
const isRouteGroupDir = isRouteGroup(entry.name);
if (isRouteGroupDir) {
if (includeRouteGroups) {
routeSegment = entry.name;
} else {
routeSegment = "";
}
} else if (isDynamic) {
routeSegment = getDynamicRouteSegment(entry.name);
} else {
routeSegment = entry.name;
}
const newBasePath = routeSegment ? `${basePath}/${routeSegment}` : basePath;
const subRoutes = scanAppDirectory(fullPath, newBasePath, includeRouteGroups);
dynamicRoutes.push(...subRoutes.dynamicRoutes);
staticRoutes.push(...subRoutes.staticRoutes);
isrRoutes.push(...subRoutes.isrRoutes);
}
}
} catch (error) {
console.warn("Error building route manifest:", error);
}
return { dynamicRoutes, staticRoutes, isrRoutes };
}
function createRouteManifest(options) {
let targetDir;
if (options?.appDirPath) {
targetDir = options.appDirPath;
} else {
const projectDir = process.cwd();
const maybeAppDirPath = path.join(projectDir, "app");
const maybeSrcAppDirPath = path.join(projectDir, "src", "app");
if (fs.existsSync(maybeAppDirPath) && fs.lstatSync(maybeAppDirPath).isDirectory()) {
targetDir = maybeAppDirPath;
} else if (fs.existsSync(maybeSrcAppDirPath) && fs.lstatSync(maybeSrcAppDirPath).isDirectory()) {
targetDir = maybeSrcAppDirPath;
}
}
if (!targetDir) {
return {
isrRoutes: [],
dynamicRoutes: [],
staticRoutes: []
};
}
if (manifestCache && lastAppDirPath === targetDir && lastIncludeRouteGroups === options?.includeRouteGroups) {
return manifestCache;
}
const { dynamicRoutes, staticRoutes, isrRoutes } = scanAppDirectory(
targetDir,
options?.basePath,
options?.includeRouteGroups
);
const manifest = {
dynamicRoutes,
staticRoutes,
isrRoutes
};
manifestCache = manifest;
lastAppDirPath = targetDir;
lastIncludeRouteGroups = options?.includeRouteGroups;
return manifest;
}
exports.createRouteManifest = createRouteManifest;
//# sourceMappingURL=createRouteManifest.js.map