From 6a37da801c5189d79b5505a9775ae34110d99bea Mon Sep 17 00:00:00 2001 From: Sumit Morchhale Date: Tue, 22 Apr 2025 09:02:16 +0530 Subject: [PATCH] Added code changes for engine api list feature --- src/main/engines/CxEngines.ts | 97 ++++++++++++++++++++++++++++ src/main/wrapper/CxConstants.ts | 5 +- src/main/wrapper/CxWrapper.ts | 31 +++++++++ src/main/wrapper/ExecutionService.ts | 6 ++ src/tests/EnginesTest.test.ts | 47 ++++++++++++++ 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/main/engines/CxEngines.ts create mode 100644 src/tests/EnginesTest.test.ts diff --git a/src/main/engines/CxEngines.ts b/src/main/engines/CxEngines.ts new file mode 100644 index 00000000..c0a69965 --- /dev/null +++ b/src/main/engines/CxEngines.ts @@ -0,0 +1,97 @@ +// interface Api { +// api_url: string; +// api_name: string; +// description: string; +// } + +// interface Engine { +// engine_id: string; +// engine_name: string; +// apis: Api[]; +// } + +// class EngineCollection { +// engines: Engine[]; + +// constructor(data: any) { +// this.engines = data.engines.map((engine: any) => ({ +// engine_id: engine.engine_id, +// engine_name: engine.engine_name, +// apis: engine.apis.map((api: any) => ({ +// api_url: api.api_url, +// api_name: api.api_name, +// description: api.description, +// })), +// })); +// } +// } + + +// type Engine = { +// engine_id: string; +// engine_name: string; +// apis: Array<{ +// api_url: string; +// api_name: string; +// description: string; +// }>; +// }; + +// export default class DataParser { +// private rawData: any; + +// constructor(rawData: any) { +// this.rawData = data; +// } + +// public static getParsedData(rawData: any): Array { +// this.rawData=rawData +// return this.rawData.engines.map((data: any) => ({ +// engine_id: engine.engine_id, +// engine_name: engine.engine_name, +// apis: engine.apis.map((api: any) => ({ +// api_url: api.api_url, +// api_name: api.api_name, +// description: api.description +// })) +// })); +// } +// } + + + + + + +interface Api { + api_url: string; + api_name: string; + description: string; + } + + interface Engine { + engine_id: string; + engine_name: string; + apis: Api[]; + } + + export default class EngineParser { + public static parseEngine(json: any): Engine[] { + if (json && Array.isArray(json.engines)) { + return json.engines.map((engine: any) => ({ + engine_id: engine.engine_id, + engine_name: engine.engine_name, + apis: engine.apis.map((api: any) => ({ + api_url: api.api_url, + api_name: api.api_name, + description: api.description + })) + })); + } else { + throw new Error("Invalid JSON format"); + } + } + } + + + \ No newline at end of file diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index 49d7643d..473a7cd2 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -106,5 +106,8 @@ export enum CxConstants { STATE_CONFIRMED = "confirmed", CMD_LEARN_MORE = "learn-more", IDE_SCANS_KEY = " scan.config.plugins.ideScans", - AI_GUIDED_REMEDIATION_KEY = " scan.config.plugins.aiGuidedRemediation" + AI_GUIDED_REMEDIATION_KEY = " scan.config.plugins.aiGuidedRemediation", + CMD_ENGINES = "engines", + ENGINE_NAME="--engine-name", + ENGINE_TYPE="EngineParser" } diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index 0afa2f33..24d55713 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -177,6 +177,16 @@ export class CxWrapper { return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.PROJECT_TYPE); } + async engineApiList(filters: string): Promise { + const validated_filters = this.filterEnginesName(filters); + const commands: string[] = [CxConstants.CMD_ENGINES, "list-api","--output-format", "json"].concat(validated_filters); + commands.push(...this.initializeCommands(false)); + const filterEngineCommand = commands.filter(item => item !== "--debug"); + console.log(filterEngineCommand) + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, filterEngineCommand, CxConstants.ENGINE_TYPE); + } + async projectBranches(projectId: string, filters: string): Promise { // Verify and add possible branch filter by name const validated_filters = this.filterArguments(CxConstants.BRANCH_NAME + filters) @@ -471,4 +481,25 @@ export class CxWrapper { } return r; } + + filterEnginesName(filters: string): string[] { + const r = []; + if (filters.length > 0) { + r.push(CxConstants.ENGINE_NAME); + if(filters==="SAST") + { + r.push("SAST"); + } + if(filters==="SCA") + { + r.push("SCA"); + } + if(filters==="Iac") + { + r.push("Iac"); + } + } + + return r; + } } \ No newline at end of file diff --git a/src/main/wrapper/ExecutionService.ts b/src/main/wrapper/ExecutionService.ts index 65443950..a8654ef2 100644 --- a/src/main/wrapper/ExecutionService.ts +++ b/src/main/wrapper/ExecutionService.ts @@ -23,6 +23,7 @@ import CxScaRealTime from "../scaRealtime/CxScaRealTime"; import CxChat from "../chat/CxChat"; import CxMask from "../mask/CxMask"; import CxAsca from "../asca/CxAsca"; +import EngineParser from "../engines/CxEngines"; let skipValue = false; const fileSourceFlag = "--file-source" @@ -80,6 +81,7 @@ export class ExecutionService { }); this.fsObject.on('exit',(code: number) => { + console.log("code",code) logger.info("Exit code received from AST-CLI: " + code); if(code==1){ stderr = stdout @@ -209,6 +211,10 @@ export class ExecutionService { const projects = CxProject.parseProject(resultObject); cxCommandOutput.payload = projects; break; + case CxConstants.ENGINE_TYPE: + const engines = EngineParser.parseEngine(resultObject); + cxCommandOutput.payload = engines + break; case CxConstants.CODE_BASHING_TYPE: const codeBashing = CxCodeBashing.parseCodeBashing(resultObject); cxCommandOutput.payload = codeBashing; diff --git a/src/tests/EnginesTest.test.ts b/src/tests/EnginesTest.test.ts new file mode 100644 index 00000000..86124905 --- /dev/null +++ b/src/tests/EnginesTest.test.ts @@ -0,0 +1,47 @@ +import {CxWrapper} from '../main/wrapper/CxWrapper'; +import {CxCommandOutput} from "../main/wrapper/CxCommandOutput"; +import {BaseTest} from "./BaseTest"; + +describe("EngineAPIList cases",() => { + const cxScanConfig = new BaseTest(); + it('EngineAPIList Successful case1', async () => { + const auth = new CxWrapper(cxScanConfig); + const data = await auth.engineApiList("SAST"); + const cxCommandOutput: CxCommandOutput = data; + console.log(cxCommandOutput) + expect(cxCommandOutput.payload.length).toBeGreaterThan(0); + }); + + it('EngineAPIList Successful case2', async () => { + const auth = new CxWrapper(cxScanConfig); + const data = await auth.engineApiList("SCA"); + const cxCommandOutput: CxCommandOutput = data; + console.log(cxCommandOutput) + expect(cxCommandOutput.payload.length).toBeGreaterThan(0); + }); + + it('EngineAPIList Successful case3', async () => { + const auth = new CxWrapper(cxScanConfig); + const data = await auth.engineApiList("Iac"); + const cxCommandOutput: CxCommandOutput = data; + console.log(cxCommandOutput) + expect(cxCommandOutput.payload.length).toBeGreaterThan(0); + }); + + it('EngineAPIList Successful case4', async () => { + const auth = new CxWrapper(cxScanConfig); + const data = await auth.engineApiList(""); + const cxCommandOutput: CxCommandOutput = data; + console.log(cxCommandOutput) + expect(cxCommandOutput.payload.length).toBeGreaterThan(0); + }); + + it('EngineAPIList Successful case5', async () => { + const auth = new CxWrapper(cxScanConfig); + const data = await auth.engineApiList("xyz"); + const cxCommandOutput: CxCommandOutput = data; + console.log(cxCommandOutput) + expect(cxCommandOutput.exitCode).toBe(1); + }); + +}); \ No newline at end of file