UNPKG

@sentry/nextjs

Version:
168 lines (165 loc) • 5.94 kB
import * as fs from 'fs'; import * as path from 'path'; import { getBuildLogger } from '../buildLogger.js'; const DEFAULT_LOCALE_PARAM_NAMES = ["locale", "lang", "language", "lng"]; let manifestCache = null; let lastAppDirPath = null; let lastIncludeRouteGroups = void 0; let lastLocaleParamNames = 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, localeParamNames) { 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, localeParamNames) }; } function hasOptionalPrefix(paramNames, localeParamNames) { const firstParam = paramNames[0]; if (firstParam === void 0) { return false; } return localeParamNames.includes(firstParam); } function scanAppDirectory(dir, basePath = "", includeRouteGroups = false, localeParamNames = DEFAULT_LOCALE_PARAM_NAMES, silent) { const dynamicRoutes = []; const staticRoutes = []; 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(":"); if (isDynamic) { const { regex, paramNames, hasOptionalPrefix: hasOptionalPrefix2 } = buildRegexForDynamicRoute(routePath, localeParamNames); 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, localeParamNames, silent); dynamicRoutes.push(...subRoutes.dynamicRoutes); staticRoutes.push(...subRoutes.staticRoutes); } } } catch (error) { getBuildLogger(silent).warn("[@sentry/nextjs] Error building route manifest:", error); } return { dynamicRoutes, staticRoutes }; } 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 { dynamicRoutes: [], staticRoutes: [] }; } const localeParamNames = options?.localeParamNames ?? DEFAULT_LOCALE_PARAM_NAMES; if (manifestCache && lastAppDirPath === targetDir && lastIncludeRouteGroups === options?.includeRouteGroups && lastLocaleParamNames?.join(",") === localeParamNames.join(",")) { return manifestCache; } const { dynamicRoutes, staticRoutes } = scanAppDirectory( targetDir, options?.basePath, options?.includeRouteGroups, localeParamNames, options?.silent ); const manifest = { dynamicRoutes, staticRoutes }; manifestCache = manifest; lastAppDirPath = targetDir; lastIncludeRouteGroups = options?.includeRouteGroups; lastLocaleParamNames = localeParamNames; return manifest; } export { DEFAULT_LOCALE_PARAM_NAMES, createRouteManifest }; //# sourceMappingURL=createRouteManifest.js.map