All files / src/cm6 lint-source.ts

100% Statements 30/30
100% Branches 11/11
100% Functions 3/3
100% Lines 30/30

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 481x 1x                         1x 103x 7x 7x   7x   5x   5x 7x 103x   3x 3x 3x 3x 3x 3x 3x 3x 3x   3x 3x 3x 1x 3x 1x 3x 1x 3x 3x  
import { type Diagnostic as CMDiagnostic, type LintSource } from '@codemirror/lint';
import {
  SpelDiagnosticEngine,
  type ContextSchema,
  type SpelDiagnostic,
  DiagnosticSeverity,
} from '@agentix-e/spel-ts';
 
/**
 * Adapter: spel-ts DiagnosticEngine → CM6 LintSource.
 *
 * Runs syntax + semantic + context checks on each change
 * and maps SpelDiagnostic[] to CM6 Diagnostic[].
 */
export function spelLint(getContextSchema?: () => ContextSchema | null): LintSource {
  return (view) => {
    const expression = view.state.sliceDoc();
    const schema = getContextSchema?.() ?? undefined;
 
    if (expression.trim().length === 0) return [];
 
    const diagnostics = SpelDiagnosticEngine.validate(expression, schema);
 
    return diagnostics.map((d) => mapToCM6Diagnostic(d));
  };
}
 
function mapToCM6Diagnostic(d: SpelDiagnostic): CMDiagnostic {
  return {
    from: d.from,
    to: d.to,
    message: d.message,
    severity: mapSeverity(d.severity),
    source: d.code,
  };
}
 
function mapSeverity(sev: DiagnosticSeverity): 'error' | 'warning' | 'info' {
  switch (sev) {
    case DiagnosticSeverity.ERROR:
      return 'error';
    case DiagnosticSeverity.WARNING:
      return 'warning';
    case DiagnosticSeverity.INFO:
      return 'info';
  }
}