# All files / src mapper.ts

85% Statements 17/20
50% Branches 3/6
40% Functions 2/5
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125

    6x
    6x
    6x
    6x
    6x
    6x

    6x
    6x

    6x

    6x

    6x

    6x

    6x

    6x

    6x

    6x

    6x

     import type {
      ContextAnalysisResult,
      DependencyGraph,
      DependencyNode,
      ModuleCluster,
    } from './types';
    import { calculateEnhancedCohesion } from './metrics';
    import { analyzeIssues } from './issue-analyzer';
    import {
      calculateImportDepth,
      getTransitiveDependencies,
      calculateContextBudget,
    } from './graph-builder';
    import {
      classifyFile,
      adjustCohesionForClassification,
      adjustFragmentationForClassification,
    } from './classifier';
    import { getClassificationRecommendations } from './remediation';

    export interface MappingOptions {
      maxDepth: number;
      maxContextBudget: number;
      minCohesion: number;
      maxFragmentation: number;
    }

    /**
     * Maps a single dependency node to a comprehensive ContextAnalysisResult.
     *
     * @param node - The dependency node to map
     * @param graph - The full dependency graph
     * @param clusters - All identified module clusters
     * @param allCircularDeps - All identified circular dependencies
     * @param options - Mapping options for detailed analysis
     */
    export function mapNodeToResult(
      node: DependencyNode,
      graph: DependencyGraph,
      clusters: ModuleCluster[],
      allCircularDeps: string[][],
      options: MappingOptions
    ): ContextAnalysisResult {
      const file = node.file;
      const tokenCost = node.tokenCost;
      const importDepth = calculateImportDepth(file, graph);
      const transitiveDeps = getTransitiveDependencies(file, graph);
      const contextBudget = calculateContextBudget(file, graph);
      const circularDeps = allCircularDeps.filter((cycle) => cycle.includes(file));

      // Find cluster for this file
      const cluster = clusters.find((c) => c.files.includes(file));
      const rawFragmentationScore = cluster ? cluster.fragmentationScore : 0;

      // Cohesion
      const rawCohesionScore = calculateEnhancedCohesion(
        node.exports,
        file,
        options as any
      );

      // Initial classification
      const fileClassification = classifyFile(node, rawCohesionScore);

      // Adjust scores based on classification
      const cohesionScore = adjustCohesionForClassification(
        rawCohesionScore,
        fileClassification
      );
      const fragmentationScore = adjustFragmentationForClassification(
        rawFragmentationScore,
        fileClassification
      );

      const { severity, issues, recommendations, potentialSavings } = analyzeIssues(
        {
          file,
          importDepth,
          contextBudget,
          cohesionScore,
          fragmentationScore,
          maxDepth: options.maxDepth,
          maxContextBudget: options.maxContextBudget,
          minCohesion: options.minCohesion,
          maxFragmentation: options.maxFragmentation,
          circularDeps,
        }
      );

      // Add classification-specific recommendations
      const classRecs = getClassificationRecommendations(
        fileClassification,
        file,
        issues
      );
      const allRecommendations = Array.from(
        new Set([...recommendations, ...classRecs])
      );

      return {
        file,
        tokenCost,
        linesOfCode: node.linesOfCode,
        importDepth,
        dependencyCount: transitiveDeps.length,
        dependencyList: transitiveDeps,
        circularDeps,
        cohesionScore,
        domains: Array.from(
          new Set(
            node.exports.flatMap((e) => e.domains?.map((d) => d.domain) || [])
          )
        ),
        exportCount: node.exports.length,
        contextBudget,
        fragmentationScore,
        relatedFiles: cluster ? cluster.files : [],
        fileClassification,
        severity,
        issues,
        recommendations: allRecommendations,
        potentialSavings,
      };
    }