@@ -2,15 +2,15 @@ import { ScanOverview } from "./ScanOverviewPanel";
22import * as vscode from "vscode" ;
33import * as uuid from "uuid" ;
44import { convertArrayToCSV } from "convert-array-to-csv" ;
5- import { ScanResult } from "@flow-scanner/lightning-flow-scanner-core" ;
5+ import { exportSarif , ScanResult } from "@flow-scanner/lightning-flow-scanner-core" ;
6+ import { CacheProvider } from "../providers/cache-provider" ;
67
78export class ViolationOverview {
89 public static currentPanel : ViolationOverview | undefined ;
910 public static readonly viewType = "report" ;
1011 private readonly _panel : vscode . WebviewPanel ;
1112 private readonly _extensionUri : vscode . Uri ;
1213 private _disposables : vscode . Disposable [ ] = [ ] ;
13- private isDownloading = false ;
1414
1515 public static createOrShow (
1616 extensionUri : vscode . Uri ,
@@ -106,22 +106,64 @@ export class ViolationOverview {
106106 return ;
107107 }
108108 case "download" : {
109- if ( ! data . value ) {
109+ if ( ! data . value || ! Array . isArray ( data . value ) || data . value . length === 0 ) {
110110 await vscode . window . showInformationMessage (
111- "No results found. Please make sure to complete a scan before calculating coverage ."
111+ "No results found. Please make sure to complete a scan before downloading ."
112112 ) ;
113113 return ;
114114 }
115- let saveResult = await vscode . window . showSaveDialog ( {
116- filters : {
117- csv : [ ".csv" ] ,
118- } ,
119- } ) ;
120- const csv = convertArrayToCSV ( data . value ) ;
121- await vscode . workspace . fs . writeFile ( saveResult , Buffer . from ( csv ) ) ;
122- await vscode . window . showInformationMessage (
123- "Downloaded file: " + saveResult . fsPath
115+
116+ const formatChoice = await vscode . window . showQuickPick (
117+ [
118+ { label : "CSV" , description : "Comma-separated values" , value : "csv" } ,
119+ { label : "SARIF" , description : "Static Analysis Results Interchange Format" , value : "sarif" }
120+ ] ,
121+ {
122+ placeHolder : "Select export format (Esc to cancel)" ,
123+ canPickMany : false ,
124+ ignoreFocusOut : false ,
125+ }
124126 ) ;
127+
128+ if ( ! formatChoice ) return ;
129+
130+ const chosenFormat = formatChoice . value ;
131+ const filterKey = chosenFormat === "sarif" ? "sarif" : "csv" ;
132+ const filterExt = chosenFormat === "sarif" ? ".sarif" : ".csv" ;
133+
134+ const defaultUri = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri ;
135+ const saveResult = await vscode . window . showSaveDialog ( {
136+ defaultUri,
137+ filters : { [ filterKey ] : [ filterExt ] } ,
138+ title : `Save ${ chosenFormat . toUpperCase ( ) } file` ,
139+ } ) ;
140+
141+ if ( ! saveResult ) return ;
142+
143+ try {
144+ let content : string ;
145+
146+ if ( chosenFormat === "sarif" ) {
147+ const cachedResults = CacheProvider . instance . get ( "results" ) as ScanResult [ ] | undefined ;
148+ if ( ! cachedResults || cachedResults . length === 0 ) {
149+ await vscode . window . showWarningMessage ( "No scan data available for SARIF export. Please run a scan first." ) ;
150+ return ;
151+ }
152+ content = exportSarif ( cachedResults ) ;
153+ } else {
154+ content = convertArrayToCSV ( data . value ) ;
155+ }
156+
157+ await vscode . workspace . fs . writeFile ( saveResult , Buffer . from ( content , "utf-8" ) ) ;
158+ await vscode . window . showInformationMessage (
159+ `Downloaded ${ chosenFormat . toUpperCase ( ) } file: ${ saveResult . fsPath } `
160+ ) ;
161+ } catch ( err : any ) {
162+ await vscode . window . showErrorMessage (
163+ `Failed to export ${ chosenFormat . toUpperCase ( ) } : ${ err ?. message || err } `
164+ ) ;
165+ }
166+ break ;
125167 }
126168 }
127169 } ) ;
0 commit comments