{"version":3,"file":"route-transformer.mjs","sources":["../../../../src/lib/routing/discovery/route-transformer.ts"],"sourcesContent":["/**\n * @file Route Transformer\n * @description Transforms discovered file paths into route configuration objects.\n * Handles conversion from file-system conventions to React Router compatible route definitions.\n *\n * @module @/lib/routing/discovery/route-transformer\n *\n * This module provides:\n * - File path to route config transformation\n * - Route tree building from flat file list\n * - Layout hierarchy resolution\n * - Lazy loading wrapper generation\n * - Route metadata enrichment\n *\n * @example\n * ```typescript\n * import { RouteTransformer, transformRoutes } from '@/lib/routing/discovery/route-transformer';\n *\n * const transformer = new RouteTransformer({\n *   basePath: 'src/routes',\n *   lazy: true,\n * });\n *\n * const routes = await transformer.transform(discoveredFiles);\n * ```\n */\n\nimport type { DiscoveredFile, RouteFileType } from './auto-scanner';\nimport { type ExtractedPath, extractPathFromFile } from './path-extractor';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Transformed route configuration\n */\nexport interface TransformedRoute {\n  /** Unique route identifier */\n  readonly id: string;\n  /** URL path pattern */\n  readonly path: string;\n  /** Original file path */\n  readonly filePath: string;\n  /** Whether route is lazy loaded */\n  readonly lazy: boolean;\n  /** Route import path for lazy loading */\n  readonly importPath: string;\n  /** Route component name */\n  readonly componentName: string;\n  /** Child routes */\n  readonly children: readonly TransformedRoute[];\n  /** Parent layout route ID (if any) */\n  readonly layoutId: string | null;\n  /** Route metadata */\n  readonly meta: TransformedRouteMeta;\n  /** Route type */\n  readonly type: RouteFileType;\n  /** Whether this is an index route */\n  readonly index: boolean;\n  /** Extracted path information */\n  readonly extracted: ExtractedPath;\n}\n\n/**\n * Route metadata attached to transformed routes\n */\nexport interface TransformedRouteMeta {\n  /** Page title template */\n  readonly title?: string;\n  /** SEO description */\n  readonly description?: string;\n  /** Whether route requires authentication */\n  readonly requiresAuth?: boolean;\n  /** Required roles */\n  readonly roles?: readonly string[];\n  /** Required permissions */\n  readonly permissions?: readonly string[];\n  /** Feature flag dependency */\n  readonly featureFlag?: string;\n  /** Route groups */\n  readonly groups: readonly string[];\n  /** Parallel slots */\n  readonly parallelSlots: readonly string[];\n  /** Custom metadata from file exports */\n  readonly custom?: Record<string, unknown>;\n}\n\n/**\n * Route transformer configuration\n */\nexport interface TransformerConfig {\n  /** Base path for route files */\n  readonly basePath: string;\n  /** Enable lazy loading for routes */\n  readonly lazy: boolean;\n  /** Custom import path resolver */\n  readonly resolveImportPath?: (filePath: string) => string;\n  /** Custom route ID generator */\n  readonly generateId?: (filePath: string, extracted: ExtractedPath) => string;\n  /** Custom component name generator */\n  readonly generateComponentName?: (filePath: string) => string;\n  /** Metadata extractor from file content */\n  readonly extractMeta?: (filePath: string) => Promise<Partial<TransformedRouteMeta>>;\n  /** Whether to include error boundaries */\n  readonly includeErrorBoundaries?: boolean;\n  /** Whether to include loading states */\n  readonly includeLoadingStates?: boolean;\n  /** Feature flag for transformer */\n  readonly featureFlag?: string;\n}\n\n/**\n * Route tree node for hierarchical representation\n */\nexport interface RouteTreeNode {\n  /** Route at this node */\n  readonly route: TransformedRoute;\n  /** Child nodes */\n  readonly children: readonly RouteTreeNode[];\n  /** Layout node (if this is wrapped by a layout) */\n  readonly layout: RouteTreeNode | null;\n  /** Parallel route slots */\n  readonly slots: ReadonlyMap<string, RouteTreeNode>;\n}\n\n/**\n * Transformation result with statistics\n */\nexport interface TransformResult {\n  /** Transformed routes as flat list */\n  readonly routes: readonly TransformedRoute[];\n  /** Routes organized as tree */\n  readonly tree: readonly RouteTreeNode[];\n  /** Transformation statistics */\n  readonly stats: TransformStats;\n  /** Any warnings during transformation */\n  readonly warnings: readonly TransformWarning[];\n}\n\n/**\n * Transformation statistics\n */\nexport interface TransformStats {\n  /** Total routes transformed */\n  readonly totalRoutes: number;\n  /** Number of lazy routes */\n  readonly lazyRoutes: number;\n  /** Number of layout routes */\n  readonly layoutRoutes: number;\n  /** Number of index routes */\n  readonly indexRoutes: number;\n  /** Maximum nesting depth */\n  readonly maxDepth: number;\n  /** Routes with parameters */\n  readonly parametricRoutes: number;\n  /** Transformation duration (ms) */\n  readonly durationMs: number;\n}\n\n/**\n * Warning generated during transformation\n */\nexport interface TransformWarning {\n  /** Warning type */\n  readonly type: 'missing-layout' | 'orphan-route' | 'duplicate-path' | 'deep-nesting' | 'naming';\n  /** File path that caused warning */\n  readonly filePath: string;\n  /** Warning message */\n  readonly message: string;\n  /** Suggested fix */\n  readonly suggestion?: string;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default transformer configuration\n */\nexport const DEFAULT_TRANSFORMER_CONFIG: TransformerConfig = {\n  basePath: 'src/routes',\n  lazy: true,\n  includeErrorBoundaries: true,\n  includeLoadingStates: true,\n};\n\n/**\n * Maximum recommended nesting depth\n */\nconst MAX_RECOMMENDED_DEPTH = 5;\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Generate a route ID from file path\n *\n * @param _filePath - File path (unused, kept for signature compatibility)\n * @param extracted - Extracted path information\n * @returns Unique route ID\n */\nfunction defaultGenerateId(_filePath: string, extracted: ExtractedPath): string {\n  // Create ID from URL path\n  const { urlPath } = extracted;\n  if (urlPath === '/') return 'INDEX';\n\n  return urlPath\n    .replace(/^\\//, '')\n    .replace(/\\//g, '_')\n    .replace(/:/g, 'BY_')\n    .replace(/\\?/g, '_OPT')\n    .replace(/\\*/g, 'CATCH_ALL')\n    .toUpperCase();\n}\n\n/**\n * Generate a component name from file path\n *\n * @param filePath - File path\n * @returns PascalCase component name\n */\nfunction defaultGenerateComponentName(filePath: string): string {\n  const parts = filePath.replace(/\\\\/g, '/').split('/').filter(Boolean);\n\n  // Get the last meaningful segment\n  let name = parts.pop() ?? 'Route';\n\n  // Remove extension\n  name = name.replace(/\\.(tsx?|jsx?)$/, '');\n\n  // Skip common names\n  const commonNames = ['page', 'index', 'layout', '_layout', '_index'];\n  if (name !== null && name !== undefined && name !== '' && commonNames.includes(name)) {\n    name = parts.pop() ?? 'Route';\n  }\n\n  // Convert to PascalCase\n  return `${name\n    .replace(/[[\\]()@.]/g, '')\n    .replace(/[-_](\\w)/g, (_: string, c: string) => c.toUpperCase())\n    .replace(/^(\\w)/, (_: string, c: string) => c.toUpperCase())}Route`;\n}\n\n/**\n * Default import path resolver\n *\n * @param filePath - File path\n * @param basePath - Base path for routes\n * @returns Import path string\n */\nfunction defaultResolveImportPath(filePath: string, basePath: string): string {\n  // Normalize paths\n  const normalized = filePath.replace(/\\\\/g, '/');\n  const base = basePath.replace(/\\\\/g, '/');\n\n  // Make relative to base\n  if (normalized.startsWith(base)) {\n    const relative = normalized.slice(base.length).replace(/^\\//, '');\n    return `@/routes/${relative.replace(/\\.(tsx?|jsx?)$/, '')}`;\n  }\n\n  // Fall back to absolute-ish import\n  return `@/${normalized.replace(/\\.(tsx?|jsx?)$/, '')}`;\n}\n\n/**\n * Sort routes by specificity for proper matching\n *\n * @param routes - Routes to sort\n * @returns Sorted routes (most specific first)\n */\nfunction sortRoutesBySpecificity(routes: TransformedRoute[]): TransformedRoute[] {\n  return [...routes].sort((a, b) => {\n    // Index routes last within same parent\n    if (a.index && !b.index) return 1;\n    if (!a.index && b.index) return -1;\n\n    // Catch-all routes last\n    if (a.extracted.hasCatchAll && !b.extracted.hasCatchAll) return 1;\n    if (!a.extracted.hasCatchAll && b.extracted.hasCatchAll) return -1;\n\n    // More static segments = more specific\n    const staticA = a.extracted.segments.filter((s) => s.type === 'static').length;\n    const staticB = b.extracted.segments.filter((s) => s.type === 'static').length;\n    if (staticA !== staticB) return staticB - staticA;\n\n    // Fewer dynamic segments = more specific\n    const dynamicA = a.extracted.params.length;\n    const dynamicB = b.extracted.params.length;\n    if (dynamicA !== dynamicB) return dynamicA - dynamicB;\n\n    // Alphabetical as tiebreaker\n    return a.path.localeCompare(b.path);\n  });\n}\n\n// =============================================================================\n// RouteTransformer Class\n// =============================================================================\n\n/**\n * Transforms discovered files into route configurations\n *\n * @example\n * ```typescript\n * const transformer = new RouteTransformer({\n *   basePath: 'src/routes',\n *   lazy: true,\n * });\n *\n * const result = await transformer.transform(files);\n * console.log(`Transformed ${result.stats.totalRoutes} routes`);\n * ```\n */\nexport class RouteTransformer {\n  private readonly config: TransformerConfig;\n\n  constructor(config: Partial<TransformerConfig> = {}) {\n    this.config = {\n      ...DEFAULT_TRANSFORMER_CONFIG,\n      ...config,\n    };\n  }\n\n  /**\n   * Transform discovered files into route configurations\n   *\n   * @param files - Discovered files from scanner\n   * @returns Transformation result\n   */\n  async transform(files: readonly DiscoveredFile[]): Promise<TransformResult> {\n    const startTime = Date.now();\n    const warnings: TransformWarning[] = [];\n    const routes: TransformedRoute[] = [];\n    const layoutMap = new Map<string, TransformedRoute>();\n\n    // First pass: transform all files\n    for (const file of files) {\n      const route = await this.transformFile(file);\n      routes.push(route);\n\n      // Track layouts\n      if (file.fileType === 'layout') {\n        const layoutPath = file.directory || '/';\n        layoutMap.set(layoutPath, route);\n      }\n    }\n\n    // Second pass: assign layouts and check for warnings\n    for (const route of routes) {\n      if (route.type !== 'layout') {\n        // Find parent layout\n        const parentLayout = this.findParentLayout(route, layoutMap);\n        if (parentLayout) {\n          // Use Object.assign since we need to modify the readonly property\n          (route as { layoutId: string | null }).layoutId = parentLayout.id;\n        }\n      }\n\n      // Check for warnings\n      if (route.extracted.depth > MAX_RECOMMENDED_DEPTH) {\n        warnings.push({\n          type: 'deep-nesting',\n          filePath: route.filePath,\n          message: `Route has ${route.extracted.depth} levels of nesting (max recommended: ${MAX_RECOMMENDED_DEPTH})`,\n          suggestion: 'Consider flattening the route structure or using route groups',\n        });\n      }\n    }\n\n    // Check for duplicate paths\n    const pathMap = new Map<string, TransformedRoute[]>();\n    for (const route of routes) {\n      if (route.type === 'page' || route.type === 'route') {\n        const existing = pathMap.get(route.path) ?? [];\n        existing.push(route);\n        pathMap.set(route.path, existing);\n      }\n    }\n\n    for (const [path, duplicates] of pathMap) {\n      if (duplicates.length > 1) {\n        for (const route of duplicates) {\n          warnings.push({\n            type: 'duplicate-path',\n            filePath: route.filePath,\n            message: `Multiple routes match path \"${path}\"`,\n            suggestion: 'Ensure each path has a unique route file',\n          });\n        }\n      }\n    }\n\n    // Build tree structure\n    const tree = this.buildRouteTree(routes);\n\n    // Calculate stats\n    const stats: TransformStats = {\n      totalRoutes: routes.length,\n      lazyRoutes: routes.filter((r) => r.lazy).length,\n      layoutRoutes: routes.filter((r) => r.type === 'layout').length,\n      indexRoutes: routes.filter((r) => r.index).length,\n      maxDepth: Math.max(0, ...routes.map((r) => r.extracted.depth)),\n      parametricRoutes: routes.filter((r) => r.extracted.params.length > 0).length,\n      durationMs: Date.now() - startTime,\n    };\n\n    // Sort routes for proper matching order\n    const sortedRoutes = sortRoutesBySpecificity(routes);\n\n    return {\n      routes: Object.freeze(sortedRoutes),\n      tree: Object.freeze(tree),\n      stats,\n      warnings: Object.freeze(warnings),\n    };\n  }\n\n  /**\n   * Transform a single file into a route\n   */\n  private async transformFile(file: DiscoveredFile): Promise<TransformedRoute> {\n    const extracted = extractPathFromFile(file.relativePath);\n\n    // Generate ID\n    const id = this.config.generateId\n      ? this.config.generateId(file.absolutePath, extracted)\n      : defaultGenerateId(file.absolutePath, extracted);\n\n    // Generate component name\n    const componentName = this.config.generateComponentName\n      ? this.config.generateComponentName(file.absolutePath)\n      : defaultGenerateComponentName(file.relativePath);\n\n    // Resolve import path\n    const importPath = this.config.resolveImportPath\n      ? this.config.resolveImportPath(file.absolutePath)\n      : defaultResolveImportPath(file.relativePath, this.config.basePath);\n\n    // Extract metadata\n    let customMeta: Partial<TransformedRouteMeta> = {};\n    if (this.config.extractMeta) {\n      try {\n        customMeta = await this.config.extractMeta(file.absolutePath);\n      } catch {\n        // Ignore metadata extraction errors\n      }\n    }\n\n    const meta: TransformedRouteMeta = {\n      ...customMeta,\n      groups: extracted.groups,\n      parallelSlots: extracted.parallelSlots,\n    };\n\n    return {\n      id,\n      path: extracted.urlPath,\n      filePath: file.absolutePath,\n      lazy: this.config.lazy,\n      importPath,\n      componentName,\n      children: [],\n      layoutId: null,\n      meta,\n      type: file.fileType,\n      index: extracted.isIndex,\n      extracted,\n    };\n  }\n\n  /**\n   * Find the parent layout for a route\n   */\n  private findParentLayout(\n    route: TransformedRoute,\n    layoutMap: Map<string, TransformedRoute>\n  ): TransformedRoute | null {\n    // Get directory of route file\n\n\n    // Walk up directory tree looking for layout\n    let searchDir = route.filePath.replace(/\\\\/g, '/').replace(/\\/[^/]+$/, '');\n    while (searchDir) {\n      const layout = layoutMap.get(searchDir);\n      if (layout && layout.id !== route.id) {\n        return layout;\n      }\n\n      // Move up one directory\n      const parent = searchDir.replace(/\\/[^/]+$/, '');\n      if (parent === searchDir) break;\n      searchDir = parent;\n    }\n\n    // Check root layout\n    return layoutMap.get('/') ?? layoutMap.get('') ?? null;\n  }\n\n  /**\n   * Build hierarchical route tree\n   */\n  private buildRouteTree(routes: readonly TransformedRoute[]): readonly RouteTreeNode[] {\n    const layoutRoutes = routes.filter((r) => r.type === 'layout');\n    const pageRoutes = routes.filter((r) => r.type !== 'layout');\n    const nodeMap = new Map<string, RouteTreeNode & { children: RouteTreeNode[] }>();\n\n    // Create nodes for all layouts\n    for (const layout of layoutRoutes) {\n      nodeMap.set(layout.id, {\n        route: layout,\n        children: [],\n        layout: null,\n        slots: new Map(),\n      });\n    }\n\n    // Create nodes for pages and attach to layouts\n    const rootNodes: RouteTreeNode[] = [];\n\n    for (const page of pageRoutes) {\n      const node: RouteTreeNode & { children: RouteTreeNode[] } = {\n        route: page,\n        children: [],\n        layout:\n          page.layoutId != null && page.layoutId !== ''\n            ? (nodeMap.get(page.layoutId) ?? null)\n            : null,\n        slots: new Map(),\n      };\n\n      if (page.layoutId != null && page.layoutId !== '') {\n        const layoutNode = nodeMap.get(page.layoutId);\n        if (layoutNode) {\n          layoutNode.children.push(node);\n        } else {\n          rootNodes.push(node);\n        }\n      } else {\n        rootNodes.push(node);\n      }\n    }\n\n    // Add layout nodes without parents to root\n    for (const layoutNode of nodeMap.values()) {\n      if (layoutNode.route.layoutId == null || layoutNode.route.layoutId === '') {\n        rootNodes.push(layoutNode);\n      }\n    }\n\n    return rootNodes;\n  }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a new RouteTransformer instance\n *\n * @param config - Transformer configuration\n * @returns Configured RouteTransformer\n */\nexport function createRouteTransformer(config: Partial<TransformerConfig> = {}): RouteTransformer {\n  return new RouteTransformer(config);\n}\n\n/**\n * Transform discovered files into route configurations (convenience function)\n *\n * @param files - Discovered files\n * @param config - Transformer configuration\n * @returns Transformation result\n */\nexport async function transformRoutes(\n  files: readonly DiscoveredFile[],\n  config: Partial<TransformerConfig> = {}\n): Promise<TransformResult> {\n  const transformer = new RouteTransformer(config);\n  return transformer.transform(files);\n}\n\n// =============================================================================\n// Code Generation Functions\n// =============================================================================\n\n/**\n * Generate route configuration code\n *\n * @param routes - Transformed routes\n * @returns Generated TypeScript code\n */\nexport function generateRouteConfig(routes: readonly TransformedRoute[]): string {\n  const imports: string[] = [];\n  const routeConfigs: string[] = [];\n\n  for (const route of routes) {\n    if (route.lazy) {\n      imports.push(`const ${route.componentName} = lazy(() => import('${route.importPath}'));`);\n    } else {\n      imports.push(`import { default as ${route.componentName} } from '${route.importPath}';`);\n    }\n\n    routeConfigs.push(`  {\n    id: '${route.id}',\n    path: '${route.path}',\n    element: <${route.componentName} />,\n    ${route.index ? 'index: true,' : ''}\n    ${route.children.length > 0 ? `children: [/* nested routes */],` : ''}\n  }`);\n  }\n\n  return `// Auto-generated route configuration\nimport { lazy } from 'react';\n\n${imports.join('\\n')}\n\nexport const routes = [\n${routeConfigs.join(',\\n')}\n];\n`;\n}\n\n/**\n * Generate route type definitions\n *\n * @param routes - Transformed routes\n * @returns Generated TypeScript type definitions\n */\nexport function generateRouteTypes(routes: readonly TransformedRoute[]): string {\n  const routeIds = routes.map((r) => `'${r.id}'`).join(' | ');\n  const routePaths = routes.map((r) => `'${r.path}'`).join(' | ');\n\n  const paramTypes: string[] = [];\n  for (const route of routes) {\n    if (route.extracted.params.length > 0) {\n      const params = route.extracted.params\n        .map((p) => {\n          const isOptional = route.extracted.optionalParams.includes(p);\n          return `${p}${isOptional ? '?' : ''}: string`;\n        })\n        .join('; ');\n      paramTypes.push(`  '${route.path}': { ${params} };`);\n    }\n  }\n\n  return `// Auto-generated route types\n\nexport type RouteId = ${routeIds || 'never'};\n\nexport type RoutePath = ${routePaths || 'never'};\n\nexport interface RouteParams {\n${paramTypes.join('\\n') || '  // 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"],"names":["DEFAULT_TRANSFORMER_CONFIG","MAX_RECOMMENDED_DEPTH","defaultGenerateId","_filePath","extracted","urlPath","defaultGenerateComponentName","filePath","parts","name","commonNames","_","c","defaultResolveImportPath","basePath","normalized","base","sortRoutesBySpecificity","routes","a","b","staticA","s","staticB","dynamicA","dynamicB","RouteTransformer","config","files","startTime","warnings","layoutMap","file","route","layoutPath","parentLayout","pathMap","existing","path","duplicates","tree","stats","sortedRoutes","extractPathFromFile","id","componentName","importPath","customMeta","meta","searchDir","layout","parent","layoutRoutes","r","pageRoutes","nodeMap","rootNodes","page","node","layoutNode","createRouteTransformer","transformRoutes"],"mappings":"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"}