UNPKG

sicua

Version:

A tool for analyzing project structure and dependencies

242 lines (241 loc) 9.48 kB
"use strict"; /** * Scoring criteria and weights for component analysis * Defines how different metrics contribute to the overall problematic score * Focus on "easily overlooked" issues that developers miss */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SCORE_RANGES = exports.FILE_TYPE_EXCLUSIONS = exports.DEFAULT_SCORING_MULTIPLIERS = exports.DEFAULT_SCORING_THRESHOLDS = exports.DEFAULT_SCORING_WEIGHTS = void 0; exports.getFileType = getFileType; /** * Rebalanced scoring weights focusing on architectural and maintainability issues * that actually make components problematic in real Next.js/React projects */ exports.DEFAULT_SCORING_WEIGHTS = { // High impact factors - Architectural complexity (50% total weight) cyclomaticComplexity: 0.12, // Reduced to make room for new metrics cognitiveComplexity: 0.1, // Reduced to make room for new metrics couplingDegree: 0.12, // Keep high - coupling is critical maintainabilityIndex: 0.1, // Keep high - direct maintainability measure reactComplexity: 0.08, // NEW - React-specific complexity patterns containerComplexity: 0.08, // NEW - Container component complexity // Medium impact factors - Code quality issues (35% total weight) errorHandlingGaps: 0.12, // Keep high - critical for reliability typeIssues: 0.08, // Reduced but still important componentFlowComplexity: 0.08, // Keep same - complex rendering logic zombieCode: 0.04, // Keep same - waste but not critical circularDependencies: 0.03, // Keep same - rare but critical // Lower impact factors - Surface-level issues (15% total weight) translationIssues: 0.04, // Keep same seoProblems: 0.03, // Significantly reduced accessibilityIssues: 0.03, // Reduced but still important performanceIssues: 0.02, // Keep same deduplicationOpportunities: 0.02, // Keep same codeMetrics: 0.01, // Reduced - surface-level magicNumbers: 0.01, // Reduced - usually obvious }; /** * Updated thresholds focusing on architectural complexity */ exports.DEFAULT_SCORING_THRESHOLDS = { // Complexity thresholds (more sensitive) highCyclomaticComplexity: 8, // Lowered - be more sensitive highCognitiveComplexity: 12, // Lowered - cognitive load matters lowMaintainabilityIndex: 50, // Increased - higher bar for maintainability // Coupling thresholds (more sensitive) highCouplingDegree: 0.85, // Adjusted for new coupling formula // Code quality thresholds lowCodeToCommentRatio: 0.1, highMagicNumberCount: 15, // Increased - be less sensitive // Type analysis thresholds (more sensitive) highAnyUsage: 1, // Lowered - any usage of 'any' is problematic highComplexTypeCount: 2, // Lowered - complex types indicate over-engineering // Component flow thresholds (more sensitive) highConditionalRenderCount: 4, // Lowered - conditional rendering complexity deepComponentNesting: 3, // Lowered - deep nesting is hard to follow // SEO thresholds (less sensitive) criticalSeoIssues: 3, // Increased - don't flag minor SEO issues missingSeoMeta: 2, // Increased - some pages don't need all meta poorImageOptimization: 5, // Increased // Accessibility thresholds (less sensitive) missingAltTexts: 3, // Increased missingAriaLabels: 4, // Increased poorSemanticStructure: 3, // Increased // Performance thresholds largeBundleSize: 500, missingLazyLoading: 3, blockingResources: 4, // Translation thresholds (less sensitive) highMissingTranslations: 15, // Increased // Deduplication thresholds highSimilarityScore: 0.8, }; /** * Updated scoring multipliers with focus on architectural issues */ exports.DEFAULT_SCORING_MULTIPLIERS = { // Critical architectural penalties inCircularDependency: 2.0, // Increased - breaks builds noErrorHandlingForRiskyOps: 1.8, // Increased - causes runtime failures hasAnyType: 1.2, // Reduced - common in migration scenarios // Reduced SEO/accessibility penalties for pages criticalSeoMissing: 1.1, // Significantly reduced - expected in some page types criticalAccessibilityMissing: 1.2, // Slightly reduced // Enhanced bonuses for good architecture hasProperErrorHandling: 0.8, // Better bonus for good practices hasGoodTypeAnnotations: 0.85, // Better bonus lowComplexity: 0.85, // Better bonus for simple, clean code goodSeoImplementation: 0.95, // Minimal bonus - not architecture goodAccessibilityImplementation: 0.92, // Minimal bonus }; /** * Updated file type exclusions with better page component handling */ exports.FILE_TYPE_EXCLUSIONS = { constants: { excludeMetrics: [ "magicNumbers", "codeMetrics", "deduplicationOpportunities", "componentFlowComplexity", "seoProblems", "accessibilityIssues", ], reduceWeights: { typeIssues: 0.3, translationIssues: 0.1, }, }, config: { excludeMetrics: [ "magicNumbers", "componentFlowComplexity", "translationIssues", "seoProblems", "accessibilityIssues", ], reduceWeights: { typeIssues: 0.5, codeMetrics: 0.3, }, }, types: { excludeMetrics: [ "componentFlowComplexity", "seoProblems", "accessibilityIssues", "performanceIssues", "errorHandlingGaps", ], increaseWeights: { typeIssues: 2.5, // Type files should have excellent types }, }, utility: { increaseWeights: { errorHandlingGaps: 1.5, // Utilities should handle errors well typeIssues: 1.4, // Utilities should be strongly typed cyclomaticComplexity: 1.2, // Utilities should be simple }, reduceWeights: { seoProblems: 0.1, // Utilities don't affect SEO accessibilityIssues: 0.1, }, }, component: { increaseWeights: { cyclomaticComplexity: 1.3, // Components should be simple cognitiveComplexity: 1.3, couplingDegree: 1.2, // Components should be loosely coupled componentFlowComplexity: 1.4, // Complex rendering is problematic }, reduceWeights: { seoProblems: 0.3, // Most components don't handle SEO directly }, }, hook: { increaseWeights: { errorHandlingGaps: 1.4, // Hooks should handle edge cases typeIssues: 1.3, // Hooks should be well-typed cyclomaticComplexity: 1.2, // Hooks should be simple }, reduceWeights: { couplingDegree: 0.7, // Hooks naturally have dependencies seoProblems: 0.1, accessibilityIssues: 0.1, }, }, page: { // Special handling for pages - distinguish simple from complex increaseWeights: { cyclomaticComplexity: 1.8, // Pages should be simple containers cognitiveComplexity: 1.8, couplingDegree: 1.5, // Pages shouldn't be highly coupled componentFlowComplexity: 1.6, // Complex page logic is problematic errorHandlingGaps: 1.3, // Pages should handle errors gracefully }, reduceWeights: { seoProblems: 0.2, // Pages naturally have SEO - don't over-penalize accessibilityIssues: 0.4, // Important but not architecture-breaking translationIssues: 0.8, // Reduced penalty for pages }, }, }; /** * Score ranges for categorizing issues */ exports.SCORE_RANGES = { CRITICAL: { min: 80, max: 100 }, HIGH: { min: 60, max: 79 }, MEDIUM: { min: 40, max: 59 }, LOW: { min: 20, max: 39 }, MINIMAL: { min: 0, max: 19 }, }; /** * Enhanced file type detection with more specific categorization */ function getFileType(componentName, fullPath) { const fileName = componentName.toLowerCase(); const path = fullPath.toLowerCase(); // Check for constants/configuration files if (fileName.includes("constant") || fileName.includes("config") || path.includes("/constants/") || path.includes("/config/") || (fileName === "index" && path.includes("/constants/"))) { return "constants"; } // Check for configuration files if (fileName.includes(".config") || fileName.includes("configuration") || path.includes("config.") || fileName.endsWith("rc")) { return "config"; } // Check for type definition files if (fileName.includes(".types") || fileName.includes(".type") || path.includes("/types/") || fileName.includes("interface") || fileName.includes("schema")) { return "types"; } // Check for pages (higher priority than components) if (path.includes("/pages/") || (path.includes("/app/") && path.includes("page."))) { return "page"; } // Check for hooks if (fileName.startsWith("use") && fileName.length > 3) { return "hook"; } // Check for utilities if (path.includes("/utils/") || path.includes("/helpers/") || path.includes("/lib/") || fileName.includes("util")) { return "utility"; } // Default to component return "component"; }