1+ import { CodeAnalyzerConfigFactory } from "../factories/CodeAnalyzerConfigFactory.js" ;
2+ import { EnginePluginsFactory } from "../factories/EnginePluginsFactory.js" ;
3+ import { TelemetryService } from "@salesforce/mcp-provider-api" ;
4+ import { CodeAnalyzer , Rule , RuleSelection } from "@salesforce/code-analyzer-core" ;
5+ import { getMessage } from "../messages.js" ;
6+ import { getErrorMessage } from "../utils.js" ;
7+ import { ErrorCapturer } from "../listeners/ErrorCapturer.js" ;
8+ import { TelemetryListenerFactory } from "../factories/TelemetryListenerFactory.js" ;
9+ import { EnginePlugin } from "@salesforce/code-analyzer-engine-api" ;
10+ import * as Constants from "../constants.js" ;
11+
12+ type ListRulesActionOptions = {
13+ configFactory : CodeAnalyzerConfigFactory
14+ enginePluginsFactory : EnginePluginsFactory
15+ telemetryService ?: TelemetryService
16+ }
17+
18+ export type ListRulesInput = {
19+ selector : string
20+ } ;
21+
22+
23+ export type ListRulesOutput = {
24+ status : string
25+ rules ?: {
26+ name : string
27+ engine : string
28+ severity : number
29+ tags : string [ ]
30+ description : string
31+ resources : string [ ]
32+ } [ ]
33+ } ;
34+
35+ export interface ListRulesAction {
36+ exec ( input : ListRulesInput ) : Promise < ListRulesOutput > ;
37+ }
38+
39+ export class ListRulesActionImpl implements ListRulesAction {
40+ private readonly configFactory : CodeAnalyzerConfigFactory ;
41+ private readonly enginePluginsFactory : EnginePluginsFactory ;
42+ private readonly telemetryService ?: TelemetryService ;
43+
44+ public constructor ( options : ListRulesActionOptions ) {
45+ this . configFactory = options . configFactory ;
46+ this . enginePluginsFactory = options . enginePluginsFactory ;
47+ this . telemetryService = options . telemetryService ;
48+ }
49+
50+ public async exec ( input : ListRulesInput ) : Promise < ListRulesOutput > {
51+ let analyzer : CodeAnalyzer ;
52+ try {
53+ analyzer = new CodeAnalyzer ( this . configFactory . create ( ) ) ;
54+ } catch ( e ) {
55+ return {
56+ status : getMessage ( 'errorCreatingConfig' , getErrorMessage ( e ) )
57+ } ;
58+ }
59+
60+ const errorCapturer : ErrorCapturer = new ErrorCapturer ( ) ;
61+ errorCapturer . listen ( analyzer ) ;
62+
63+ const telemetryListener = new TelemetryListenerFactory ( ) . create ( this . telemetryService )
64+ telemetryListener . listen ( analyzer )
65+
66+ const enginePlugins : EnginePlugin [ ] = this . enginePluginsFactory . create ( ) ;
67+ try {
68+ for ( const enginePlugin of enginePlugins ) {
69+ await analyzer . addEnginePlugin ( enginePlugin ) ;
70+ }
71+ } catch ( e ) {
72+ return {
73+ status : getMessage ( 'errorAddingEngine' , getErrorMessage ( e ) )
74+ } ;
75+ }
76+
77+ const ruleSelection : RuleSelection = await analyzer . selectRules ( [ input . selector ] ) ;
78+ this . emitEngineTelemetry ( ruleSelection , enginePlugins . flatMap ( p => p . getAvailableEngineNames ( ) ) ) ;
79+
80+ const rules = ruleSelection . getEngineNames ( ) . flatMap ( e => ruleSelection . getRulesFor ( e ) ) . map ( r => {
81+ return {
82+ name : r . getName ( ) ,
83+ engine : r . getEngineName ( ) ,
84+ severity : r . getSeverityLevel ( ) ,
85+ description : r . getDescription ( ) ,
86+ resources : r . getResourceUrls ( ) ,
87+ tags : r . getTags ( )
88+ }
89+ } ) ;
90+ return {
91+ status : "success" ,
92+ rules
93+ } ;
94+ }
95+
96+
97+ private emitEngineTelemetry ( ruleSelection : RuleSelection , coreEngineNames : string [ ] ) : void {
98+ const selectedEngineNames : Set < string > = new Set ( ruleSelection . getEngineNames ( ) ) ;
99+ for ( const coreEngineName of coreEngineNames ) {
100+ if ( ! selectedEngineNames . has ( coreEngineName ) ) {
101+ continue ;
102+ }
103+ if ( this . telemetryService ) {
104+ this . telemetryService . sendEvent ( Constants . TelemetryEventName , {
105+ source : Constants . TelemetrySource ,
106+ sfcaEvent : Constants . McpTelemetryEvents . ENGINE_SELECTION ,
107+ engine : coreEngineName ,
108+ ruleCount : ruleSelection . getRulesFor ( coreEngineName ) . length
109+ } )
110+ }
111+ }
112+ }
113+ }
0 commit comments