UNPKG

@mkpro118/semantic-change-detector

Version:

Semantic change detection for TypeScript and TSX code with GitHub Actions integration

461 lines 15.3 kB
import type ts from 'typescript'; import type { SemanticChangeKind } from './semantic-change-kind.js'; export type { SemanticChangeKind } from './semantic-change-kind.js'; /** * SemanticChangeKind enumerates the categories of code changes that the * analyzer can detect. Each key corresponds to a specific rule and * includes a short string tag that is emitted with the change. The * documentation for each value explains what it means and why it * matters for behavior and tests. * * Notes * - These values are used in user-facing output and in CI annotations. * - Treat them as stable identifiers. * * @library-export */ /** * The union of all semantic change identifiers listed in * {@link SemanticChangeKind}. Useful for narrowing and switch * statements when handling results. * * @library-export */ export type SemanticChangeType = keyof SemanticChangeKind; /** * The severity assigned to a change. This guides test requirements and * CI reporting. * * - low — Cosmetic or low-risk changes. * - medium — Potential behavior change; tests recommended. * - high — Likely behavior change; tests required. * * @library-export */ export type SeverityLevel = 'low' | 'medium' | 'high'; /** * A single detected semantic change. * * Fields * - kind — The change category. * - severity — The assigned impact level. * - line/column — Location in the modified file (1/0 indexed). * - detail — Human-readable explanation of the change. * - astNode — AST node kind near the change. * - context — Optional extra info (e.g., signatures before/after). * * @library-export */ export type SemanticChange = { /** The change category identifier. */ kind: SemanticChangeType; /** Impact level for CI and test guidance. */ severity: SeverityLevel; /** 1-indexed line number in the modified file. */ line: number; /** 0-indexed column number in the modified file. */ column: number; /** Human-readable description of the change. */ detail: string; /** The AST node kind closest to the change. */ astNode: string; /** Optional extra details like prior/next signatures. */ context?: string; }; /** * A compact representation of a unified diff hunk used to scope * analysis. Hunks provide line ranges and the added/removed lines. * * @library-export */ export type DiffHunk = { /** File path the hunk applies to. */ file: string; /** Base (pre-change) line range covered by the hunk. */ baseRange: { start: number; end: number; }; /** Head (post-change) line range covered by the hunk. */ headRange: { start: number; end: number; }; /** Lines added in the head version (without leading '+'). */ addedLines: Array<{ lineNumber: number; content: string; }>; /** Lines removed from the base version (without leading '-'). */ removedLines: Array<{ lineNumber: number; content: string; }>; }; /** * A summarized semantic view of a source file used by the structural * analyzer. This captures imports/exports, declarations, JSX surface, * hooks, and known side-effect calls. * * @library-export */ export type SemanticContext = { /** Parsed TypeScript source file. */ sourceFile: ts.SourceFile; imports: Array<{ /** Module specifier text (e.g., 'react'). */ module: string; /** Imported names (post-alias). */ specifiers: string[]; /** Whether default import is present. */ isDefault: boolean; /** Whether namespace import (import * as X) is present. */ isNamespace: boolean; /** 1-indexed line of the import. */ line: number; /** 0-indexed column of the import. */ column: number; }>; exports: Array<{ /** Exported symbol name. */ name: string; /** Classifies export declaration kind. */ type: 'function' | 'class' | 'interface' | 'type' | 'variable' | 'const'; /** True when exported as default. */ isDefault: boolean; /** 1-indexed line of the export. */ line: number; /** 0-indexed column of the export. */ column: number; /** Optional signature text for callable exports. */ signature?: string; }>; functions: Array<{ /** Function name. */ name: string; /** Parameter list with simple types and optionality. */ parameters: Array<{ /** Parameter name. */ name: string; /** Parameter type (text). */ type: string; /** Whether parameter is optional. */ optional: boolean; }>; /** Return type (text). */ returnType: string; /** Whether function is async. */ isAsync: boolean; /** Cyclomatic complexity metric. */ complexity: number; /** 1-indexed line of declaration. */ line: number; /** 0-indexed column of declaration. */ column: number; }>; classes: Array<{ /** Class name. */ name: string; /** Superclass name if present. */ extends?: string; /** Implemented interface names. */ implements: string[]; /** 1-indexed line of class. */ line: number; /** 0-indexed column of class. */ column: number; methods: Array<{ /** Method name. */ name: string; /** Method parameters (simple representation). */ parameters: Array<{ /** Parameter name. */ name: string; /** Parameter type (text). */ type: string; /** Whether parameter is optional. */ optional: boolean; }>; /** Declared return type (text). */ returnType: string; /** Whether method is async. */ isAsync: boolean; /** Whether method is static. */ isStatic: boolean; /** Visibility modifier. */ visibility: 'public' | 'private' | 'protected'; }>; properties: Array<{ /** Property name. */ name: string; /** Declared type (text). */ type: string; /** Whether property is static. */ isStatic: boolean; /** Visibility modifier. */ visibility: 'public' | 'private' | 'protected'; }>; }>; interfaces: Array<{ /** Interface name. */ name: string; /** Extended interface names. */ extends: string[]; /** 1-indexed line of interface. */ line: number; /** 0-indexed column of interface. */ column: number; properties: Array<{ /** Property name. */ name: string; /** Property type (text). */ type: string; /** Whether property is optional. */ optional: boolean; }>; methods: Array<{ /** Method name. */ name: string; /** Parameters for the method. */ parameters: Array<{ /** Parameter name. */ name: string; /** Parameter type. */ type: string; /** Optional parameter flag. */ optional: boolean; }>; /** Return type (text). */ returnType: string; }>; }>; types: Array<{ /** Type alias or interface name. */ name: string; /** Normalized string for structural comparison. */ definition: string; /** 1-indexed declaration line. */ line: number; /** 0-indexed declaration column. */ column: number; }>; variables: Array<{ /** Variable name. */ name: string; /** Declared type (text). */ type: string; /** True when declared with const. */ isConst: boolean; /** True if an initializer is present. */ hasInitializer: boolean; /** 1-indexed line of declaration. */ line: number; /** 0-indexed column of declaration. */ column: number; }>; reactHooks: Array<{ /** Hook name (e.g., useEffect). */ name: string; /** Dependency identifiers as string form. */ dependencies: string[]; /** Hook classification. */ type: 'useState' | 'useEffect' | 'useCallback' | 'useMemo' | 'useContext' | 'useReducer' | 'custom'; /** 1-indexed line of the hook call. */ line: number; /** 0-indexed column of the hook call. */ column: number; }>; jsxElements: Array<{ /** Tag or component name. */ tagName: string; /** Props with a coarse type for analysis. */ props: Array<{ /** Prop name. */ name: string; /** Prop value classification. */ type: 'literal' | 'expression' | 'spread'; }>; /** Whether element contains children. */ hasChildren: boolean; /** True when the tag is a React component (capitalized). */ isComponent: boolean; }>; /** File-level complexity metric. */ complexity: number; sideEffectCalls: Array<{ /** Callee text for a known side-effect call. */ name: string; /** 1-indexed call line. */ line: number; /** 0-indexed call column. */ column: number; /** Number of arguments passed. */ arguments: number; }>; }; export type { AnalyzerConfig } from './config.js'; /** * The aggregated result for a multi-file analysis. * * Fields * - requiresTests — Whether high-severity changes require tests. * - summary — A human-readable summary string. * - filesAnalyzed — Number of files processed. * - totalChanges — Total detected changes. * - severityBreakdown — Counts by severity. * - highSeverityChanges — Count of high severity changes. * - topChangeTypes — The most frequent change kinds. * - criticalChanges — High-severity changes with location and details. * - changes — All changes with file path and AST context. * - failedFiles — Files that failed to analyze with error message. * - hasReactChanges — True if JSX/React hooks changes were detected. * - performance — Timing and memory usage metrics. * * @library-export */ export type AnalysisResult = { /** True if tests are required due to high severity. */ requiresTests: boolean; /** Human-readable summary of results. */ summary: string; /** Number of files analyzed. */ filesAnalyzed: number; /** Total number of detected changes. */ totalChanges: number; /** Counts of changes by severity. */ severityBreakdown: { /** High-severity changes count. */ high: number; /** Medium-severity changes count. */ medium: number; /** Low-severity changes count. */ low: number; }; /** Number of high-severity changes. */ highSeverityChanges: number; /** Top occurring change kinds and their max severity. */ topChangeTypes: Array<{ /** Change kind identifier. */ kind: string; /** Frequency of this change kind. */ count: number; /** Max severity observed for this kind. */ maxSeverity: SeverityLevel; }>; /** High-impact changes highlighted for quick review. */ criticalChanges: Array<{ /** File path. */ file: string; /** 1-indexed line of change. */ line: number; /** 0-indexed column of change. */ column: number; /** Change kind. */ kind: string; /** Human-readable details. */ detail: string; /** Change severity. */ severity: SeverityLevel; }>; /** All changes across analyzed files. */ changes: Array<{ /** File path. */ file: string; /** 1-indexed line of change. */ line: number; /** 0-indexed column of change. */ column: number; /** Change kind. */ kind: string; /** Human-readable details. */ detail: string; /** Change severity. */ severity: SeverityLevel; /** AST node near the change. */ astNode: string; /** Optional extra information. */ context?: string; }>; /** Files that failed analysis and their error messages. */ failedFiles: Array<{ filePath: string; error: string; }>; /** True if any React/JSX-related changes were found. */ hasReactChanges: boolean; /** Performance metrics for the analysis run. */ performance: { /** Total elapsed analysis time in ms. */ analysisTimeMs: number; /** Peak memory usage in MB. */ memoryUsageMB: number; }; }; /** * The extracted JSX structure and behavior signals used by the JSX * analyzer. * * @library-export */ export type JSXAnalysisResult = { /** JSX elements with basic metadata and prop classifications. */ elements: Array<{ /** Tag or component name. */ tagName: string; /** 1-indexed element start line. */ line: number; /** 0-indexed element start column. */ column: number; /** Prop list with value kinds. */ props: Array<{ /** Prop name. */ name: string; /** Prop value classification. */ type: 'literal' | 'expression' | 'spread'; /** Raw prop value text (normalized as needed). */ value: string; }>; /** Whether the element has children. */ hasChildren: boolean; /** True when component (capitalized) rather than DOM tag. */ isComponent: boolean; }>; /** Event handlers discovered with basic complexity estimate. */ eventHandlers: Array<{ /** Host element tag or component name. */ element: string; /** Event name (e.g., onClick). */ event: string; /** 1-indexed handler line. */ line: number; /** 0-indexed handler column. */ column: number; /** Inline handler flag. */ isInline: boolean; /** Rough complexity heuristic for the handler. */ complexity: number; }>; /** Logical expressions used in JSX rendering. */ logicalExpressions: Array<{ /** 1-indexed line. */ line: number; /** 0-indexed column. */ column: number; /** Operator token (e.g., && or ||). */ operator: string; /** Complexity heuristic for the expression. */ complexity: number; }>; /** Conditional rendering sites (ternary / logical / conditional). */ conditionalRendering: Array<{ /** 1-indexed line. */ line: number; /** 0-indexed column. */ column: number; /** Conditional kind classification. */ type: 'ternary' | 'logical' | 'conditional'; }>; /** Component names referenced by JSX. */ componentReferences: string[]; }; //# sourceMappingURL=index.d.ts.map