{"version":3,"file":"discovery-engine.mjs","sources":["../../../../src/lib/routing/discovery/discovery-engine.ts"],"sourcesContent":["/**\n * @file Route Discovery Engine\n * @description Main orchestrator for the route discovery system. Coordinates scanning,\n * path extraction, transformation, and validation into a unified discovery pipeline.\n *\n * @module @/lib/routing/discovery/discovery-engine\n *\n * This module provides:\n * - Unified discovery pipeline orchestration\n * - Configurable discovery strategies\n * - Event-driven discovery process\n * - Validation and conflict detection\n * - Code generation integration\n * - Caching and incremental updates\n *\n * @example\n * ```typescript\n * import { DiscoveryEngine, createDiscoveryEngine } from '@/lib/routing/discovery/discovery-engine';\n *\n * const engine = createDiscoveryEngine({\n *   rootDir: process.cwd(),\n *   scanPaths: ['src/routes', 'src/features'],\n * });\n *\n * const result = await engine.discover();\n * console.log(`Discovered ${result.routes.length} routes`);\n * ```\n */\n\nimport {\n  type AutoScanner,\n  createAutoScanner,\n  type AutoScannerConfig,\n  type ScanResult,\n} from './auto-scanner';\nimport {\n  type RouteTransformer,\n  createRouteTransformer,\n  type TransformerConfig,\n  type TransformedRoute,\n  type TransformResult,\n} from './route-transformer';\nimport {\n  validatePathPattern,\n  type PathExtractorConfig,\n} from './path-extractor';\nimport { splitPath } from '../core/path-utils';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Discovery engine configuration\n */\nexport interface DiscoveryEngineConfig {\n  /** Root directory for discovery */\n  readonly rootDir: string;\n  /** Scanner configuration */\n  readonly scanner?: Partial<AutoScannerConfig>;\n  /** Transformer configuration */\n  readonly transformer?: Partial<TransformerConfig>;\n  /** Path extractor configuration */\n  readonly extractor?: Partial<PathExtractorConfig>;\n  /** Enable validation during discovery */\n  readonly validate?: boolean;\n  /** Enable conflict detection */\n  readonly detectConflicts?: boolean;\n  /** Enable code generation */\n  readonly generateCode?: boolean;\n  /** Output directory for generated code */\n  readonly outputDir?: string;\n  /** Event handlers for discovery lifecycle */\n  readonly handlers?: DiscoveryHandlers;\n  /** Feature flag for discovery engine */\n  readonly featureFlag?: string;\n}\n\n/**\n * Discovery lifecycle event handlers\n */\nexport interface DiscoveryHandlers {\n  /** Called before scanning starts */\n  readonly onScanStart?: () => void | Promise<void>;\n  /** Called after scanning completes */\n  readonly onScanComplete?: (result: ScanResult) => void | Promise<void>;\n  /** Called before transformation starts */\n  readonly onTransformStart?: () => void | Promise<void>;\n  /** Called after transformation completes */\n  readonly onTransformComplete?: (result: TransformResult) => void | Promise<void>;\n  /** Called when a route is discovered */\n  readonly onRouteDiscovered?: (route: TransformedRoute) => void | Promise<void>;\n  /** Called when validation errors occur */\n  readonly onValidationError?: (errors: readonly ValidationError[]) => void | Promise<void>;\n  /** Called when conflicts are detected */\n  readonly onConflict?: (conflicts: readonly RouteConflict[]) => void | Promise<void>;\n  /** Called when discovery completes */\n  readonly onComplete?: (result: DiscoveryResult) => void | Promise<void>;\n  /** Called when an error occurs */\n  readonly onError?: (error: Error) => void | Promise<void>;\n}\n\n/**\n * Validation error in discovered routes\n */\nexport interface ValidationError {\n  /** Error type */\n  readonly type: 'invalid-path' | 'invalid-segment' | 'missing-export' | 'invalid-param';\n  /** Route that caused the error */\n  readonly routeId: string;\n  /** File path */\n  readonly filePath: string;\n  /** Error message */\n  readonly message: string;\n  /** Error details */\n  readonly details?: Record<string, unknown>;\n}\n\n/**\n * Route conflict between discovered routes\n */\nexport interface RouteConflict {\n  /** Conflict type */\n  readonly type: 'exact-duplicate' | 'param-conflict' | 'catch-all-shadow' | 'ambiguous';\n  /** Routes involved in conflict */\n  readonly routes: readonly TransformedRoute[];\n  /** Path pattern where conflict occurs */\n  readonly path: string;\n  /** Conflict severity */\n  readonly severity: 'error' | 'warning';\n  /** Conflict message */\n  readonly message: string;\n  /** Suggested resolution */\n  readonly suggestion?: string;\n}\n\n/**\n * Complete discovery result\n */\nexport interface DiscoveryResult {\n  /** Discovered and transformed routes */\n  readonly routes: readonly TransformedRoute[];\n  /** Route tree structure */\n  readonly tree: TransformResult['tree'];\n  /** Scan result */\n  readonly scan: ScanResult;\n  /** Transform result */\n  readonly transform: TransformResult;\n  /** Validation errors (if validation enabled) */\n  readonly validationErrors: readonly ValidationError[];\n  /** Route conflicts (if conflict detection enabled) */\n  readonly conflicts: readonly RouteConflict[];\n  /** Generated code (if code generation enabled) */\n  readonly generatedCode?: GeneratedCode;\n  /** Discovery statistics */\n  readonly stats: DiscoveryStats;\n  /** Discovery timestamp */\n  readonly timestamp: number;\n}\n\n/**\n * Generated code from discovery\n */\nexport interface GeneratedCode {\n  /** Route configuration code */\n  readonly routeConfig: string;\n  /** Type definitions */\n  readonly typeDefinitions: string;\n  /** Route manifest */\n  readonly manifest: string;\n}\n\n/**\n * Discovery statistics\n */\nexport interface DiscoveryStats {\n  /** Total discovery duration (ms) */\n  readonly totalDurationMs: number;\n  /** Scan duration (ms) */\n  readonly scanDurationMs: number;\n  /** Transform duration (ms) */\n  readonly transformDurationMs: number;\n  /** Validation duration (ms) */\n  readonly validationDurationMs: number;\n  /** Files scanned */\n  readonly filesScanned: number;\n  /** Routes discovered */\n  readonly routesDiscovered: number;\n  /** Validation errors count */\n  readonly validationErrorCount: number;\n  /** Conflicts count */\n  readonly conflictCount: number;\n}\n\n/**\n * Discovery engine state\n */\nexport type DiscoveryState =\n  | 'idle'\n  | 'scanning'\n  | 'transforming'\n  | 'validating'\n  | 'generating'\n  | 'complete'\n  | 'error';\n\n/**\n * Discovery event types\n */\nexport type DiscoveryEventType =\n  | 'state-change'\n  | 'route-discovered'\n  | 'validation-error'\n  | 'conflict-detected'\n  | 'complete'\n  | 'error';\n\n/**\n * Discovery event payload\n */\nexport interface DiscoveryEvent {\n  readonly type: DiscoveryEventType;\n  readonly timestamp: number;\n  readonly data: unknown;\n}\n\n/**\n * Discovery event listener\n */\nexport type DiscoveryEventListener = (event: DiscoveryEvent) => void;\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default discovery engine configuration\n */\nexport const DEFAULT_DISCOVERY_ENGINE_CONFIG: Partial<DiscoveryEngineConfig> = {\n  validate: true,\n  detectConflicts: true,\n  generateCode: false,\n};\n\n// =============================================================================\n// DiscoveryEngine Class\n// =============================================================================\n\n/**\n * Main orchestrator for route discovery\n *\n * @example\n * ```typescript\n * const engine = new DiscoveryEngine({\n *   rootDir: process.cwd(),\n *   scanPaths: ['src/routes'],\n * });\n *\n * // Add event listener\n * engine.on('route-discovered', (event) => {\n *   console.log('Discovered:', event.data);\n * });\n *\n * // Run discovery\n * const result = await engine.discover();\n * ```\n */\nexport class DiscoveryEngine {\n  private readonly config: DiscoveryEngineConfig;\n  private readonly scanner: AutoScanner;\n  private readonly transformer: RouteTransformer;\n  private state: DiscoveryState = 'idle';\n  private readonly listeners = new Map<DiscoveryEventType, Set<DiscoveryEventListener>>();\n  private lastResult: DiscoveryResult | null = null;\n\n  constructor(config: DiscoveryEngineConfig) {\n    this.config = {\n      ...DEFAULT_DISCOVERY_ENGINE_CONFIG,\n      ...config,\n    };\n\n    // Initialize scanner with merged config\n    this.scanner = createAutoScanner({\n      roots: config.scanner?.roots ?? ['src/routes', 'src/pages'],\n      ...config.scanner,\n    });\n\n    // Initialize transformer\n    this.transformer = createRouteTransformer({\n      basePath: config.rootDir,\n      ...config.transformer,\n    });\n  }\n\n  /**\n   * Get current discovery state\n   */\n  getState(): DiscoveryState {\n    return this.state;\n  }\n\n  /**\n   * Get last discovery result\n   */\n  getLastResult(): DiscoveryResult | null {\n    return this.lastResult;\n  }\n\n  /**\n   * Add event listener\n   */\n  on(type: DiscoveryEventType, listener: DiscoveryEventListener): () => void {\n    if (!this.listeners.has(type)) {\n      this.listeners.set(type, new Set());\n    }\n    const listenersSet = this.listeners.get(type);\n    if (listenersSet) {\n      listenersSet.add(listener);\n    }\n\n    // Return unsubscribe function\n    return () => {\n      this.listeners.get(type)?.delete(listener);\n    };\n  }\n\n  /**\n   * Remove event listener\n   */\n  off(type: DiscoveryEventType, listener: DiscoveryEventListener): void {\n    this.listeners.get(type)?.delete(listener);\n  }\n\n  /**\n   * Run the discovery process\n   *\n   * @param forceRefresh - Skip cache and perform fresh discovery\n   * @returns Discovery result\n   */\n  async discover(forceRefresh = false): Promise<DiscoveryResult> {\n    const startTime = Date.now();\n    const validationErrors: ValidationError[] = [];\n    const conflicts: RouteConflict[] = [];\n\n    try {\n      // Phase 1: Scanning\n      this.setState('scanning');\n      await this.config.handlers?.onScanStart?.();\n\n      const scanResult = await this.scanner.scan(forceRefresh);\n      await this.config.handlers?.onScanComplete?.(scanResult);\n\n      const scanDurationMs = Date.now() - startTime;\n\n      // Phase 2: Transformation\n      this.setState('transforming');\n      const transformStartTime = Date.now();\n      await this.config.handlers?.onTransformStart?.();\n\n      const transformResult = await this.transformer.transform(scanResult.files);\n      await this.config.handlers?.onTransformComplete?.(transformResult);\n\n      // Emit route discovered events\n      for (const route of transformResult.routes) {\n        this.emit('route-discovered', route);\n        await this.config.handlers?.onRouteDiscovered?.(route);\n      }\n\n      const transformDurationMs = Date.now() - transformStartTime;\n\n      // Phase 3: Validation\n      let validationDurationMs = 0;\n      if (this.config.validate === true) {\n        this.setState('validating');\n        const validationStartTime = Date.now();\n\n        const errors = this.validateRoutes(transformResult.routes);\n        validationErrors.push(...errors);\n\n        if (errors.length > 0) {\n          this.emit('validation-error', errors);\n          await this.config.handlers?.onValidationError?.(errors);\n        }\n\n        validationDurationMs = Date.now() - validationStartTime;\n      }\n\n      // Phase 4: Conflict Detection\n      if (this.config.detectConflicts === true) {\n        const detectedConflicts = this.detectConflicts(transformResult.routes);\n        conflicts.push(...detectedConflicts);\n\n        for (const conflict of detectedConflicts) {\n          this.emit('conflict-detected', conflict);\n          await this.config.handlers?.onConflict?.([conflict]);\n        }\n      }\n\n      // Phase 5: Code Generation\n      let generatedCode: GeneratedCode | undefined;\n      if (this.config.generateCode === true) {\n        this.setState('generating');\n        generatedCode = this.generateCode(transformResult.routes);\n      }\n\n      // Build result\n      const result: DiscoveryResult = {\n        routes: transformResult.routes,\n        tree: transformResult.tree,\n        scan: scanResult,\n        transform: transformResult,\n        validationErrors: Object.freeze(validationErrors),\n        conflicts: Object.freeze(conflicts),\n        generatedCode,\n        stats: {\n          totalDurationMs: Date.now() - startTime,\n          scanDurationMs,\n          transformDurationMs,\n          validationDurationMs,\n          filesScanned: scanResult.stats.totalFiles,\n          routesDiscovered: transformResult.routes.length,\n          validationErrorCount: validationErrors.length,\n          conflictCount: conflicts.length,\n        },\n        timestamp: Date.now(),\n      };\n\n      this.setState('complete');\n      this.lastResult = result;\n\n      this.emit('complete', result);\n      await this.config.handlers?.onComplete?.(result);\n\n      return result;\n    } catch (error) {\n      this.setState('error');\n      this.emit('error', error);\n      await this.config.handlers?.onError?.(error as Error);\n      throw error;\n    }\n  }\n\n  /**\n   * Clear scanner cache\n   */\n  clearCache(): void {\n    this.scanner.clearCache();\n    this.lastResult = null;\n  }\n\n  /**\n   * Get scanner instance for advanced usage\n   */\n  getScanner(): AutoScanner {\n    return this.scanner;\n  }\n\n  /**\n   * Get transformer instance for advanced usage\n   */\n  getTransformer(): RouteTransformer {\n    return this.transformer;\n  }\n\n  /**\n   * Emit an event\n   */\n  private emit(type: DiscoveryEventType, data: unknown): void {\n    const event: DiscoveryEvent = {\n      type,\n      timestamp: Date.now(),\n      data,\n    };\n\n    const listeners = this.listeners.get(type);\n    if (listeners) {\n      for (const listener of listeners) {\n        try {\n          listener(event);\n        } catch (error) {\n          console.error('Discovery event listener error:', error);\n        }\n      }\n    }\n  }\n\n  /**\n   * Update state and emit state change event\n   */\n  private setState(newState: DiscoveryState): void {\n    const oldState = this.state;\n    this.state = newState;\n    this.emit('state-change', { oldState, newState });\n  }\n\n  /**\n   * Validate discovered routes\n   */\n  private validateRoutes(routes: readonly TransformedRoute[]): ValidationError[] {\n    const errors: ValidationError[] = [];\n\n    for (const route of routes) {\n      // Validate path pattern\n      const pathValidation = validatePathPattern(route.path);\n      if (!pathValidation.isValid) {\n        for (const error of pathValidation.errors) {\n          errors.push({\n            type: 'invalid-path',\n            routeId: route.id,\n            filePath: route.filePath,\n            message: error,\n          });\n        }\n      }\n\n      // Validate segments\n      for (const segment of route.extracted.segments) {\n        if (segment.type === 'dynamic' && !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(segment.value)) {\n          errors.push({\n            type: 'invalid-param',\n            routeId: route.id,\n            filePath: route.filePath,\n            message: `Invalid parameter name: ${segment.value}`,\n            details: { segment: segment.raw },\n          });\n        }\n      }\n    }\n\n    return errors;\n  }\n\n  /**\n   * Detect conflicts between routes\n   */\n  private detectConflicts(routes: readonly TransformedRoute[]): RouteConflict[] {\n    const conflicts: RouteConflict[] = [];\n    const pathMap = new Map<string, TransformedRoute[]>();\n\n    // Group routes by path\n    for (const route of routes) {\n      if (route.type === 'layout') continue; // Layouts don't conflict\n\n      const existing = pathMap.get(route.path) ?? [];\n      existing.push(route);\n      pathMap.set(route.path, existing);\n    }\n\n    // Check for exact duplicates\n    for (const [path, routeGroup] of pathMap) {\n      if (routeGroup.length > 1) {\n        conflicts.push({\n          type: 'exact-duplicate',\n          routes: routeGroup,\n          path,\n          severity: 'error',\n          message: `Multiple routes with path \"${path}\"`,\n          suggestion: 'Remove duplicate route files or rename them',\n        });\n      }\n    }\n\n    // Check for parameter conflicts\n    const paramRoutes = routes.filter(r => r.extracted.params.length > 0);\n    for (let i = 0; i < paramRoutes.length; i++) {\n      for (let j = i + 1; j < paramRoutes.length; j++) {\n        const routeA = paramRoutes[i];\n        const routeB = paramRoutes[j];\n\n        if (routeA !== undefined && routeB !== undefined && this.doRoutesConflict(routeA, routeB)) {\n          conflicts.push({\n            type: 'param-conflict',\n            routes: [routeA, routeB],\n            path: routeA.path,\n            severity: 'warning',\n            message: `Potential conflict between \"${routeA.path}\" and \"${routeB.path}\"`,\n            suggestion: 'Ensure routes have distinct static prefixes',\n          });\n        }\n      }\n    }\n\n    // Check for catch-all shadowing\n    const catchAllRoutes = routes.filter(r => r.extracted.hasCatchAll);\n    for (const catchAll of catchAllRoutes) {\n      const shadowed = routes.filter(r =>\n        r.id !== catchAll.id &&\n        r.path.startsWith(catchAll.path.replace('*', ''))\n      );\n\n      if (shadowed.length > 0) {\n        conflicts.push({\n          type: 'catch-all-shadow',\n          routes: [catchAll, ...shadowed],\n          path: catchAll.path,\n          severity: 'warning',\n          message: `Catch-all route \"${catchAll.path}\" may shadow ${shadowed.length} other routes`,\n          suggestion: 'Ensure catch-all route is processed last',\n        });\n      }\n    }\n\n    return conflicts;\n  }\n\n  /**\n   * Check if two routes conflict\n   *\n   * Uses core splitPath utility for path segmentation.\n   */\n  private doRoutesConflict(a: TransformedRoute, b: TransformedRoute): boolean {\n    const segmentsA = splitPath(a.path);\n    const segmentsB = splitPath(b.path);\n\n    // Different lengths = no conflict\n    if (segmentsA.length !== segmentsB.length) return false;\n\n    // Check each segment\n    for (let i = 0; i < segmentsA.length; i++) {\n      const segA = segmentsA[i] ?? '';\n      const segB = segmentsB[i] ?? '';\n\n      const isDynamicA = segA.startsWith(':');\n      const isDynamicB = segB.startsWith(':');\n\n      // Both static and different = no conflict\n      if (!isDynamicA && !isDynamicB && segA !== segB) return false;\n    }\n\n    // All segments either match or are dynamic = potential conflict\n    return true;\n  }\n\n  /**\n   * Generate code from discovered routes\n   */\n  private generateCode(routes: readonly TransformedRoute[]): GeneratedCode {\n    // Route configuration\n    const imports: string[] = [\n      \"import { lazy } from 'react';\",\n      \"import type { RouteObject } from 'react-router-dom';\",\n    ];\n\n    const lazyImports = routes\n      .filter(r => r.lazy)\n      .map(r => `const ${r.componentName} = lazy(() => import('${r.importPath}'));`);\n\n    const routeObjects = routes\n      .filter(r => r.type === 'page' || r.type === 'route')\n      .map(r => `  {\n    id: '${r.id}',\n    path: '${r.path}',\n    element: <${r.componentName} />,\n    ${r.index ? 'index: true,' : ''}\n  }`);\n\n    const routeConfig = `${imports.join('\\n')}\n\n${lazyImports.join('\\n')}\n\nexport const routes: RouteObject[] = [\n${routeObjects.join(',\\n')}\n];`;\n\n    // Type definitions\n    const routeIds = routes.map(r => `  | '${r.id}'`).join('\\n');\n    const routePaths = routes.map(r => `  | '${r.path}'`).join('\\n');\n\n    const paramTypes = routes\n      .filter(r => r.extracted.params.length > 0)\n      .map(r => {\n        const params = r.extracted.params\n          .map(p => `    ${p}${r.extracted.optionalParams.includes(p) ? '?' : ''}: string;`)\n          .join('\\n');\n        return `  '${r.path}': {\\n${params}\\n  };`;\n      })\n      .join('\\n');\n\n    const typeDefinitions = `// Auto-generated route types\n// DO NOT EDIT - This file is generated by the route discovery engine\n\nexport type RouteId =\n${routeIds || '  never'};\n\nexport type RoutePath =\n${routePaths || '  never'};\n\nexport interface RouteParams {\n${paramTypes || '  // No parametric routes'}\n}\n\nexport type RouteParamsFor<T extends RoutePath> = T extends keyof RouteParams\n  ? RouteParams[T]\n  : Record<string, never>;\n`;\n\n    // Route manifest\n    const manifestEntries = routes.map(r => ({\n      id: r.id,\n      path: r.path,\n      type: r.type,\n      index: r.index,\n      params: r.extracted.params,\n      groups: r.meta.groups,\n    }));\n\n    const manifest = JSON.stringify(\n      {\n        version: '1.0.0',\n        generatedAt: new Date().toISOString(),\n        routes: manifestEntries,\n      },\n      null,\n      2\n    );\n\n    return {\n      routeConfig,\n      typeDefinitions,\n      manifest,\n    };\n  }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a new DiscoveryEngine instance\n *\n * @param config - Engine configuration\n * @returns Configured DiscoveryEngine\n */\nexport function createDiscoveryEngine(config: DiscoveryEngineConfig): DiscoveryEngine {\n  return new DiscoveryEngine(config);\n}\n\n/**\n * Run a one-shot discovery (convenience function)\n *\n * @param rootDir - Root directory to scan\n * @param options - Discovery options\n * @returns Discovery result\n */\nexport async function discoverRoutes(\n  rootDir: string,\n  options: Partial<Omit<DiscoveryEngineConfig, 'rootDir'>> = {}\n): Promise<DiscoveryResult> {\n  const engine = new DiscoveryEngine({\n    rootDir,\n    ...options,\n  });\n  return engine.discover();\n}\n\n// =============================================================================\n// Singleton Instance\n// =============================================================================\n\nlet defaultEngine: DiscoveryEngine | null = null;\n\n/**\n * Get or create the default discovery engine\n *\n * @param config - Configuration for default engine (only used on first call)\n * @returns Default discovery engine instance\n */\nexport function getDiscoveryEngine(\n  config?: DiscoveryEngineConfig\n): DiscoveryEngine {\n  if (!defaultEngine && config) {\n    defaultEngine = new DiscoveryEngine(config);\n  }\n  if (!defaultEngine) {\n    throw new Error('Discovery engine not initialized. Call with config first.');\n  }\n  return defaultEngine;\n}\n\n/**\n * Initialize the default discovery engine\n *\n * @param config - Engine configuration\n */\nexport function initDiscoveryEngine(config: DiscoveryEngineConfig): void {\n  defaultEngine = new DiscoveryEngine(config);\n}\n\n/**\n * Reset the default discovery engine\n */\nexport function resetDiscoveryEngine(): void {\n  defaultEngine = null;\n}\n"],"names":["DEFAULT_DISCOVERY_ENGINE_CONFIG","DiscoveryEngine","config","createAutoScanner","createRouteTransformer","type","listener","listenersSet","forceRefresh","startTime","validationErrors","conflicts","scanResult","scanDurationMs","transformStartTime","transformResult","route","transformDurationMs","validationDurationMs","validationStartTime","errors","detectedConflicts","conflict","generatedCode","result","error","data","event","listeners","newState","oldState","routes","pathValidation","validatePathPattern","segment","pathMap","existing","path","routeGroup","paramRoutes","r","i","j","routeA","routeB","catchAllRoutes","catchAll","shadowed","a","b","segmentsA","splitPath","segmentsB","segA","segB","isDynamicA","isDynamicB","imports","lazyImports","routeObjects","routeConfig","routeIds","routePaths","paramTypes","params","p","typeDefinitions","manifestEntries","manifest","createDiscoveryEngine","defaultEngine","getDiscoveryEngine","initDiscoveryEngine","resetDiscoveryEngine"],"mappings":"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"}