{"version":3,"file":"route-validator.mjs","sources":["../../../src/lib/routing/route-validator.ts"],"sourcesContent":["/**\n * @file Route Validation Utilities\n * @description Comprehensive route file validation with auto-fix suggestions\n */\n\nimport type {\n  DiscoveredRoute,\n  RouteValidationResult,\n  RouteValidationError,\n  RouteValidationWarning,\n  RouteFixSuggestion,\n  RouteErrorCode,\n  RouteWarningCode,\n} from './types';\nimport { detectAllConflicts, generateFixSuggestions } from './conflict-detector';\nimport { splitPath } from './core/path-utils';\n\n// =============================================================================\n// Validation Rules\n// =============================================================================\n\n/**\n * Validation rule configuration\n */\nexport interface ValidationRule {\n  /** Rule ID */\n  readonly id: string;\n  /** Rule name */\n  readonly name: string;\n  /** Rule description */\n  readonly description: string;\n  /** Severity level */\n  readonly severity: 'error' | 'warning';\n  /** Whether the rule is enabled by default */\n  readonly enabledByDefault: boolean;\n  /** Validation function */\n  readonly validate: (\n    route: DiscoveredRoute,\n    allRoutes: readonly DiscoveredRoute[]\n  ) => ValidationRuleResult | null;\n}\n\n/**\n * Result of a validation rule check\n */\nexport interface ValidationRuleResult {\n  readonly passed: boolean;\n  readonly message?: string;\n  readonly suggestion?: RouteFixSuggestion;\n}\n\n/**\n * Validation options\n */\nexport interface ValidationOptions {\n  /** Maximum allowed nesting depth */\n  maxNestingDepth?: number;\n  /** Require loader functions for data routes */\n  requireLoaders?: boolean;\n  /** Require error boundaries */\n  requireErrorBoundaries?: boolean;\n  /** Check for consistent naming */\n  checkNamingConventions?: boolean;\n  /** List of disabled rules */\n  disabledRules?: readonly string[];\n}\n\n// =============================================================================\n// Built-in Validation Rules\n// =============================================================================\n\n/**\n * Check for valid route segment naming\n */\nconst validSegmentNamingRule: ValidationRule = {\n  id: 'valid-segment-naming',\n  name: 'Valid Segment Naming',\n  description: 'Route segments should use valid naming conventions',\n  severity: 'error',\n  enabledByDefault: true,\n  validate(route) {\n    for (const segment of route.segments) {\n      // Check for invalid characters in static segments\n      if (segment.type === 'static') {\n        if (!/^[a-z0-9-]+$/i.test(segment.name)) {\n          return {\n            passed: false,\n            message: `Invalid segment name \"${segment.name}\" in route \"${route.urlPath}\". Use only alphanumeric characters and hyphens.`,\n            suggestion: {\n              description: 'Rename segment to use valid characters',\n              oldValue: segment.name,\n              newValue: segment.name.toLowerCase().replace(/[^a-z0-9-]/g, '-'),\n              autoFixable: true,\n            },\n          };\n        }\n      }\n\n      // Check for valid dynamic parameter names\n      if (segment.type === 'dynamic' || segment.type === 'optional') {\n        if ((segment.paramName != null) && !/^[a-z][a-zA-Z0-9]*$/.test(segment.paramName)) {\n          return {\n            passed: false,\n            message: `Invalid parameter name \"${segment.paramName}\" in route \"${route.urlPath}\". Use camelCase naming.`,\n            suggestion: {\n              description: 'Rename parameter to use camelCase',\n              oldValue: segment.paramName,\n              newValue: toCamelCase(segment.paramName),\n              autoFixable: true,\n            },\n          };\n        }\n      }\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * Check for catch-all route placement\n */\nconst catchAllPlacementRule: ValidationRule = {\n  id: 'catch-all-placement',\n  name: 'Catch-All Placement',\n  description: 'Catch-all routes should be at the end of the path',\n  severity: 'error',\n  enabledByDefault: true,\n  validate(route) {\n    const catchAllIndex = route.segments.findIndex((s) => s.type === 'catchAll');\n\n    if (catchAllIndex !== -1 && catchAllIndex !== route.segments.length - 1) {\n      return {\n        passed: false,\n        message: `Catch-all segment in \"${route.urlPath}\" must be the last segment.`,\n      };\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * Check for reasonable nesting depth\n */\nconst nestingDepthRule: ValidationRule = {\n  id: 'nesting-depth',\n  name: 'Nesting Depth',\n  description: 'Routes should not be too deeply nested',\n  severity: 'warning',\n  enabledByDefault: true,\n  validate(route) {\n    const maxDepth = 5; // Can be configured\n\n    if (route.depth > maxDepth) {\n      return {\n        passed: false,\n        message: `Route \"${route.urlPath}\" has ${route.depth} levels of nesting. Consider flattening to improve maintainability.`,\n        suggestion: {\n          description: 'Consider restructuring to reduce nesting',\n          oldValue: route.urlPath,\n          newValue: flattenPath(route.urlPath),\n          autoFixable: false,\n        },\n      };\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * Check for consistent file naming\n */\nconst fileNamingConventionRule: ValidationRule = {\n  id: 'file-naming-convention',\n  name: 'File Naming Convention',\n  description: 'Route files should follow consistent naming conventions',\n  severity: 'warning',\n  enabledByDefault: true,\n  validate(route) {\n    const filename = route.filePath.split('/').pop() ?? '';\n\n    // Check for PascalCase for page components\n    if (!route.isLayout && !route.isIndex) {\n      const nameWithoutExt = filename.replace(/\\.(tsx?|jsx?)$/, '');\n\n      // Skip dynamic segments\n      if (nameWithoutExt.startsWith('[')) {\n        return { passed: true };\n      }\n\n      // Check if PascalCase\n      if (!/^[A-Z][a-zA-Z0-9]*$/.test(nameWithoutExt)) {\n        return {\n          passed: false,\n          message: `Route file \"${filename}\" should use PascalCase naming (e.g., \"${toPascalCase(nameWithoutExt)}.tsx\").`,\n          suggestion: {\n            description: 'Rename file to use PascalCase',\n            oldValue: filename,\n            newValue: `${toPascalCase(nameWithoutExt)}.tsx`,\n            autoFixable: true,\n          },\n        };\n      }\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * Check for orphaned layouts\n */\nconst orphanedLayoutRule: ValidationRule = {\n  id: 'orphaned-layout',\n  name: 'Orphaned Layout',\n  description: 'Layouts should have at least one child route',\n  severity: 'warning',\n  enabledByDefault: true,\n  validate(route, allRoutes) {\n    if (!route.isLayout) return { passed: true };\n\n    const hasChildren = allRoutes.some(\n      (r) => !r.isLayout && r.parentLayout === route.filePath\n    );\n\n    if (!hasChildren) {\n      return {\n        passed: false,\n        message: `Layout \"${route.filePath}\" has no child routes. Consider removing or adding routes.`,\n      };\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * Check for duplicate path segments\n */\nconst duplicateSegmentsRule: ValidationRule = {\n  id: 'duplicate-segments',\n  name: 'Duplicate Segments',\n  description: 'Avoid repeating the same segment in a path',\n  severity: 'warning',\n  enabledByDefault: true,\n  validate(route) {\n    const staticSegments = route.segments\n      .filter((s) => s.type === 'static')\n      .map((s) => s.name);\n\n    const seen = new Set<string>();\n    for (const segment of staticSegments) {\n      if (seen.has(segment)) {\n        return {\n          passed: false,\n          message: `Route \"${route.urlPath}\" has duplicate segment \"${segment}\". This may cause confusion.`,\n        };\n      }\n      seen.add(segment);\n    }\n\n    return { passed: true };\n  },\n};\n\n/**\n * All built-in validation rules\n */\nexport const BUILT_IN_RULES: readonly ValidationRule[] = [\n  validSegmentNamingRule,\n  catchAllPlacementRule,\n  nestingDepthRule,\n  fileNamingConventionRule,\n  orphanedLayoutRule,\n  duplicateSegmentsRule,\n];\n\n// =============================================================================\n// Validation Engine\n// =============================================================================\n\n/**\n * Validate a single route against all rules\n */\nexport function validateRoute(\n  route: DiscoveredRoute,\n  allRoutes: readonly DiscoveredRoute[],\n  rules: readonly ValidationRule[] = BUILT_IN_RULES,\n  options: ValidationOptions = {}\n): RouteValidationResult {\n  const errors: RouteValidationError[] = [];\n  const warnings: RouteValidationWarning[] = [];\n  const suggestions: RouteFixSuggestion[] = [];\n\n  const disabledRules = new Set(options.disabledRules ?? []);\n\n  for (const rule of rules) {\n    if (disabledRules.has(rule.id)) continue;\n    if (!rule.enabledByDefault && !isRuleExplicitlyEnabled(rule.id, options)) continue;\n\n    const result = rule.validate(route, allRoutes);\n\n    if (result && !result.passed) {\n      if (rule.severity === 'error') {\n        errors.push({\n          code: rule.id as RouteErrorCode,\n          message: result.message ?? `Rule \"${rule.name}\" failed`,\n          filePath: route.filePath,\n        });\n      } else {\n        warnings.push({\n          code: rule.id as RouteWarningCode,\n          message: result.message ?? `Rule \"${rule.name}\" warning`,\n          filePath: route.filePath,\n          suggestion: result.suggestion?.description,\n        });\n      }\n\n      if (result.suggestion) {\n        suggestions.push(result.suggestion);\n      }\n    }\n  }\n\n  return {\n    isValid: errors.length === 0,\n    errors,\n    warnings,\n    suggestions,\n  };\n}\n\n/**\n * Validate all routes\n */\nexport function validateAllRoutes(\n  routes: readonly DiscoveredRoute[],\n  options: ValidationOptions = {}\n): RouteValidationResult {\n  const allErrors: RouteValidationError[] = [];\n  const allWarnings: RouteValidationWarning[] = [];\n  const allSuggestions: RouteFixSuggestion[] = [];\n\n  // Validate each route individually\n  for (const route of routes) {\n    const result = validateRoute(route, routes, BUILT_IN_RULES, options);\n    allErrors.push(...result.errors);\n    allWarnings.push(...result.warnings);\n    allSuggestions.push(...result.suggestions);\n  }\n\n  // Run conflict detection\n  const conflictResult = detectAllConflicts(routes, {\n    maxNestingDepth: options.maxNestingDepth,\n    checkNestedDynamic: true,\n    checkDeepNesting: true,\n    checkIndexLayouts: true,\n  });\n\n  // Convert conflicts to errors/warnings\n  for (const conflict of conflictResult.conflicts) {\n    if (conflict.severity === 'error') {\n      allErrors.push({\n        code: conflict.type.toUpperCase() as RouteErrorCode,\n        message: conflict.message,\n        filePath: conflict.files[0] ?? '',\n      });\n    } else {\n      allWarnings.push({\n        code: conflict.type.toUpperCase() as RouteWarningCode,\n        message: conflict.message,\n        filePath: conflict.files[0] ?? '',\n      });\n    }\n  }\n\n  // Generate fix suggestions for conflicts\n  const conflictSuggestions = generateFixSuggestions(conflictResult.conflicts);\n  allSuggestions.push(...conflictSuggestions);\n\n  return {\n    isValid: allErrors.length === 0,\n    errors: allErrors,\n    warnings: allWarnings,\n    suggestions: allSuggestions,\n  };\n}\n\n/**\n * Generate a validation report\n */\nexport function generateValidationReport(result: RouteValidationResult): string {\n  const lines: string[] = [\n    '',\n    '='.repeat(70),\n    '  ROUTE VALIDATION REPORT',\n    '='.repeat(70),\n    '',\n  ];\n\n  if (result.isValid && result.warnings.length === 0) {\n    lines.push('All routes passed validation.');\n    lines.push('');\n    return lines.join('\\n');\n  }\n\n  if (result.errors.length > 0) {\n    lines.push(`ERRORS (${result.errors.length}):`);\n    lines.push('-'.repeat(50));\n    lines.push('');\n\n    for (const error of result.errors) {\n      lines.push(`  [${error.code}] ${error.message}`);\n      lines.push(`  File: ${error.filePath}`);\n      if (error.line != null) {\n        lines.push(`  Line: ${error.line}${(error.column != null) ? `:${error.column}` : ''}`);\n      }\n      lines.push('');\n    }\n  }\n\n  if (result.warnings.length > 0) {\n    lines.push(`WARNINGS (${result.warnings.length}):`);\n    lines.push('-'.repeat(50));\n    lines.push('');\n\n    for (const warning of result.warnings) {\n      lines.push(`  [${warning.code}] ${warning.message}`);\n      lines.push(`  File: ${warning.filePath}`);\n      if (warning.suggestion != null) {\n        lines.push(`  Suggestion: ${warning.suggestion}`);\n      }\n      lines.push('');\n    }\n  }\n\n  if (result.suggestions.length > 0) {\n    lines.push('FIX SUGGESTIONS:');\n    lines.push('-'.repeat(50));\n    lines.push('');\n\n    for (const suggestion of result.suggestions) {\n      lines.push(`  ${suggestion.description}`);\n      if (suggestion.oldValue && suggestion.newValue) {\n        lines.push(`    Change: \"${suggestion.oldValue}\" -> \"${suggestion.newValue}\"`);\n      }\n      lines.push(`    Auto-fixable: ${suggestion.autoFixable ? 'Yes' : 'No'}`);\n      lines.push('');\n    }\n  }\n\n  lines.push('='.repeat(70));\n  lines.push('');\n\n  return lines.join('\\n');\n}\n\n// =============================================================================\n// Auto-Fix Utilities\n// =============================================================================\n\n/**\n * Auto-fix result\n */\nexport interface AutoFixResult {\n  readonly applied: readonly RouteFixSuggestion[];\n  readonly skipped: readonly RouteFixSuggestion[];\n  readonly errors: readonly { suggestion: RouteFixSuggestion; error: Error }[];\n}\n\n/**\n * Apply auto-fixable suggestions\n * Note: This returns the fix operations to be performed, actual file operations\n * should be done by the caller (Vite plugin or CLI)\n */\nexport function getAutoFixOperations(\n  suggestions: readonly RouteFixSuggestion[]\n): {\n  fileRenames: Array<{ oldPath: string; newPath: string }>;\n  contentChanges: Array<{ filePath: string; search: string; replace: string }>;\n} {\n  const fileRenames: Array<{ oldPath: string; newPath: string }> = [];\n  const contentChanges: Array<{ filePath: string; search: string; replace: string }> = [];\n\n  for (const suggestion of suggestions) {\n    if (!suggestion.autoFixable) continue;\n\n    // Detect file rename suggestions\n    if (\n      suggestion.oldValue.includes('/') &&\n      suggestion.newValue.includes('/') &&\n      suggestion.oldValue !== suggestion.newValue\n    ) {\n      fileRenames.push({\n        oldPath: suggestion.oldValue,\n        newPath: suggestion.newValue,\n      });\n    }\n    // Detect content changes\n    else if (suggestion.oldValue && suggestion.newValue) {\n      contentChanges.push({\n        filePath: '', // Will be determined by caller\n        search: suggestion.oldValue,\n        replace: suggestion.newValue,\n      });\n    }\n  }\n\n  return { fileRenames, contentChanges };\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Convert string to camelCase\n */\nfunction toCamelCase(str: string): string {\n  return str\n    .replace(/[-_](.)/g, (_: string, char: string) => char.toUpperCase())\n    .replace(/^(.)/, (_: string, char: string) => char.toLowerCase());\n}\n\n/**\n * Convert string to PascalCase\n */\nfunction toPascalCase(str: string): string {\n  return str\n    .replace(/[-_](.)/g, (_: string, char: string) => char.toUpperCase())\n    .replace(/^(.)/, (_: string, char: string) => char.toUpperCase());\n}\n\n/**\n * Flatten a deep path\n */\nfunction flattenPath(path: string): string {\n  const parts = splitPath(path);\n  if (parts.length <= 3) return path;\n\n  // Keep first and last two segments\n  return `/${parts[0]}/${parts.slice(-2).join('/')}`;\n}\n\n/**\n * Check if a rule is explicitly enabled in options\n */\nfunction isRuleExplicitlyEnabled(\n  _ruleId: string,\n  _options: ValidationOptions\n): boolean {\n  // Could be extended to support explicit rule enabling\n  return false;\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\n// Exports moved to avoid conflicts within routing module\n"],"names":["validSegmentNamingRule","route","segment","toCamelCase","catchAllPlacementRule","catchAllIndex","s","nestingDepthRule","flattenPath","fileNamingConventionRule","filename","nameWithoutExt","toPascalCase","orphanedLayoutRule","allRoutes","r","duplicateSegmentsRule","staticSegments","seen","BUILT_IN_RULES","validateRoute","rules","options","errors","warnings","suggestions","disabledRules","rule","isRuleExplicitlyEnabled","result","validateAllRoutes","routes","allErrors","allWarnings","allSuggestions","conflictResult","detectAllConflicts","conflict","conflictSuggestions","generateFixSuggestions","generateValidationReport","lines","error","warning","suggestion","getAutoFixOperations","fileRenames","contentChanges","str","_","char","path","parts","splitPath","_ruleId","_options"],"mappings":"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"}