{"version":3,"file":"conflict-detector.mjs","sources":["../../../../src/lib/routing/core/conflict-detector.ts"],"sourcesContent":["/**\n * @file Route Conflict Detection Utilities\n * @description Framework-agnostic utilities for detecting route conflicts, ambiguities,\n * and potential issues in route configurations. Useful for build-time validation.\n *\n * @module @/lib/routing/core/conflict-detector\n *\n * @example\n * ```typescript\n * import {\n *   detectConflicts,\n *   findExactDuplicates,\n *   findDynamicShadows,\n *   sortBySpecificity,\n * } from '@/lib/routing/core/conflict-detector';\n *\n * const conflicts = detectConflicts(routes);\n * if (conflicts.hasErrors) {\n *   console.error(conflicts.report);\n * }\n * ```\n */\n\nimport type { ParsedRouteSegment } from './segment-parser';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Represents a discovered route for conflict detection\n */\nexport interface RouteForConflictDetection {\n  /** URL path pattern */\n  readonly urlPath: string;\n  /** Source file path (for error reporting) */\n  readonly filePath: string;\n  /** Parsed segments */\n  readonly segments: readonly ParsedRouteSegment[];\n  /** Whether this is a layout */\n  readonly isLayout: boolean;\n  /** Whether this is an index route */\n  readonly isIndex: boolean;\n  /** Nesting depth */\n  readonly depth: number;\n}\n\n/**\n * Type of route conflict\n */\nexport type ConflictType = 'exact' | 'ambiguous' | 'shadow';\n\n/**\n * Severity of a conflict\n */\nexport type ConflictSeverity = 'error' | 'warning';\n\n/**\n * Route conflict information\n */\nexport interface RouteConflict {\n  /** Type of conflict */\n  readonly type: ConflictType;\n  /** Conflicting path pattern */\n  readonly path: string;\n  /** Files involved in conflict */\n  readonly files: readonly string[];\n  /** Human-readable message */\n  readonly message: string;\n  /** Severity level */\n  readonly severity: ConflictSeverity;\n}\n\n/**\n * Result of conflict detection analysis\n */\nexport interface ConflictDetectionResult {\n  /** Whether any errors were detected */\n  readonly hasErrors: boolean;\n  /** Whether any warnings were detected */\n  readonly hasWarnings: boolean;\n  /** List of detected conflicts */\n  readonly conflicts: readonly RouteConflict[];\n  /** Human-readable report */\n  readonly report: string;\n}\n\n/**\n * Options for conflict detection\n */\nexport interface ConflictDetectionOptions {\n  /** Maximum nesting depth before warning */\n  maxNestingDepth?: number;\n  /** Check for nested dynamic conflicts */\n  checkNestedDynamic?: boolean;\n  /** Check for deep nesting warnings */\n  checkDeepNesting?: boolean;\n  /** Check for index-layout conflicts */\n  checkIndexLayouts?: boolean;\n}\n\n// =============================================================================\n// Main Detection Functions\n// =============================================================================\n\n/**\n * Detect all route conflicts in a set of routes\n *\n * @param routes - Routes to check for conflicts\n * @param options - Detection options\n * @returns Conflict detection result\n */\nexport function detectConflicts(\n  routes: readonly RouteForConflictDetection[],\n  options: ConflictDetectionOptions = {}\n): ConflictDetectionResult {\n  const {\n    maxNestingDepth = 5,\n    checkNestedDynamic = true,\n    checkDeepNesting = true,\n    checkIndexLayouts = true,\n  } = options;\n\n  const conflicts: RouteConflict[] = [];\n\n  // Filter out layouts for most conflict detection\n  const routeRoutes = routes.filter((r) => !r.isLayout);\n\n  // Core conflict detection\n  conflicts.push(...findExactDuplicates(routeRoutes));\n  conflicts.push(...findDynamicShadows(routeRoutes));\n  conflicts.push(...findAmbiguousRoutes(routeRoutes));\n  conflicts.push(...findCatchAllConflicts(routeRoutes));\n\n  // Advanced conflict detection\n  if (checkNestedDynamic) {\n    conflicts.push(...findNestedDynamicConflicts(routeRoutes));\n  }\n\n  if (checkDeepNesting) {\n    conflicts.push(...findDeepNestingWarnings(routes, maxNestingDepth));\n  }\n\n  if (checkIndexLayouts) {\n    conflicts.push(...findIndexLayoutConflicts(routes));\n  }\n\n  return {\n    hasErrors: conflicts.some((c) => c.severity === 'error'),\n    hasWarnings: conflicts.some((c) => c.severity === 'warning'),\n    conflicts,\n    report: generateConflictReport(conflicts),\n  };\n}\n\n// =============================================================================\n// Duplicate Detection\n// =============================================================================\n\n/**\n * Find routes with exactly the same URL path\n *\n * @param routes - Routes to check\n * @returns Array of duplicate conflicts\n */\nexport function findExactDuplicates(routes: readonly RouteForConflictDetection[]): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n  const pathGroups = new Map<string, RouteForConflictDetection[]>();\n\n  // Group routes by URL path\n  for (const route of routes) {\n    const existing = pathGroups.get(route.urlPath) ?? [];\n    existing.push(route);\n    pathGroups.set(route.urlPath, existing);\n  }\n\n  // Find groups with more than one route\n  for (const [path, routeGroup] of pathGroups) {\n    if (routeGroup.length > 1) {\n      conflicts.push({\n        type: 'exact',\n        path,\n        files: routeGroup.map((r) => r.filePath),\n        message: `Duplicate route definition for \"${path}\". Only one route file should define this path.`,\n        severity: 'error',\n      });\n    }\n  }\n\n  return conflicts;\n}\n\n// =============================================================================\n// Shadow Detection\n// =============================================================================\n\n/**\n * Find static routes that would be shadowed by dynamic routes\n *\n * Example: `/users/new` would be matched by `/users/:id` before reaching the static route\n *\n * @param routes - Routes to check\n * @returns Array of shadow conflicts\n */\nexport function findDynamicShadows(routes: readonly RouteForConflictDetection[]): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n\n  // Separate static and dynamic routes\n  const staticRoutes = routes.filter(\n    (r) => !r.segments.some((s) => s.type === 'dynamic' || s.type === 'catchAll')\n  );\n\n  const dynamicRoutes = routes.filter((r) => r.segments.some((s) => s.type === 'dynamic'));\n\n  // Check each static route against dynamic routes\n  for (const staticRoute of staticRoutes) {\n    for (const dynamicRoute of dynamicRoutes) {\n      if (wouldShadow(dynamicRoute.urlPath, staticRoute.urlPath)) {\n        conflicts.push({\n          type: 'shadow',\n          path: staticRoute.urlPath,\n          files: [dynamicRoute.filePath, staticRoute.filePath],\n          message:\n            `Static route \"${staticRoute.urlPath}\" may be shadowed by dynamic route \"${dynamicRoute.urlPath}\". ` +\n            `Consider renaming to avoid confusion or ensure proper route ordering.`,\n          severity: 'warning',\n        });\n      }\n    }\n  }\n\n  return conflicts;\n}\n\n/**\n * Check if a dynamic route pattern would match a static path\n */\nfunction wouldShadow(dynamicPath: string, staticPath: string): boolean {\n  const dynamicParts = dynamicPath.split('/').filter(Boolean);\n  const staticParts = staticPath.split('/').filter(Boolean);\n\n  // Different lengths can't shadow (unless catch-all)\n  if (dynamicParts.length !== staticParts.length) {\n    return false;\n  }\n\n  // Check each segment\n  for (let i = 0; i < dynamicParts.length; i++) {\n    const dynamicPart = dynamicParts[i];\n    const staticPart = staticParts[i];\n\n    if (dynamicPart == null || staticPart == null) {\n      continue;\n    }\n\n    // Dynamic segment matches anything\n    if (dynamicPart.startsWith(':')) {\n      continue;\n    }\n\n    // Static segments must match exactly\n    if (dynamicPart !== staticPart) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n// =============================================================================\n// Ambiguous Route Detection\n// =============================================================================\n\n/**\n * Find ambiguous dynamic routes at the same path level\n *\n * Example: `[id].tsx` and `[slug].tsx` in the same directory\n *\n * @param routes - Routes to check\n * @returns Array of ambiguous conflicts\n */\nexport function findAmbiguousRoutes(routes: readonly RouteForConflictDetection[]): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n\n  // Group routes by their \"normalized\" path (dynamic segments replaced)\n  const normalizedGroups = new Map<string, RouteForConflictDetection[]>();\n\n  for (const route of routes) {\n    const normalized = normalizePathPattern(route.urlPath);\n    const existing = normalizedGroups.get(normalized) ?? [];\n    existing.push(route);\n    normalizedGroups.set(normalized, existing);\n  }\n\n  // Find groups with multiple different dynamic param names\n  for (const [, routeGroup] of normalizedGroups) {\n    if (routeGroup.length <= 1) continue;\n\n    // Check if they have different param names at the same position\n    const paramSignatures = routeGroup.map((r) => getParamSignature(r.urlPath));\n    const uniqueSignatures = new Set(paramSignatures);\n\n    const [firstRoute] = routeGroup;\n    if (uniqueSignatures.size > 1 && firstRoute) {\n      conflicts.push({\n        type: 'ambiguous',\n        path: firstRoute.urlPath,\n        files: routeGroup.map((r) => r.filePath),\n        message:\n          `Ambiguous dynamic routes with different parameter names: ${routeGroup.map((r) => r.filePath).join(', ')}. ` +\n          `These routes are indistinguishable at runtime.`,\n        severity: 'error',\n      });\n    }\n  }\n\n  return conflicts;\n}\n\n/**\n * Normalize a path pattern by replacing dynamic segments with placeholders\n */\nfunction normalizePathPattern(path: string): string {\n  return path\n    .replace(/:[^/?]+\\?/g, ':optional')\n    .replace(/:[^/]+/g, ':param')\n    .replace(/\\*/g, ':catchall');\n}\n\n/**\n * Get a signature of parameter names in a path\n */\nfunction getParamSignature(path: string): string {\n  const params = path.match(/:[^/?]+/g) ?? [];\n  return params.join(',');\n}\n\n// =============================================================================\n// Catch-All Conflict Detection\n// =============================================================================\n\n/**\n * Find catch-all routes that conflict with each other\n *\n * @param routes - Routes to check\n * @returns Array of catch-all conflicts\n */\nexport function findCatchAllConflicts(\n  routes: readonly RouteForConflictDetection[]\n): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n\n  const catchAllRoutes = routes.filter((r) => r.segments.some((s) => s.type === 'catchAll'));\n\n  // Multiple catch-all routes at the same path prefix is an error\n  const catchAllByPrefix = new Map<string, RouteForConflictDetection[]>();\n\n  for (const route of catchAllRoutes) {\n    const prefix = route.urlPath.replace(/\\/\\*$/, '');\n    const existing = catchAllByPrefix.get(prefix) ?? [];\n    existing.push(route);\n    catchAllByPrefix.set(prefix, existing);\n  }\n\n  for (const [prefix, routeGroup] of catchAllByPrefix) {\n    if (routeGroup.length > 1) {\n      conflicts.push({\n        type: 'exact',\n        path: `${prefix}/*`,\n        files: routeGroup.map((r) => r.filePath),\n        message: `Multiple catch-all routes at \"${prefix}/*\". Only one catch-all route is allowed per path prefix.`,\n        severity: 'error',\n      });\n    }\n  }\n\n  return conflicts;\n}\n\n// =============================================================================\n// Advanced Conflict Detection\n// =============================================================================\n\n/**\n * Detect nested dynamic route conflicts\n *\n * Example: /users/:id/posts/:postId vs /users/:userId/comments/:commentId\n *\n * @param routes - Routes to check\n * @returns Array of nested dynamic conflicts\n */\nexport function findNestedDynamicConflicts(\n  routes: readonly RouteForConflictDetection[]\n): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n  const dynamicRoutes = routes.filter(\n    (r) => r.segments.filter((s) => s.type === 'dynamic').length >= 2\n  );\n\n  // Group by static prefix before first dynamic segment\n  const groupedByPrefix = new Map<string, RouteForConflictDetection[]>();\n\n  for (const route of dynamicRoutes) {\n    const staticPrefix = getStaticPathPrefix(route.urlPath);\n    const existing = groupedByPrefix.get(staticPrefix) ?? [];\n    existing.push(route);\n    groupedByPrefix.set(staticPrefix, existing);\n  }\n\n  // Check each group for nested conflicts\n  for (const [prefix, routeGroup] of groupedByPrefix) {\n    if (routeGroup.length <= 1) continue;\n\n    // Check if routes have same structure but different param names\n    const structures = routeGroup.map((r) => getRouteStructure(r.urlPath));\n    const uniqueStructures = new Set(structures);\n\n    // Same structure with different param names\n    if (uniqueStructures.size === 1 && routeGroup.length > 1) {\n      const paramSignatures = routeGroup.map((r) => getParamNames(r.urlPath).join(','));\n      const uniqueParams = new Set(paramSignatures);\n\n      if (uniqueParams.size > 1) {\n        conflicts.push({\n          type: 'ambiguous',\n          path: prefix,\n          files: routeGroup.map((r) => r.filePath),\n          message:\n            `Nested dynamic routes under \"${prefix}\" have conflicting parameter names. ` +\n            `Routes: ${routeGroup.map((r) => r.urlPath).join(', ')}. ` +\n            `This may cause confusion and runtime issues.`,\n          severity: 'warning',\n        });\n      }\n    }\n  }\n\n  return conflicts;\n}\n\n/**\n * Get the static prefix of a path (before first dynamic segment)\n */\nfunction getStaticPathPrefix(path: string): string {\n  const parts = path.split('/').filter(Boolean);\n  const staticParts: string[] = [];\n\n  for (const part of parts) {\n    if (part.startsWith(':') || part === '*') break;\n    staticParts.push(part);\n  }\n\n  return `/${staticParts.join('/')}`;\n}\n\n/**\n * Get route structure (static/dynamic pattern)\n */\nfunction getRouteStructure(path: string): string {\n  return path\n    .split('/')\n    .filter(Boolean)\n    .map((part) => {\n      if (part.startsWith(':')) return ':param';\n      if (part === '*') return '*';\n      return 'static';\n    })\n    .join('/');\n}\n\n/**\n * Get parameter names from path\n */\nfunction getParamNames(path: string): string[] {\n  const matches = path.match(/:[^/?]+/g) ?? [];\n  return matches.map((m) => m.slice(1).replace('?', ''));\n}\n\n/**\n * Detect deep nesting issues (warning)\n *\n * @param routes - Routes to check\n * @param maxDepth - Maximum allowed depth\n * @returns Array of deep nesting conflicts\n */\nexport function findDeepNestingWarnings(\n  routes: readonly RouteForConflictDetection[],\n  maxDepth: number = 5\n): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n\n  for (const route of routes) {\n    if (route.depth > maxDepth) {\n      conflicts.push({\n        type: 'shadow', // Using shadow as a proxy for warning type\n        path: route.urlPath,\n        files: [route.filePath],\n        message:\n          `Route \"${route.urlPath}\" has ${route.depth} levels of nesting, ` +\n          `exceeding the recommended maximum of ${maxDepth}. ` +\n          `Consider flattening your route structure for better maintainability.`,\n        severity: 'warning',\n      });\n    }\n  }\n\n  return conflicts;\n}\n\n/**\n * Detect index route conflicts\n *\n * Example: index.tsx and _layout.tsx both trying to render at same path\n *\n * @param routes - Routes to check\n * @returns Array of index-layout conflicts\n */\nexport function findIndexLayoutConflicts(\n  routes: readonly RouteForConflictDetection[]\n): RouteConflict[] {\n  const conflicts: RouteConflict[] = [];\n\n  const indexRoutes = routes.filter((r) => r.isIndex);\n  const layoutRoutes = routes.filter((r) => r.isLayout);\n\n  // Check for index routes without a layout\n  for (const index of indexRoutes) {\n    const hasLayout = layoutRoutes.some((layout) =>\n      index.filePath.startsWith(layout.filePath.replace(/[/\\\\][^/\\\\]+$/, ''))\n    );\n\n    if (!hasLayout && index.depth > 1) {\n      conflicts.push({\n        type: 'shadow',\n        path: index.urlPath,\n        files: [index.filePath],\n        message:\n          `Index route at \"${index.urlPath}\" has no parent layout. ` +\n          `Consider adding a _layout.tsx file for consistent page structure.`,\n        severity: 'warning',\n      });\n    }\n  }\n\n  return conflicts;\n}\n\n// =============================================================================\n// Report Generation\n// =============================================================================\n\n/**\n * Generate a human-readable conflict report\n *\n * @param conflicts - Array of conflicts\n * @returns Formatted report string\n */\nexport function generateConflictReport(conflicts: readonly RouteConflict[]): string {\n  if (conflicts.length === 0) {\n    return 'No route conflicts detected.';\n  }\n\n  const lines: string[] = ['', '='.repeat(70), '  ROUTE CONFLICT REPORT', '='.repeat(70), ''];\n\n  const errors = conflicts.filter((c) => c.severity === 'error');\n  const warnings = conflicts.filter((c) => c.severity === 'warning');\n\n  if (errors.length > 0) {\n    lines.push(`ERRORS (${errors.length}):`);\n    lines.push('-'.repeat(50));\n    lines.push('');\n\n    for (const error of errors) {\n      lines.push(`  [${error.type.toUpperCase()}] ${error.message}`);\n      lines.push('');\n      lines.push('  Files involved:');\n      for (const file of error.files) {\n        lines.push(`    - ${file}`);\n      }\n      lines.push('');\n    }\n  }\n\n  if (warnings.length > 0) {\n    lines.push(`WARNINGS (${warnings.length}):`);\n    lines.push('-'.repeat(50));\n    lines.push('');\n\n    for (const warning of warnings) {\n      lines.push(`  [${warning.type.toUpperCase()}] ${warning.message}`);\n      lines.push('');\n      lines.push('  Files involved:');\n      for (const file of warning.files) {\n        lines.push(`    - ${file}`);\n      }\n      lines.push('');\n    }\n  }\n\n  lines.push('='.repeat(70));\n  lines.push('');\n\n  return lines.join('\\n');\n}\n\n// =============================================================================\n// Route Specificity\n// =============================================================================\n\n/**\n * Calculate route specificity for proper ordering\n *\n * Higher specificity = more specific route = should be matched first\n *\n * @param route - Route to calculate specificity for\n * @returns Specificity score\n */\nexport function calculateRouteSpecificity(route: RouteForConflictDetection): number {\n  let specificity = 0;\n\n  for (const segment of route.segments) {\n    switch (segment.type) {\n      case 'static':\n        specificity += 100;\n        break;\n      case 'index':\n        specificity += 90;\n        break;\n      case 'dynamic':\n        specificity += 50;\n        break;\n      case 'optional':\n        specificity += 30;\n        break;\n      case 'catchAll':\n        specificity += 10;\n        break;\n      case 'group':\n      case 'layout':\n        // These don't affect specificity\n        break;\n    }\n  }\n\n  return specificity;\n}\n\n/**\n * Sort routes by specificity (most specific first)\n *\n * @param routes - Routes to sort\n * @returns Sorted routes array\n */\nexport function sortBySpecificity<T extends RouteForConflictDetection>(routes: readonly T[]): T[] {\n  return [...routes].sort((a, b) => {\n    const specA = calculateRouteSpecificity(a);\n    const specB = calculateRouteSpecificity(b);\n\n    // Higher specificity first\n    if (specA !== specB) {\n      return specB - specA;\n    }\n\n    // Same specificity: shorter path first\n    if (a.depth !== b.depth) {\n      return a.depth - b.depth;\n    }\n\n    // Same depth: alphabetical\n    return a.urlPath.localeCompare(b.urlPath);\n  });\n}\n\n// =============================================================================\n// Validation Utilities\n// =============================================================================\n\n/**\n * Validate routes and throw on errors\n *\n * @param routes - Routes to validate\n * @throws Error if route conflicts are detected\n */\nexport function validateRoutes(routes: readonly RouteForConflictDetection[]): void {\n  const result = detectConflicts(routes);\n\n  if (result.hasErrors) {\n    throw new Error(\n      `Route conflict detection failed with ${result.conflicts.filter((c) => c.severity === 'error').length} error(s). ` +\n        `See console for details.`\n    );\n  }\n}\n\n/**\n * Check if routes are valid (without throwing)\n *\n * @param routes - Routes to validate\n * @returns True if no errors found\n */\nexport function areRoutesValid(routes: readonly RouteForConflictDetection[]): boolean {\n  const result = detectConflicts(routes);\n  return !result.hasErrors;\n}\n"],"names":["detectConflicts","routes","options","maxNestingDepth","checkNestedDynamic","checkDeepNesting","checkIndexLayouts","conflicts","routeRoutes","r","findExactDuplicates","findDynamicShadows","findAmbiguousRoutes","findCatchAllConflicts","findNestedDynamicConflicts","findDeepNestingWarnings","findIndexLayoutConflicts","c","generateConflictReport","pathGroups","route","existing","path","routeGroup","staticRoutes","s","dynamicRoutes","staticRoute","dynamicRoute","wouldShadow","dynamicPath","staticPath","dynamicParts","staticParts","i","dynamicPart","staticPart","normalizedGroups","normalized","normalizePathPattern","paramSignatures","getParamSignature","uniqueSignatures","firstRoute","catchAllRoutes","catchAllByPrefix","prefix","groupedByPrefix","staticPrefix","getStaticPathPrefix","structures","getRouteStructure","getParamNames","parts","part","m","maxDepth","indexRoutes","layoutRoutes","index","layout","lines","errors","warnings","error","file","warning","calculateRouteSpecificity","specificity","segment","sortBySpecificity","a","b","specA","specB","validateRoutes","result","areRoutesValid"],"mappings":"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"}