@conterra/vuln-scan 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jira-reporter.js +4 -4
- package/dist/vuln-scan.js +3 -3
- package/package.json +3 -3
package/dist/jira-reporter.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var J=require("path"),V=require("zx");var R=require("fs/promises");function E(r,e=""){return O(r,e)}function O(r,e="",n
|
|
3
|
-
`,s+=
|
|
4
|
-
`),
|
|
2
|
+
"use strict";var J=require("path"),V=require("zx");var R=require("fs/promises");function E(r,e=""){return O(r,e,new Set,new Set)}function O(r,e="",n,t){let s=`${e}- ${r.purl}`;if(n.has(r.purl))return s+=" (cycle detected)",s;if(t.has(r.purl))return s+=" (deduplicated)",s;t.add(r.purl),n.add(r.purl);let i=n.size===1;for(let o of r.usedBy){let a=O(o,e+(i?" ":" "),n,t);a!==""&&(s+=`
|
|
3
|
+
`,s+=a)}return n.delete(r.purl),s}async function U(r){let{scanSummaryPath:e,jiraConfigPath:n,jiraUser:t,jiraApiToken:s,dryRun:i=!1}=r,[o,a]=await Promise.all([W(e),q(n)]),c={created:[],skipped:[],errors:[]},u=new I(a.jiraUrl,t,s),C=new Map;for(let[f,T]of Object.entries(o.vulnerabilities)){let K=o.vulnerabilityToProject[f]??[];for(let l of a.issues){let w=K.filter(h=>M(h,l.reportProjects));if(w.length===0)continue;let S=X(T);try{let h=await u.issueExists(l.jiraProject,f);if(h){console.log(`[skip] Issue for ${f} already exists: ${h}`),c.skipped.push(`${l.jiraProject}::${f}`);continue}if(i){console.log(`[dry-run] Would create issue in ${l.jiraProject}: "${S}"`),console.log(` Matching projects: ${w.join(", ")}`),c.created.push(`${l.jiraProject}::${f}`);continue}let b,k=[],v=!1;for(let p of l.addToBoard??[]){let m=p.matchProjects??["*"];if(w.some(d=>M(d,m)))if(p.sprintBoardId!=null){if(!v){v=!0;let d=p.sprintBoardId;if(!C.has(d)){let P=await u.getActiveSprintId(d).catch(H=>(console.warn(`[warn] Could not resolve active sprint for boardId ${d}: ${String(H)}`),null));C.set(d,P)}b=C.get(d)??void 0,p.issueLabels&&k.push(...p.issueLabels)}}else p.issueLabels&&k.push(...p.issueLabels)}let B=[...l.issueLabels??[],...k],j=new Map;if(o.projectsToComponents)for(let p of w){let m=o.projectsToComponents[p]??{},x=[];for(let d of T.components){let P=m[d];P&&x.push(P)}x.length>0&&j.set(p,x)}let _=ne(T,w,j),$=await u.createIssue({projectKey:l.jiraProject,issueType:l.issueType,summary:S,description:_,labels:B.length>0?B:void 0,sprintId:b});if(j.size>0){let p=re(f,j);if(p){let m=`${f}-dependency-trees.md`;await u.attachMarkdown($,m,p),console.log(`[attached] ${m} to ${$}`)}}console.log(`[created] ${$} in ${l.jiraProject}: "${S}"`),c.created.push($)}catch(h){let b=`Failed to process ${f} for project ${l.jiraProject}: ${String(h)}`;console.error(`[error] ${b}`),c.errors.push(b)}}}return c}async function W(r){let e=await(0,R.readFile)(r,"utf8");return JSON.parse(e)}async function q(r){let e=await(0,R.readFile)(r,"utf8"),n=JSON.parse(e);if(!n.issues&&n.issue&&(n.issues=n.issue),!n.jiraUrl||typeof n.jiraUrl!="string")throw new Error("jira-conf.json: missing or invalid 'jiraUrl' field");if(!Array.isArray(n.issues))throw new Error("jira-conf.json: missing or invalid 'issues' array");return n}function G(r){return r.replace(/[.+?^${}()|[\]\\]/g,"\\$&")}function Q(r,e){let n=e.split("*").map(G).join(".*");return new RegExp(`^${n}$`).test(r)}function M(r,e){return e.some(n=>Q(r,n))}function X(r){let e=r.title?`: ${r.title}`:"";return`[${r.severity}] ${r.id}${e}`}function Y(...r){return{type:"doc",version:1,content:r}}function g(r,e){return{type:"heading",attrs:{level:r},content:[{type:"text",text:e}]}}function Z(r){let e=r.split(/\r?\n/),n=[],t=0;for(;t<e.length;){let s=e[t],i=s.match(/^```(\w*)$/);if(i){let c=i[1]??"text",u=[];for(t++;t<e.length&&!e[t].startsWith("```");)u.push(e[t]),t++;t++,n.push(L(u.join(`
|
|
4
|
+
`),c));continue}let o=s.match(/^(#{1,3})\s+(.+)$/);if(o){let c=Math.min(o[1].length,3);n.push(g(c,o[2].trim())),t++;continue}if(/^[-*]\s/.test(s)){let c=[];for(;t<e.length&&/^[-*]\s/.test(e[t]);){let u=e[t].replace(/^[-*]\s+/,"");c.push({type:"listItem",content:[{type:"paragraph",content:A(u)}]}),t++}n.push({type:"bulletList",content:c});continue}if(/^\d+\.\s/.test(s)){let c=[];for(;t<e.length&&/^\d+\.\s/.test(e[t]);){let u=e[t].replace(/^\d+\.\s+/,"");c.push({type:"listItem",content:[{type:"paragraph",content:A(u)}]}),t++}n.push({type:"orderedList",content:c});continue}if(s.trim()===""){t++;continue}let a=[];for(;t<e.length&&e[t].trim()!==""&&!/^(#{1,3}\s|[-*]\s|\d+\.\s|```)/.test(e[t]);)a.push(e[t]),t++;if(a.length>0){let c=[];for(let u=0;u<a.length;u++)c.push(...A(a[u])),u<a.length-1&&c.push({type:"hardBreak"});n.push({type:"paragraph",content:c})}}return n}function A(r){let e=[],n=/(\*\*(.+?)\*\*|\*(.+?)\*|`(.+?)`|_(.+?)_)/g,t=0,s;for(;(s=n.exec(r))!==null;)s.index>t&&e.push({type:"text",text:r.slice(t,s.index)}),s[2]!==void 0?e.push({type:"text",text:s[2],marks:[{type:"strong"}]}):s[3]!==void 0?e.push({type:"text",text:s[3],marks:[{type:"em"}]}):s[4]!==void 0?e.push({type:"text",text:s[4],marks:[{type:"code"}]}):s[5]!==void 0&&e.push({type:"text",text:s[5],marks:[{type:"em"}]}),t=s.index+s[0].length;return t<r.length&&e.push({type:"text",text:r.slice(t)}),e.length>0?e:[{type:"text",text:r}]}function L(r,e="text"){return{type:"codeBlock",attrs:{language:e},content:[{type:"text",text:r}]}}function ee(r){return{type:"bulletList",content:r.map(e=>({type:"listItem",content:[{type:"paragraph",content:[{type:"text",text:e}]}]}))}}function te(r){return{type:"bulletList",content:r.map(e=>({type:"listItem",content:[{type:"paragraph",content:[{type:"text",text:e,marks:[{type:"link",attrs:{href:e}}]}]}]}))}}function N(r,...e){return{type:"expand",attrs:{title:r},content:e}}function y(r){return{type:"paragraph",content:[{type:"text",text:r,marks:[{type:"em"}]}]}}function D(r){return!r||r.length===0?"":r.map(e=>E(e,"")).join(`
|
|
5
5
|
|
|
6
6
|
`)}function re(r,e){if(e.size===0)return"";let n=[`# Verwendungsb\xE4ume f\xFCr ${r}`,""];for(let[t,s]of[...e.entries()].sort(([i],[o])=>i.localeCompare(o))){n.push(`## ${t}`,"");let i=D(s);i&&n.push("```",i,"```"),n.push("")}return n.join(`
|
|
7
|
-
`)}function ne(r,e,n=new Map){let t=[],i=0;if(t.push(g(1,"Informationen zur Schwachstelle")),t.push(y("Diese Informationen wurden automatisch generiert.")),r.refs&&r.refs.length>0&&t.push(te(r.refs)),r.description){let o=Z(r.description);t.push(N("Beschreibung",...o))}t.push(g(2,"Betroffene Artefakte")),r.components&&r.components.length>0?t.push(ee(r.components)):t.push(y("Keine Komponenten bekannt.")),t.push(g(2,"Gemeldet f\xFCr"));for(let o of e.slice().sort()){t.push({type:"paragraph",content:[{type:"text",text:o,marks:[{type:"strong"}]}]});let
|
|
7
|
+
`)}function ne(r,e,n=new Map){let t=[],i=0;if(t.push(g(1,"Informationen zur Schwachstelle")),t.push(y("Diese Informationen wurden automatisch generiert.")),r.refs&&r.refs.length>0&&t.push(te(r.refs)),r.description){let o=Z(r.description);t.push(N("Beschreibung",...o))}t.push(g(2,"Betroffene Artefakte")),r.components&&r.components.length>0?t.push(ee(r.components)):t.push(y("Keine Komponenten bekannt.")),t.push(g(2,"Gemeldet f\xFCr"));for(let o of e.slice().sort()){t.push({type:"paragraph",content:[{type:"text",text:o,marks:[{type:"strong"}]}]});let a=n.get(o);if(a&&a.length>0){let c=D(a);c&&(i+=c.length,i>2e4?t.push(N("Verwendungsbaum",y("Gesamtgr\xF6\xDFe der Verwendungsb\xE4ume \xFCberschreitet Limit. Siehe Issue-Attachments f\xFCr vollst\xE4ndige B\xE4ume."))):t.push(N("Verwendungsbaum",L(c))))}}return t.push(g(1,"Einwertung")),t.push(y("Einwertung des CVE in Bezug auf die gemeldeten Projekte/Produkte. Dies kann eine Bewertung der Schwere, der Auswirkungen und der Wahrscheinlichkeit eines Angriffs umfassen.")),t.push(g(1,"Betroffen sind")),t.push(y("Abschlie\xDFende Darstellung, welche Projekte/Produkte tats\xE4chlich betroffen oder nicht betroffen sind.")),t.push(g(1,"Ma\xDFnahmen")),t.push(y("\xDCbersicht der zu ergreifenden Ma\xDFnahmen, um den CVE zu beheben oder zu mitigieren. Dies kann Patches, Updates oder Konfigurations\xE4nderungen umfassen.")),Y(...t)}var I=class{authHeader;baseUrl;constructor(e,n,t){this.baseUrl=e.replace(/\/$/,""),this.authHeader=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`}get headers(){return{Authorization:this.authHeader,"Content-Type":"application/json",Accept:"application/json"}}async safeJson(e,n){let t=await e.text();try{return JSON.parse(t)}catch{let s=t.slice(0,500).replace(/\s+/g," ").trim();throw new Error(`${n}: expected JSON but got (HTTP ${e.status}): ${s}`)}}async issueExists(e,n){let t=n.replace(/"/g,'\\"'),s=`project = "${e}" AND summary ~ "\\"${t}\\""`,i=`${this.baseUrl}/rest/api/3/search/jql?jql=${encodeURIComponent(s)}&maxResults=1&fields=summary`,o=await fetch(i,{method:"GET",headers:this.headers});if(!o.ok){let c=await o.text();throw new Error(`Jira search failed (${o.status}): ${c}`)}return(await this.safeJson(o,"Jira search")).issues[0]?.key??null}async createIssue(e){let n={project:{key:e.projectKey},issuetype:{name:e.issueType},summary:e.summary,description:e.description};e.labels&&e.labels.length>0&&(n.labels=e.labels),e.sprintId!=null&&(n.customfield_10020=e.sprintId);let t={fields:n},s=await fetch(`${this.baseUrl}/rest/api/3/issue`,{method:"POST",headers:this.headers,body:JSON.stringify(t)});if(!s.ok){let o=await s.text();throw new Error(`Jira create issue failed (${s.status}): ${o}`)}return(await this.safeJson(s,"Jira create issue")).key}async attachMarkdown(e,n,t){let s=`${this.baseUrl}/rest/api/3/issue/${e}/attachments`,i=new FormData;i.append("file",new Blob([t],{type:"text/markdown"}),n);let o=await fetch(s,{method:"POST",headers:{Authorization:this.authHeader,"X-Atlassian-Token":"no-check"},body:i});if(!o.ok){let a=await o.text();throw new Error(`Jira attach file failed (${o.status}): ${a}`)}}async getActiveSprintId(e){let n=`${this.baseUrl}/rest/agile/1.0/board/${e}/sprint?state=active&maxResults=1`,t=await fetch(n,{method:"GET",headers:this.headers});if(!t.ok){let i=await t.text();throw new Error(`Jira agile sprint lookup failed (${t.status}): ${i}`)}return(await this.safeJson(t,"Jira sprint lookup")).values[0]?.id??null}};V.dotenv.config();var F=process.env;function se(r){let e=r.slice(2),n=process.cwd(),t=(0,J.join)(n,"jira-conf.json"),s=(0,J.join)(n,"output","scan-summary.json"),i=!1;for(let o=0;o<e.length;o++){let a=e[o];(a==="--jira-config"||a==="-c")&&e[o+1]?t=e[++o]:(a==="--summary"||a==="-s")&&e[o+1]?s=e[++o]:a==="--dry-run"?i=!0:a==="--help"||a==="-h"?(z(),process.exit(0)):(console.error(`Unknown argument: ${a}`),z(),process.exit(1))}return{jiraConfigPath:t,scanSummaryPath:s,dryRun:i}}function z(){console.log(`Usage: ct-vuln-jira-report [options]
|
|
8
8
|
|
|
9
9
|
Options:
|
|
10
10
|
-c, --jira-config <path> Path to jira-conf.json configuration file
|
package/dist/vuln-scan.js
CHANGED
|
@@ -588,8 +588,8 @@ GFS4: `),console.error(e)});Ju[v0]||(yNe=global[v0]||[],vNe(Ju,yNe),Ju.close=(fu
|
|
|
588
588
|
|
|
589
589
|
see https://github.com/jprichardson/node-fs-extra/issues/269`,"Warning","fs-extra-WARN0002");let{srcStat:n,destStat:a}=wI.checkPathsSync(e,t,"copy",r);if(wI.checkParentPathsSync(e,n,t,"copy"),r.filter&&!r.filter(e,t))return;let s=SI.dirname(t);return p_.existsSync(s)||Q2r(s),$Ne(a,e,t,r)}function $Ne(e,t,r,n){let s=(n.dereference?p_.statSync:p_.lstatSync)(t);if(s.isDirectory())return oyr(s,e,t,r,n);if(s.isFile()||s.isCharacterDevice()||s.isBlockDevice())return tyr(s,e,t,r,n);if(s.isSymbolicLink())return lyr(e,t,r,n);throw s.isSocket()?new Error(`Cannot copy a socket file: ${t}`):s.isFIFO()?new Error(`Cannot copy a FIFO pipe: ${t}`):new Error(`Unknown file: ${t}`)}function tyr(e,t,r,n,a){return t?ryr(e,r,n,a):VNe(e,r,n,a)}function ryr(e,t,r,n){if(n.overwrite)return p_.unlinkSync(r),VNe(e,t,r,n);if(n.errorOnExist)throw new Error(`'${r}' already exists`)}function VNe(e,t,r,n){return p_.copyFileSync(t,r),n.preserveTimestamps&&nyr(e.mode,t,r),Rle(r,e.mode)}function nyr(e,t,r){return iyr(e)&&ayr(r,e),syr(t,r)}function iyr(e){return(e&128)===0}function ayr(e,t){return Rle(e,t|128)}function Rle(e,t){return p_.chmodSync(e,t)}function syr(e,t){let r=p_.statSync(e);return Z2r(t,r.atime,r.mtime)}function oyr(e,t,r,n,a){return t?JNe(r,n,a):uyr(e.mode,r,n,a)}function uyr(e,t,r,n){return p_.mkdirSync(r),JNe(t,r,n),Rle(r,e)}function JNe(e,t,r){let n=p_.opendirSync(e);try{let a;for(;(a=n.readSync())!==null;)cyr(a.name,e,t,r)}finally{n.closeSync()}}function cyr(e,t,r,n){let a=SI.join(t,e),s=SI.join(r,e);if(n.filter&&!n.filter(a,s))return;let{destStat:u}=wI.checkPathsSync(a,s,"copy",n);return $Ne(u,a,s,n)}function lyr(e,t,r,n){let a=p_.readlinkSync(t);if(n.dereference&&(a=SI.resolve(process.cwd(),a)),e){let s;try{s=p_.readlinkSync(r)}catch(u){if(u.code==="EINVAL"||u.code==="UNKNOWN")return p_.symlinkSync(a,r);throw u}if(n.dereference&&(s=SI.resolve(process.cwd(),s)),wI.isSrcSubdir(a,s))throw new Error(`Cannot copy '${a}' to a subdirectory of itself, '${s}'.`);if(wI.isSrcSubdir(s,a))throw new Error(`Cannot overwrite '${s}' with '${a}'.`);return pyr(a,r)}else return p_.symlinkSync(a,r)}function pyr(e,t){return p_.unlinkSync(t),p_.symlinkSync(e,t)}zNe.exports=eyr});var oV=Za((x4r,HNe)=>{"use strict";var _yr=Jl().fromPromise;HNe.exports={copy:_yr(UNe()),copySync:WNe()}});var kI=Za((b4r,GNe)=>{"use strict";var KNe=n5(),dyr=Jl().fromCallback;function fyr(e,t){KNe.rm(e,{recursive:!0,force:!0},t)}function hyr(e){KNe.rmSync(e,{recursive:!0,force:!0})}GNe.exports={remove:dyr(fyr),removeSync:hyr}});var nIe=Za((D4r,rIe)=>{"use strict";var myr=Jl().fromPromise,QNe=l_(),ZNe=require("path"),eIe=em(),tIe=kI(),XNe=myr(async function(t){let r;try{r=await QNe.readdir(t)}catch{return eIe.mkdirs(t)}return Promise.all(r.map(n=>tIe.remove(ZNe.join(t,n))))});function YNe(e){let t;try{t=QNe.readdirSync(e)}catch{return eIe.mkdirsSync(e)}t.forEach(r=>{r=ZNe.join(e,r),tIe.removeSync(r)})}rIe.exports={emptyDirSync:YNe,emptydirSync:YNe,emptyDir:XNe,emptydir:XNe}});var oIe=Za((E4r,sIe)=>{"use strict";var yyr=Jl().fromPromise,iIe=require("path"),ID=l_(),aIe=em();async function gyr(e){let t;try{t=await ID.stat(e)}catch{}if(t&&t.isFile())return;let r=iIe.dirname(e),n=null;try{n=await ID.stat(r)}catch(a){if(a.code==="ENOENT"){await aIe.mkdirs(r),await ID.writeFile(e,"");return}else throw a}n.isDirectory()?await ID.writeFile(e,""):await ID.readdir(r)}function vyr(e){let t;try{t=ID.statSync(e)}catch{}if(t&&t.isFile())return;let r=iIe.dirname(e);try{ID.statSync(r).isDirectory()||ID.readdirSync(r)}catch(n){if(n&&n.code==="ENOENT")aIe.mkdirsSync(r);else throw n}ID.writeFileSync(e,"")}sIe.exports={createFile:yyr(gyr),createFileSync:vyr}});var _Ie=Za((A4r,pIe)=>{"use strict";var xyr=Jl().fromPromise,uIe=require("path"),S4=l_(),cIe=em(),{pathExists:byr}=T4(),{areIdentical:lIe}=pT();async function Dyr(e,t){let r;try{r=await S4.lstat(t)}catch{}let n;try{n=await S4.lstat(e)}catch(u){throw u.message=u.message.replace("lstat","ensureLink"),u}if(r&&lIe(n,r))return;let a=uIe.dirname(t);await byr(a)||await cIe.mkdirs(a),await S4.link(e,t)}function Eyr(e,t){let r;try{r=S4.lstatSync(t)}catch{}try{let s=S4.lstatSync(e);if(r&&lIe(s,r))return}catch(s){throw s.message=s.message.replace("lstat","ensureLink"),s}let n=uIe.dirname(t);return S4.existsSync(n)||cIe.mkdirsSync(n),S4.linkSync(e,t)}pIe.exports={createLink:xyr(Dyr),createLinkSync:Eyr}});var fIe=Za((C4r,dIe)=>{"use strict";var w4=require("path"),FI=l_(),{pathExists:Ayr}=T4(),Cyr=Jl().fromPromise;async function Tyr(e,t){if(w4.isAbsolute(e)){try{await FI.lstat(e)}catch(s){throw s.message=s.message.replace("lstat","ensureSymlink"),s}return{toCwd:e,toDst:e}}let r=w4.dirname(t),n=w4.join(r,e);if(await Ayr(n))return{toCwd:n,toDst:e};try{await FI.lstat(e)}catch(s){throw s.message=s.message.replace("lstat","ensureSymlink"),s}return{toCwd:e,toDst:w4.relative(r,e)}}function Syr(e,t){if(w4.isAbsolute(e)){if(!FI.existsSync(e))throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}let r=w4.dirname(t),n=w4.join(r,e);if(FI.existsSync(n))return{toCwd:n,toDst:e};if(!FI.existsSync(e))throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:w4.relative(r,e)}}dIe.exports={symlinkPaths:Cyr(Tyr),symlinkPathsSync:Syr}});var yIe=Za((T4r,mIe)=>{"use strict";var hIe=l_(),wyr=Jl().fromPromise;async function kyr(e,t){if(t)return t;let r;try{r=await hIe.lstat(e)}catch{return"file"}return r&&r.isDirectory()?"dir":"file"}function Fyr(e,t){if(t)return t;let r;try{r=hIe.lstatSync(e)}catch{return"file"}return r&&r.isDirectory()?"dir":"file"}mIe.exports={symlinkType:wyr(kyr),symlinkTypeSync:Fyr}});var bIe=Za((S4r,xIe)=>{"use strict";var Pyr=Jl().fromPromise,gIe=require("path"),ax=l_(),{mkdirs:Nyr,mkdirsSync:Iyr}=em(),{symlinkPaths:Byr,symlinkPathsSync:Oyr}=fIe(),{symlinkType:Lyr,symlinkTypeSync:Myr}=yIe(),{pathExists:Ryr}=T4(),{areIdentical:vIe}=pT();async function jyr(e,t,r){let n;try{n=await ax.lstat(t)}catch{}if(n&&n.isSymbolicLink()){let[c,l]=await Promise.all([ax.stat(e),ax.stat(t)]);if(vIe(c,l))return}let a=await Byr(e,t);e=a.toDst;let s=await Lyr(a.toCwd,r),u=gIe.dirname(t);return await Ryr(u)||await Nyr(u),ax.symlink(e,t,s)}function qyr(e,t,r){let n;try{n=ax.lstatSync(t)}catch{}if(n&&n.isSymbolicLink()){let c=ax.statSync(e),l=ax.statSync(t);if(vIe(c,l))return}let a=Oyr(e,t);e=a.toDst,r=Myr(a.toCwd,r);let s=gIe.dirname(t);return ax.existsSync(s)||Iyr(s),ax.symlinkSync(e,t,r)}xIe.exports={createSymlink:Pyr(jyr),createSymlinkSync:qyr}});var kIe=Za((w4r,wIe)=>{"use strict";var{createFile:DIe,createFileSync:EIe}=oIe(),{createLink:AIe,createLinkSync:CIe}=_Ie(),{createSymlink:TIe,createSymlinkSync:SIe}=bIe();wIe.exports={createFile:DIe,createFileSync:EIe,ensureFile:DIe,ensureFileSync:EIe,createLink:AIe,createLinkSync:CIe,ensureLink:AIe,ensureLinkSync:CIe,createSymlink:TIe,createSymlinkSync:SIe,ensureSymlink:TIe,ensureSymlinkSync:SIe}});var uV=Za((k4r,FIe)=>{function Uyr(e,{EOL:t=`
|
|
590
590
|
`,finalEOL:r=!0,replacer:n=null,spaces:a}={}){let s=r?t:"";return JSON.stringify(e,n,a).replace(/\n/g,t)+s}function $yr(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}FIe.exports={stringify:Uyr,stripBom:$yr}});var BIe=Za((F4r,IIe)=>{var s5;try{s5=n5()}catch{s5=require("fs")}var cV=Jl(),{stringify:PIe,stripBom:NIe}=uV();async function Vyr(e,t={}){typeof t=="string"&&(t={encoding:t});let r=t.fs||s5,n="throws"in t?t.throws:!0,a=await cV.fromCallback(r.readFile)(e,t);a=NIe(a);let s;try{s=JSON.parse(a,t?t.reviver:null)}catch(u){if(n)throw u.message=`${e}: ${u.message}`,u;return null}return s}var Jyr=cV.fromPromise(Vyr);function zyr(e,t={}){typeof t=="string"&&(t={encoding:t});let r=t.fs||s5,n="throws"in t?t.throws:!0;try{let a=r.readFileSync(e,t);return a=NIe(a),JSON.parse(a,t.reviver)}catch(a){if(n)throw a.message=`${e}: ${a.message}`,a;return null}}async function Wyr(e,t,r={}){let n=r.fs||s5,a=PIe(t,r);await cV.fromCallback(n.writeFile)(e,a,r)}var Hyr=cV.fromPromise(Wyr);function Kyr(e,t,r={}){let n=r.fs||s5,a=PIe(t,r);return n.writeFileSync(e,a,r)}IIe.exports={readFile:Jyr,readFileSync:zyr,writeFile:Hyr,writeFileSync:Kyr}});var LIe=Za((P4r,OIe)=>{"use strict";var lV=BIe();OIe.exports={readJson:lV.readFile,readJsonSync:lV.readFileSync,writeJson:lV.writeFile,writeJsonSync:lV.writeFileSync}});var pV=Za((N4r,jIe)=>{"use strict";var Gyr=Jl().fromPromise,jle=l_(),MIe=require("path"),RIe=em(),Xyr=T4().pathExists;async function Yyr(e,t,r="utf-8"){let n=MIe.dirname(e);return await Xyr(n)||await RIe.mkdirs(n),jle.writeFile(e,t,r)}function Qyr(e,...t){let r=MIe.dirname(e);jle.existsSync(r)||RIe.mkdirsSync(r),jle.writeFileSync(e,...t)}jIe.exports={outputFile:Gyr(Yyr),outputFileSync:Qyr}});var UIe=Za((I4r,qIe)=>{"use strict";var{stringify:Zyr}=uV(),{outputFile:egr}=pV();async function tgr(e,t,r={}){let n=Zyr(t,r);await egr(e,n,r)}qIe.exports=tgr});var VIe=Za((B4r,$Ie)=>{"use strict";var{stringify:rgr}=uV(),{outputFileSync:ngr}=pV();function igr(e,t,r){let n=rgr(t,r);ngr(e,n,r)}$Ie.exports=igr});var zIe=Za((O4r,JIe)=>{"use strict";var agr=Jl().fromPromise,__=LIe();__.outputJson=agr(UIe());__.outputJsonSync=VIe();__.outputJSON=__.outputJson;__.outputJSONSync=__.outputJsonSync;__.writeJSON=__.writeJson;__.writeJSONSync=__.writeJsonSync;__.readJSON=__.readJson;__.readJSONSync=__.readJsonSync;JIe.exports=__});var XIe=Za((L4r,GIe)=>{"use strict";var sgr=l_(),WIe=require("path"),{copy:ogr}=oV(),{remove:KIe}=kI(),{mkdirp:ugr}=em(),{pathExists:cgr}=T4(),HIe=pT();async function lgr(e,t,r={}){let n=r.overwrite||r.clobber||!1,{srcStat:a,isChangingCase:s=!1}=await HIe.checkPaths(e,t,"move",r);await HIe.checkParentPaths(e,a,t,"move");let u=WIe.dirname(t);return WIe.parse(u).root!==u&&await ugr(u),pgr(e,t,n,s)}async function pgr(e,t,r,n){if(!n){if(r)await KIe(t);else if(await cgr(t))throw new Error("dest already exists.")}try{await sgr.rename(e,t)}catch(a){if(a.code!=="EXDEV")throw a;await _gr(e,t,r)}}async function _gr(e,t,r){return await ogr(e,t,{overwrite:r,errorOnExist:!0,preserveTimestamps:!0}),KIe(e)}GIe.exports=lgr});var tBe=Za((M4r,eBe)=>{"use strict";var QIe=n5(),Ule=require("path"),dgr=oV().copySync,ZIe=kI().removeSync,fgr=em().mkdirpSync,YIe=pT();function hgr(e,t,r){r=r||{};let n=r.overwrite||r.clobber||!1,{srcStat:a,isChangingCase:s=!1}=YIe.checkPathsSync(e,t,"move",r);return YIe.checkParentPathsSync(e,a,t,"move"),mgr(t)||fgr(Ule.dirname(t)),ygr(e,t,n,s)}function mgr(e){let t=Ule.dirname(e);return Ule.parse(t).root===t}function ygr(e,t,r,n){if(n)return qle(e,t,r);if(r)return ZIe(t),qle(e,t,r);if(QIe.existsSync(t))throw new Error("dest already exists.");return qle(e,t,r)}function qle(e,t,r){try{QIe.renameSync(e,t)}catch(n){if(n.code!=="EXDEV")throw n;return ggr(e,t,r)}}function ggr(e,t,r){return dgr(e,t,{overwrite:r,errorOnExist:!0,preserveTimestamps:!0}),ZIe(e)}eBe.exports=hgr});var nBe=Za((R4r,rBe)=>{"use strict";var vgr=Jl().fromPromise;rBe.exports={move:vgr(XIe()),moveSync:tBe()}});var aBe=Za((j4r,iBe)=>{"use strict";iBe.exports={...l_(),...oV(),...nIe(),...kIe(),...zIe(),...em(),...nBe(),...pV(),...T4(),...kI()}});var sBe=Za(_V=>{"use strict";Object.defineProperty(_V,"__esModule",{value:!0});_V.EXTENSIONS_LANGUAGES=void 0;_V.EXTENSIONS_LANGUAGES={1:"Groff",2:"Groff",3:"Groff",4:"Groff",5:"Groff",6:"Groff",7:"Groff",8:"Groff",9:"Groff",abap:"ABAP",asc:"Public Key",ash:"AGS Script",ampl:"AMPL",mod:"XML",g4:"ANTLR",apib:"API Blueprint",apl:"APL",dyalog:"APL",asp:"ASP",asax:"ASP",ascx:"ASP",ashx:"ASP",asmx:"ASP",aspx:"ASP",axd:"ASP",dats:"ATS",hats:"ATS",sats:"ATS",as:"ActionScript",adb:"Ada",ada:"Ada",ads:"Ada",agda:"Agda",als:"Alloy",apacheconf:"ApacheConf",vhost:"Nginx",cls:"Visual Basic",applescript:"AppleScript",scpt:"AppleScript",arc:"Arc",ino:"Arduino",asciidoc:"AsciiDoc",adoc:"AsciiDoc",aj:"AspectJ",asm:"Assembly",a51:"Assembly",inc:"SourcePawn",nasm:"Assembly",aug:"Augeas",ahk:"AutoHotkey",ahkl:"AutoHotkey",au3:"AutoIt",awk:"Awk",auk:"Awk",gawk:"Awk",mawk:"Awk",nawk:"Awk",bat:"Batchfile",cmd:"Batchfile",befunge:"Befunge",bison:"Bison",bb:"BlitzBasic",decls:"BlitzBasic",bmx:"BlitzMax",bsv:"Bluespec",boo:"Boo",b:"Limbo",bf:"HyPhy",brs:"Brightscript",bro:"Bro",c:"C",cats:"C",h:"Objective-C",idc:"C",w:"C",cs:"Smalltalk",cake:"CoffeeScript",cshtml:"C#",csx:"C#",cpp:"C++","c++":"C++",cc:"C++",cp:"Component Pascal",cxx:"C++","h++":"C++",hh:"Hack",hpp:"C++",hxx:"C++",inl:"C++",ipp:"C++",tcc:"C++",tpp:"C++","c-objdump":"C-ObjDump",chs:"C2hs Haskell",clp:"CLIPS",cmake:"CMake","cmake.in":"CMake",cob:"COBOL",cbl:"COBOL",ccp:"COBOL",cobol:"COBOL",cpy:"COBOL",css:"CSS",csv:"CSV",capnp:"Cap'n Proto",mss:"CartoCSS",ceylon:"Ceylon",chpl:"Chapel",ch:"xBase",ck:"ChucK",cirru:"Cirru",clw:"Clarion",icl:"Clean",dcl:"Clean",click:"Click",clj:"Clojure",boot:"Clojure",cl2:"Clojure",cljc:"Clojure",cljs:"Clojure","cljs.hl":"Clojure",cljscm:"Clojure",cljx:"Clojure",hic:"Clojure",coffee:"CoffeeScript",_coffee:"CoffeeScript",cjsx:"CoffeeScript",cson:"CoffeeScript",iced:"CoffeeScript",cfm:"ColdFusion",cfml:"ColdFusion",cfc:"ColdFusion CFC",lisp:"NewLisp",asd:"Common Lisp",cl:"OpenCL",l:"PicoLisp",lsp:"NewLisp",ny:"Common Lisp",podsl:"Common Lisp",sexp:"Common Lisp",cps:"Component Pascal",coq:"Coq",v:"Verilog",cppobjdump:"Cpp-ObjDump","c++-objdump":"Cpp-ObjDump","c++objdump":"Cpp-ObjDump","cpp-objdump":"Cpp-ObjDump","cxx-objdump":"Cpp-ObjDump",creole:"Creole",cr:"Crystal",feature:"Cucumber",cu:"Cuda",cuh:"Cuda",cy:"Cycript",pyx:"Cython",pxd:"Cython",pxi:"Cython",d:"Makefile",di:"D","d-objdump":"D-ObjDump",com:"DIGITAL Command Language",dm:"DM",zone:"DNS Zone",arpa:"DNS Zone",darcspatch:"Darcs Patch",dpatch:"Darcs Patch",dart:"Dart",diff:"Diff",patch:"Diff",dockerfile:"Dockerfile",djs:"Dogescript",dylan:"Dylan",dyl:"Dylan",intr:"Dylan",lid:"Dylan",E:"E",ecl:"ECLiPSe",eclxml:"ECL",sch:"KiCad",brd:"KiCad",epj:"Ecere Projects",e:"Eiffel",ex:"Elixir",exs:"Elixir",elm:"Elm",el:"Emacs Lisp",emacs:"Emacs Lisp","emacs.desktop":"Emacs Lisp",em:"EmberScript",emberscript:"EmberScript",erl:"Erlang",es:"JavaScript",escript:"Erlang",hrl:"Erlang",xrl:"Erlang",yrl:"Erlang",fs:"GLSL",fsi:"F#",fsx:"F#",fx:"HLSL",flux:"FLUX",f90:"FORTRAN",f:"Forth",f03:"FORTRAN",f08:"FORTRAN",f77:"FORTRAN",f95:"FORTRAN",for:"Forth",fpp:"FORTRAN",factor:"Factor",fy:"Fancy",fancypack:"Fancy",fan:"Fantom","eam.fs":"Formatted",fth:"Forth","4th":"Forth",forth:"Forth",fr:"Text",frt:"Forth",ftl:"FreeMarker",g:"GAP",gco:"G-code",gcode:"G-code",gms:"GAMS",gap:"GAP",gd:"GDScript",gi:"GAP",tst:"Scilab",s:"GAS",ms:"MAXScript",glsl:"GLSL",fp:"GLSL",frag:"JavaScript",frg:"GLSL",fsh:"GLSL",fshader:"GLSL",geo:"GLSL",geom:"GLSL",glslv:"GLSL",gshader:"GLSL",shader:"GLSL",vert:"GLSL",vrx:"GLSL",vsh:"GLSL",vshader:"GLSL",gml:"XML",kid:"Genshi",ebuild:"Gentoo Ebuild",eclass:"Gentoo Eclass",po:"Gettext Catalog",pot:"Gettext Catalog",glf:"Glyph",gp:"Gnuplot",gnu:"Gnuplot",gnuplot:"Gnuplot",plot:"Gnuplot",plt:"Gnuplot",go:"Go",golo:"Golo",gs:"JavaScript",gst:"Gosu",gsx:"Gosu",vark:"Gosu",grace:"Grace",gradle:"Gradle",gf:"Grammatical Framework",graphql:"GraphQL",dot:"Graphviz (DOT)",gv:"Graphviz (DOT)",man:"Groff","1in":"Groff","1m":"Groff","1x":"Groff","3in":"Groff","3m":"Groff","3qt":"Groff","3x":"Groff",me:"Groff",n:"Nemerle",rno:"Groff",roff:"Groff",groovy:"Groovy",grt:"Groovy",gtpl:"Groovy",gvy:"Groovy",gsp:"Groovy Server Pages",hcl:"HCL",tf:"HCL",hlsl:"HLSL",fxh:"HLSL",hlsli:"HLSL",html:"HTML",htm:"HTML","html.hl":"HTML",st:"Smalltalk",xht:"HTML",xhtml:"HTML",mustache:"HTML+Django",jinja:"HTML+Django",eex:"HTML+EEX",erb:"HTML+ERB","erb.deface":"HTML+ERB",phtml:"HTML+PHP",http:"HTTP",php:"PHP",haml:"Haml","haml.deface":"Haml",handlebars:"Handlebars",hbs:"Handlebars",hb:"Harbour",hs:"Haskell",hsc:"Haskell",hx:"Haxe",hxsl:"Haxe",hy:"Hy",pro:"QMake",dlm:"IDL",ipf:"IGOR Pro",ini:"INI",cfg:"INI",prefs:"INI",properties:"INI",irclog:"IRC log",weechatlog:"IRC log",idr:"Idris",lidr:"Idris",ni:"Inform 7",i7x:"Inform 7",iss:"Inno Setup",io:"Io",ik:"Ioke",thy:"Isabelle",ijs:"J",flex:"JFlex",jflex:"JFlex",json:"JSON",geojson:"JSON",lock:"JSON",topojson:"JSON",json5:"JSON5",jsonld:"JSONLD",jq:"JSONiq",jsx:"JSX",jade:"Jade",j:"Objective-J",java:"Java",jsp:"Java Server Pages",js:"JavaScript",_js:"JavaScript",bones:"JavaScript",es6:"JavaScript",jake:"JavaScript",jsb:"JavaScript",jscad:"JavaScript",jsfl:"JavaScript",jsm:"JavaScript",jss:"JavaScript",njs:"JavaScript",pac:"JavaScript",sjs:"JavaScript",ssjs:"JavaScript","sublime-build":"JavaScript","sublime-commands":"JavaScript","sublime-completions":"JavaScript","sublime-keymap":"JavaScript","sublime-macro":"JavaScript","sublime-menu":"JavaScript","sublime-mousemap":"JavaScript","sublime-project":"JavaScript","sublime-settings":"JavaScript","sublime-theme":"JavaScript","sublime-workspace":"JavaScript",sublime_metrics:"JavaScript",sublime_session:"JavaScript",xsjs:"JavaScript",xsjslib:"JavaScript",jl:"Julia",ipynb:"Jupyter Notebook",krl:"KRL",kicad_pcb:"KiCad",kit:"Kit",kt:"Kotlin",ktm:"Kotlin",kts:"Kotlin",lfe:"LFE",ll:"LLVM",lol:"LOLCODE",lsl:"LSL",lslp:"LSL",lvproj:"LabVIEW",lasso:"Lasso",las:"Lasso",lasso8:"Lasso",lasso9:"Lasso",ldml:"Lasso",latte:"Latte",lean:"Lean",hlean:"Lean",less:"Less",lex:"Lex",ly:"LilyPond",ily:"LilyPond",m:"Objective-C",ld:"Linker Script",lds:"Linker Script",liquid:"Liquid",lagda:"Literate Agda",litcoffee:"Literate CoffeeScript",lhs:"Literate Haskell",ls:"LoomScript",_ls:"LiveScript",xm:"Logos",x:"Logos",xi:"Logos",lgt:"Logtalk",logtalk:"Logtalk",lookml:"LookML",lua:"Lua",fcgi:"Shell",nse:"Lua",pd_lua:"Lua",rbxs:"Lua",wlua:"Lua",mumps:"M",m4:"M4Sugar",mcr:"MAXScript",mtml:"MTML",muf:"MUF",mak:"Makefile",mk:"Makefile",mkfile:"Makefile",mako:"Mako",mao:"Mako",md:"Markdown",markdown:"Markdown",mkd:"Markdown",mkdn:"Markdown",mkdown:"Markdown",ron:"Markdown",mask:"Mask",mathematica:"Mathematica",cdf:"Mathematica",ma:"Mathematica",mt:"Mathematica",nb:"Text",nbp:"Mathematica",wl:"Mathematica",wlt:"Mathematica",matlab:"Matlab",maxpat:"Max",maxhelp:"Max",maxproj:"Max",mxt:"Max",pat:"Max",mediawiki:"MediaWiki",wiki:"MediaWiki",moo:"Moocode",metal:"Metal",minid:"MiniD",druby:"Mirah",duby:"Mirah",mir:"Mirah",mirah:"Mirah",mo:"Modelica",mms:"Module Management System",mmk:"Module Management System",monkey:"Monkey",moon:"MoonScript",myt:"Myghty",ncl:"Text",nl:"NewLisp",nsi:"NSIS",nsh:"NSIS",axs:"NetLinx",axi:"NetLinx","axs.erb":"NetLinx+ERB","axi.erb":"NetLinx+ERB",nlogo:"NetLogo",nginxconf:"Nginx",nim:"Nimrod",nimrod:"Nimrod",ninja:"Ninja",nit:"Nit",nix:"Nix",nu:"Nu",numpy:"NumPy",numpyw:"NumPy",numsc:"NumPy",ml:"OCaml",eliom:"OCaml",eliomi:"OCaml",ml4:"OCaml",mli:"OCaml",mll:"OCaml",mly:"OCaml",objdump:"ObjDump",mm:"XML",sj:"Objective-J",omgrofl:"Omgrofl",opa:"Opa",opal:"Opal",opencl:"OpenCL",p:"OpenEdge ABL",scad:"OpenSCAD",org:"Org",ox:"Ox",oxh:"Ox",oxo:"Ox",oxygene:"Oxygene",oz:"Oz",pwn:"PAWN",aw:"PHP",ctp:"PHP",php3:"PHP",php4:"PHP",php5:"PHP",phps:"PHP",phpt:"PHP",pls:"PLSQL",pck:"PLSQL",pkb:"PLSQL",pks:"PLSQL",plb:"PLSQL",plsql:"PLSQL",sql:"SQLPL",pov:"POV-Ray SDL",pan:"Pan",psc:"Papyrus",parrot:"Parrot",pasm:"Parrot Assembly",pir:"Parrot Internal Representation",pas:"Pascal",dfm:"Pascal",dpr:"Pascal",lpr:"Pascal",pp:"Puppet",pl:"Prolog",al:"Perl",cgi:"Shell",perl:"Perl",ph:"Perl",plx:"Perl",pm:"Perl6",pod:"Pod",psgi:"Perl",t:"Turing","6pl":"Perl6","6pm":"Perl6",nqp:"Perl6",p6:"Perl6",p6l:"Perl6",p6m:"Perl6",pl6:"Perl6",pm6:"Perl6",pkl:"Pickle",pig:"PigLatin",pike:"Pike",pmod:"Pike",pogo:"PogoScript",pony:"Pony",ps:"PostScript",eps:"PostScript",ps1:"PowerShell",psd1:"PowerShell",psm1:"PowerShell",pde:"Processing",prolog:"Prolog",yap:"Prolog",spin:"Propeller Spin",proto:"Protocol Buffer",pub:"Public Key",pd:"Pure Data",pb:"PureBasic",pbi:"PureBasic",purs:"PureScript",py:"Python",bzl:"Python",gyp:"Python",lmi:"Python",pyde:"Python",pyp:"Python",pyt:"Python",pyw:"Python",rpy:"Ren'Py",tac:"Python",wsgi:"Python",xpy:"Python",pytb:"Python traceback",qml:"QML",qbs:"QML",pri:"QMake",r:"Rebol",rd:"R",rsx:"R",raml:"RAML",rdoc:"RDoc",rbbas:"REALbasic",rbfrm:"REALbasic",rbmnu:"REALbasic",rbres:"REALbasic",rbtbar:"REALbasic",rbuistate:"REALbasic",rhtml:"RHTML",rmd:"RMarkdown",rkt:"Racket",rktd:"Racket",rktl:"Racket",scrbl:"Racket",rl:"Ragel in Ruby Host",raw:"Raw token data",reb:"Rebol",r2:"Rebol",r3:"Rebol",rebol:"Rebol",red:"Red",reds:"Red",cw:"Redcode",rs:"Rust",rsh:"RenderScript",robot:"RobotFramework",rg:"Rouge",rb:"Ruby",builder:"Ruby",gemspec:"Ruby",god:"Ruby",irbrc:"Ruby",jbuilder:"Ruby",mspec:"Ruby",pluginspec:"XML",podspec:"Ruby",rabl:"Ruby",rake:"Ruby",rbuild:"Ruby",rbw:"Ruby",rbx:"Ruby",ru:"Ruby",ruby:"Ruby",thor:"Ruby",watchr:"Ruby","rs.in":"Rust",sas:"SAS",scss:"SCSS",smt2:"SMT",smt:"SMT",sparql:"SPARQL",rq:"SPARQL",sqf:"SQF",hqf:"SQF",cql:"SQL",ddl:"SQL",prc:"SQL",tab:"SQL",udf:"SQL",viw:"SQL",db2:"SQLPL",ston:"STON",svg:"SVG",sage:"Sage",sagews:"Sage",sls:"Scheme",sass:"Sass",scala:"Scala",sbt:"Scala",sc:"SuperCollider",scaml:"Scaml",scm:"Scheme",sld:"Scheme",sps:"Scheme",ss:"Scheme",sci:"Scilab",sce:"Scilab",self:"Self",sh:"Shell",bash:"Shell",bats:"Shell",command:"Shell",ksh:"Shell","sh.in":"Shell",tmux:"Shell",tool:"Shell",zsh:"Shell","sh-session":"ShellSession",shen:"Shen",sl:"Slash",slim:"Slim",smali:"Smali",tpl:"Smarty",sp:"SourcePawn",sma:"SourcePawn",nut:"Squirrel",stan:"Stan",ML:"Standard ML",fun:"Standard ML",sig:"Standard ML",sml:"Standard ML",do:"Stata",ado:"Stata",doh:"Stata",ihlp:"Stata",mata:"Stata",matah:"Stata",sthlp:"Stata",styl:"Stylus",scd:"SuperCollider",swift:"Swift",sv:"SystemVerilog",svh:"SystemVerilog",vh:"SystemVerilog",toml:"TOML",txl:"TXL",tcl:"Tcl",adp:"Tcl",tm:"Tcl",tcsh:"Tcsh",csh:"Tcsh",tex:"TeX",aux:"TeX",bbx:"TeX",bib:"TeX",cbx:"TeX",dtx:"TeX",ins:"TeX",lbx:"TeX",ltx:"TeX",mkii:"TeX",mkiv:"TeX",mkvi:"TeX",sty:"TeX",toc:"TeX",tea:"Tea",txt:"Text",no:"Text",textile:"Textile",thrift:"Thrift",tu:"Turing",ttl:"Turtle",twig:"Twig",ts:"TypeScript",tsx:"TypeScript",upc:"Unified Parallel C",anim:"Unity3D Asset",asset:"Unity3D Asset",mat:"Unity3D Asset",meta:"Unity3D Asset",prefab:"Unity3D Asset",unity:"Unity3D Asset",uno:"Uno",uc:"UnrealScript",ur:"UrWeb",urs:"UrWeb",vcl:"VCL",vhdl:"VHDL",vhd:"VHDL",vhf:"VHDL",vhi:"VHDL",vho:"VHDL",vhs:"VHDL",vht:"VHDL",vhw:"VHDL",vala:"Vala",vapi:"Vala",veo:"Verilog",vim:"VimL",vb:"Visual Basic",bas:"Visual Basic",frm:"Visual Basic",frx:"Visual Basic",vba:"Visual Basic",vbhtml:"Visual Basic",vbs:"Visual Basic",volt:"Volt",vue:"Vue",owl:"Web Ontology Language",webidl:"WebIDL",x10:"X10",xc:"XC",xml:"XML",ant:"XML",axml:"XML",ccxml:"XML",clixml:"XML",cproject:"XML",csl:"XML",csproj:"XML",ct:"XML",dita:"XML",ditamap:"XML",ditaval:"XML","dll.config":"XML",dotsettings:"XML",filters:"XML",fsproj:"XML",fxml:"XML",glade:"XML",grxml:"XML",iml:"XML",ivy:"XML",jelly:"XML",jsproj:"XML",kml:"XML",launch:"XML",mdpolicy:"XML",mxml:"XML",nproj:"XML",nuspec:"XML",odd:"XML",osm:"XML",plist:"XML",props:"XML",ps1xml:"XML",psc1:"XML",pt:"XML",rdf:"XML",rss:"XML",scxml:"XML",srdf:"XML",storyboard:"XML",stTheme:"XML","sublime-snippet":"XML",targets:"XML",tmCommand:"XML",tml:"XML",tmLanguage:"XML",tmPreferences:"XML",tmSnippet:"XML",tmTheme:"XML",ui:"XML",urdf:"XML",ux:"XML",vbproj:"XML",vcxproj:"XML",vssettings:"XML",vxml:"XML",wsdl:"XML",wsf:"XML",wxi:"XML",wxl:"XML",wxs:"XML",x3d:"XML",xacro:"XML",xaml:"XML",xib:"XML",xlf:"XML",xliff:"XML",xmi:"XML","xml.dist":"XML",xproj:"XML",xsd:"XML",xul:"XML",zcml:"XML","xsp-config":"XPages","xsp.metadata":"XPages",xpl:"XProc",xproc:"XProc",xquery:"XQuery",xq:"XQuery",xql:"XQuery",xqm:"XQuery",xqy:"XQuery",xs:"XS",xslt:"XSLT",xsl:"XSLT",xojo_code:"Xojo",xojo_menu:"Xojo",xojo_report:"Xojo",xojo_script:"Xojo",xojo_toolbar:"Xojo",xojo_window:"Xojo",xtend:"Xtend",yml:"YAML",reek:"YAML",rviz:"YAML","sublime-syntax":"YAML",syntax:"YAML",yaml:"YAML","yaml-tmlanguage":"YAML",yang:"YANG",y:"Yacc",yacc:"Yacc",yy:"Yacc",zep:"Zephir",zimpl:"Zimpl",zmpl:"Zimpl",zpl:"Zimpl",desktop:"desktop","desktop.in":"desktop",ec:"eC",eh:"eC",edn:"edn",fish:"fish",mu:"mupad",nc:"nesC",ooc:"ooc",rst:"reStructuredText",rest:"reStructuredText","rest.txt":"reStructuredText","rst.txt":"reStructuredText",wisp:"wisp",prg:"xBase",prw:"xBase"}});var PI=Za($le=>{"use strict";Object.defineProperty($le,"__esModule",{value:!0});$le.setOptionValues=xgr;function xgr(e,t){for(let r of Object.keys(e))e[r]!==void 0&&(t[r]=e[r]);return t}});var uBe=Za(dV=>{"use strict";Object.defineProperty(dV,"__esModule",{value:!0});dV.SarifBuilder=void 0;var oBe=aBe(),bgr=sBe(),Dgr=PI(),Vle=class{constructor(t={}){this.log={$schema:"http://json.schemastore.org/sarif-2.1.0.json",version:"2.1.0",runs:[]},(0,Dgr.setOptionValues)(t,this.log)}addRun(t){this.log.runs.push(t.run)}generateSarifFileSync(t){let r=this.buildSarifJsonString();oBe.writeFileSync(t,r,"utf8")}async generateSarifFile(t){let r=this.buildSarifJsonString();await oBe.writeFile(t,r,"utf8")}buildSarifOutput(){return this.log.runs=this.log.runs.map(t=>this.completeRunFields(t)),this.log}buildSarifJsonString(t={indent:!1}){this.buildSarifOutput();let r=t.indent?JSON.stringify(this.log,null,2):JSON.stringify(this.log);if(r.includes("SARIF_BUILDER_INVALID"))throw new Error("Your SARIF log is invalid, please solve SARIF_BUILDER_INVALID messages");return r}completeRunFields(t){var r,n,a,s,u,c;t.artifacts=t.artifacts||[];let l=new Set(t.artifacts.map(f=>{var v;return(v=f?.location)===null||v===void 0?void 0:v.uri}).filter(Boolean));for(let f of t.results||[])for(let v of f.locations||[]){let b=(n=(r=v?.physicalLocation)===null||r===void 0?void 0:r.artifactLocation)===null||n===void 0?void 0:n.uri;if(b&&!l.has(b)){let D=b.lastIndexOf("."),S=D!==-1?b.slice(D+1):"",L=bgr.EXTENSIONS_LANGUAGES[S]||"unknown";t.artifacts.push({sourceLanguage:L,location:{uri:b}}),l.add(b)}}let d=new Map;t.artifacts.forEach((f,v)=>{var b;let D=(b=f?.location)===null||b===void 0?void 0:b.uri;D&&d.set(D,v)});let _=new Map;(((s=(a=t?.tool)===null||a===void 0?void 0:a.driver)===null||s===void 0?void 0:s.rules)||[]).forEach((f,v)=>{_.set(f.id,v)});for(let f of t.results||[]){let v=_.get(f.ruleId);if(v!==void 0&&(f.ruleIndex=v),f.locations)for(let b of f.locations){let D=(c=(u=b?.physicalLocation)===null||u===void 0?void 0:u.artifactLocation)===null||c===void 0?void 0:c.uri;if(D){let S=d.get(D);S!==void 0&&(b.physicalLocation.artifactLocation.index=S)}}}return t}};dV.SarifBuilder=Vle});var cBe=Za(fV=>{"use strict";Object.defineProperty(fV,"__esModule",{value:!0});fV.SarifResultBuilder=void 0;var Egr=PI(),Jle=class{constructor(t={}){this.result={level:"error",message:{},ruleId:"SARIF_BUILDER_INVALID: Please send the rule Id ruleId property, or call setRuleId(ruleId)"},(0,Egr.setOptionValues)(t,this.result)}initSimple(t){if(this.setLevel(t.level),this.setMessageText(t.messageText),this.setRuleId(t.ruleId),t.fileUri&&this.setLocationArtifactUri({uri:t.fileUri}),t.startLine!==null&&t.startLine!==void 0){let r={startLine:t.startLine,startColumn:t.startColumn||1,endLine:t.endLine||t.startLine,endColumn:t.endColumn||1};if(t.startLine===0||t.startColumn===0||t.endLine===0||t.endColumn===0)throw new Error("Region limit can not be 0 (minimum line 1 or column 1) in "+JSON.stringify(t));this.setLocationRegion(r)}return this}setLevel(t){this.result.level=t}setMessageText(t){this.result.message.text=t}setRuleId(t){this.result.ruleId=t}setLocationRegion(t){this.manageInitPhysicalLocation(),this.result.locations[0].physicalLocation.region=t}setLocationArtifactUri(t){this.manageInitPhysicalLocation(),this.result.locations[0].physicalLocation.artifactLocation=t}manageInitLocation(){var t,r;!((r=(t=this.result)===null||t===void 0?void 0:t.locations)===null||r===void 0)&&r.length||(this.result.locations=[{}])}manageInitPhysicalLocation(){var t;this.manageInitLocation(),!(!((t=this.result)===null||t===void 0)&&t.locations[0].physicalLocation)&&(this.result.locations[0].physicalLocation={})}};fV.SarifResultBuilder=Jle});var lBe=Za(hV=>{"use strict";Object.defineProperty(hV,"__esModule",{value:!0});hV.SarifRuleBuilder=void 0;var Agr=PI(),zle=class{constructor(t={}){this.rule={id:"SARIF_BUILDER_INVALID: Please send the rule identifier in id property, or call setRuleId(ruleId)",shortDescription:{text:"SARIF_BUILDER_INVALID: Please send the rule text in shortDescription.text property, or call setShortDescriptionText(text)"}},(0,Agr.setOptionValues)(t,this.rule)}initSimple(t){return this.setRuleId(t.ruleId),t.shortDescriptionText&&this.setShortDescriptionText(t.shortDescriptionText),t.fullDescriptionText&&this.setFullDescriptionText(t.fullDescriptionText),t.helpUri&&this.setHelpUri(t.helpUri),this}setRuleId(t){this.rule.id=t}setShortDescriptionText(t){this.rule.shortDescription.text=t}setFullDescriptionText(t){this.rule.fullDescription=this.rule.fullDescription||{text:""},this.rule.fullDescription.text=t}setHelpUri(t){this.rule.helpUri=t}};hV.SarifRuleBuilder=zle});var pBe=Za(mV=>{"use strict";Object.defineProperty(mV,"__esModule",{value:!0});mV.SarifRunBuilder=void 0;var Cgr=PI(),Wle=class{constructor(t={}){this.run={tool:{driver:{name:process.env.npm_package_name||"SARIF_BUILDER_INVALID: Please send the tool name in tool.driver.name property, or call setToolName(name)",rules:[]}},results:[]},(0,Cgr.setOptionValues)(t,this.run)}initSimple(t){return this.setToolDriverName(t.toolDriverName),this.setToolDriverVersion(t.toolDriverVersion),t.url&&this.setToolDriverUri(t.url),this}addRule(t){this.run.tool.driver.rules.push(t.rule)}addResult(t){this.run.results.push(t.result)}setToolDriverName(t){this.run.tool.driver.name=t}setToolDriverVersion(t){this.run.tool.driver.version=t}setToolDriverUri(t){this.run.tool.driver.informationUri=t}};mV.SarifRunBuilder=Wle});var _Be=Za(sx=>{"use strict";Object.defineProperty(sx,"__esModule",{value:!0});sx.SarifResultBuilder=sx.SarifRuleBuilder=sx.SarifRunBuilder=sx.SarifBuilder=void 0;var Tgr=uBe();Object.defineProperty(sx,"SarifBuilder",{enumerable:!0,get:function(){return Tgr.SarifBuilder}});var Sgr=cBe();Object.defineProperty(sx,"SarifResultBuilder",{enumerable:!0,get:function(){return Sgr.SarifResultBuilder}});var wgr=lBe();Object.defineProperty(sx,"SarifRuleBuilder",{enumerable:!0,get:function(){return wgr.SarifRuleBuilder}});var kgr=pBe();Object.defineProperty(sx,"SarifRunBuilder",{enumerable:!0,get:function(){return kgr.SarifRunBuilder}})});var fBe=Za((H4r,dBe)=>{"use strict";var Fgr=/["'&<>]/;dBe.exports=Pgr;function Pgr(e){var t=""+e,r=Fgr.exec(t);if(!r)return t;var n,a="",s=0,u=0;for(s=r.index;s<t.length;s++){switch(t.charCodeAt(s)){case 34:n=""";break;case 38:n="&";break;case 39:n="'";break;case 60:n="<";break;case 62:n=">";break;default:continue}u!==s&&(a+=t.substring(u,s)),u=s+1,a+=n}return u!==s?a+t.substring(u,s):a}});var wV=require("zx"),_T=require("fs/promises");var Vd={UNKNOWN:0,LOW:1,MEDIUM:2,HIGH:3,CRITICAL:4};var JR=class{constructor(t){this.depProvider=t}allById=new Map;getAllVulnIds(){return new Set(this.allById.keys())}getAllVulnerabilitiesSortedBySeverity(){let t=Array.from(this.allById.values());return t.sort((r,n)=>{let a=pye(r.severity,n.severity);return a===0?r.id.localeCompare(n.id):-a}),t}addVulnerability(t,r){let n=t.id,a=this.allById,s=t;if(!a.has(n))a.set(n,t),s=t;else{let u=a.get(n);u.title=u.title||t.title,u.severity=h3t(u.severity,t.severity),u.scannerSeverity[r]=t.severity,u.detectedBy=ite(u.detectedBy,r),u.components=ite(u.components,t.components[0]),u.refs=ite(u.refs,t.refs[0]),s=u}s.componentTree=s.components?.map(u=>this.depProvider.findUsagesOfComponent(u))}enhanceWithVexData(t){let r=[];for(let n of this.allById.values()){let a=t.newestVulnerabilityStatement(n.id);if(!a){r.push({id:n.id,severity:n.severity,title:n.title,description:n.description,components:n.components??[],componentTree:n.componentTree??[],refs:n.refs});continue}n.vexStatement=a}return{unmatchedVulnerabilities:r}}};function h3t(e,t){return pye(e,t)>0?e:t}function pye(e,t){return Vd[e]-Vd[t]}function ite(e,t){return t?Array.from(new Set([...e,t]).values()):e}var tV=Uo(require("path"));var hd=require("fs/promises"),Ele=require("path");async function uf(e){try{return await cT(e)?JSON.parse(await(0,hd.readFile)(e,{encoding:"utf-8"})):void 0}catch(t){throw new Error(`Error reading JSON file ${e}: ${t}`,{cause:t})}}async function Ale(e,t){let r=JSON.stringify(t,null,4)+`
|
|
591
|
-
`,n=await h2r(e,r);await(0,hd.writeFile)(e,n,{encoding:"utf-8"})}function Z1(e){return e?e.replace(/\?.*$/,""):""}async function cT(e){try{return await(0,hd.access)(e,hd.constants.F_OK),!0}catch{return!1}}async function Cle(e){let t=(0,Ele.resolve)(e),r=await(0,hd.readdir)(t,{withFileTypes:!0});for(let n of r){let a=(0,Ele.resolve)(n.parentPath,n.name);n.isDirectory()?await Cle(a):await(0,hd.rm)(a)}await(0,hd.rmdir)(t)}async function EI(e,t){let r=t?.user&&t?.pw?{Authorization:`Basic ${Buffer.from(`${t.user}:${t.pw}`).toString("base64")}`}:{},n=await fetch(e,{headers:r});if(!n.ok){let a="";try{a=await n.text()}catch(s){a=`${s}`}throw new Error(`Failed to fetch: ${e}: ${n.status} - ${n.statusText}: ${a}`)}return n}async function h2r(e,t){let r=await y2r();if(!r)return t;let n=await r.resolveConfig(e);return n?await r.format(t,{...n,filepath:e}):t}var m2r;function y2r(){return m2r??=Promise.resolve().then(()=>(cNe(),oNe)).catch(()=>{})}var Tle;async function Sle(e){if(Tle)return Tle;let t="https://repository.conterra.de/repository/maven-mirror-ct",r=A4(e.workingDir,"input/vex"),n=A4(e.workingDir,"output"),a=A4(e.workingDir,"cache"),s=["grype","trivy","ossindex"],u=A4(e.workingDir,"vuln-scan-conf.json"),c=await uf(u);if(!c)throw new Error(`Missing project configuration file '${u}'`);let l=c.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return Tle={projectConfigFileLocation:u,onNewVulnerabilities:c.onNewVulnerabilities??(c.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:c.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:c.reportNoLongerDetectedVulnerabilities??!0,consoleReport:c.consoleReport||"BY_PROJECT_DETAILED",createSubDirsForProject:c.createSubDirsForProject??!0,mavenRepo:c.mavenRepo??t,vexUrls:c.vexUrls??[],vexDir:A4(e.workingDir,c.vexDir)??r,outDir:A4(e.workingDir,c.outDir)??n,cacheDir:A4(e.workingDir,c.cacheDir)??a,scanners:(c.scanners??s).map(d=>{if(typeof d!="string")throw new Error(`Invalid scanner name '${d}' in configuration file '${u}'`);let _=d.split("@");if(_.length>2)throw new Error(`Invalid scanner name '${d}' in configuration file '${u}'`);let f=_[0],v=_[1]??"";return{name:f,version:v}}),projects:(c.projects??[]).map(d=>{let _=d;if(!_.name)throw new Error("Project name is missing on entry:"+JSON.stringify(_));if(!_.version)throw new Error("Project version is missing on entry:"+JSON.stringify(_));if(!_.purl)throw new Error("Project purl is missing on entry:"+JSON.stringify(_));return _.purlAliases||(_.purlAliases=[]),_.enabled==null&&(_.enabled=!0),_.silent==null&&(_.silent=!1),_.minimumSeverity||(_.minimumSeverity="UNKNOWN"),_.sbomFile?{..._,sbomFile:A4(e.workingDir,_.sbomFile)}:(_.detectNoLongerUsedVulnerabilities=l?_.purl.endsWith("-SNAPSHOT"):!0,d)})}}function A4(e,t){if(t)return tV.default.isAbsolute(t)?t:(0,tV.resolve)(e,t)}var k4=Uo(_Be());var yBe=Uo(fBe());function gV(e,t=""){return hBe(e,t)}function hBe(e,t="",r
|
|
592
|
-
`,a+=
|
|
591
|
+
`,n=await h2r(e,r);await(0,hd.writeFile)(e,n,{encoding:"utf-8"})}function Z1(e){return e?e.replace(/\?.*$/,""):""}async function cT(e){try{return await(0,hd.access)(e,hd.constants.F_OK),!0}catch{return!1}}async function Cle(e){let t=(0,Ele.resolve)(e),r=await(0,hd.readdir)(t,{withFileTypes:!0});for(let n of r){let a=(0,Ele.resolve)(n.parentPath,n.name);n.isDirectory()?await Cle(a):await(0,hd.rm)(a)}await(0,hd.rmdir)(t)}async function EI(e,t){let r=t?.user&&t?.pw?{Authorization:`Basic ${Buffer.from(`${t.user}:${t.pw}`).toString("base64")}`}:{},n=await fetch(e,{headers:r});if(!n.ok){let a="";try{a=await n.text()}catch(s){a=`${s}`}throw new Error(`Failed to fetch: ${e}: ${n.status} - ${n.statusText}: ${a}`)}return n}async function h2r(e,t){let r=await y2r();if(!r)return t;let n=await r.resolveConfig(e);return n?await r.format(t,{...n,filepath:e}):t}var m2r;function y2r(){return m2r??=Promise.resolve().then(()=>(cNe(),oNe)).catch(()=>{})}var Tle;async function Sle(e){if(Tle)return Tle;let t="https://repository.conterra.de/repository/maven-mirror-ct",r=A4(e.workingDir,"input/vex"),n=A4(e.workingDir,"output"),a=A4(e.workingDir,"cache"),s=["grype","trivy","ossindex"],u=A4(e.workingDir,"vuln-scan-conf.json"),c=await uf(u);if(!c)throw new Error(`Missing project configuration file '${u}'`);let l=c.findNoLongerDetectedVulnerabilitiesOnlyForSnapshots??!1;return Tle={projectConfigFileLocation:u,onNewVulnerabilities:c.onNewVulnerabilities??(c.failOnNewVulnerabilities?"fail":"warn"),onNoLongerDetectedVulnerabilities:c.onNoLongerDetectedVulnerabilities??"ignore",reportNoLongerDetectedVulnerabilities:c.reportNoLongerDetectedVulnerabilities??!0,consoleReport:c.consoleReport||"BY_PROJECT_DETAILED",createSubDirsForProject:c.createSubDirsForProject??!0,mavenRepo:c.mavenRepo??t,vexUrls:c.vexUrls??[],vexDir:A4(e.workingDir,c.vexDir)??r,outDir:A4(e.workingDir,c.outDir)??n,cacheDir:A4(e.workingDir,c.cacheDir)??a,scanners:(c.scanners??s).map(d=>{if(typeof d!="string")throw new Error(`Invalid scanner name '${d}' in configuration file '${u}'`);let _=d.split("@");if(_.length>2)throw new Error(`Invalid scanner name '${d}' in configuration file '${u}'`);let f=_[0],v=_[1]??"";return{name:f,version:v}}),projects:(c.projects??[]).map(d=>{let _=d;if(!_.name)throw new Error("Project name is missing on entry:"+JSON.stringify(_));if(!_.version)throw new Error("Project version is missing on entry:"+JSON.stringify(_));if(!_.purl)throw new Error("Project purl is missing on entry:"+JSON.stringify(_));return _.purlAliases||(_.purlAliases=[]),_.enabled==null&&(_.enabled=!0),_.silent==null&&(_.silent=!1),_.minimumSeverity||(_.minimumSeverity="UNKNOWN"),_.sbomFile?{..._,sbomFile:A4(e.workingDir,_.sbomFile)}:(_.detectNoLongerUsedVulnerabilities=l?_.purl.endsWith("-SNAPSHOT"):!0,d)})}}function A4(e,t){if(t)return tV.default.isAbsolute(t)?t:(0,tV.resolve)(e,t)}var k4=Uo(_Be());var yBe=Uo(fBe());function gV(e,t=""){return hBe(e,t,new Set,new Set)}function hBe(e,t="",r,n){let a=`${t}- ${e.purl}`;if(r.has(e.purl))return a+=" (cycle detected)",a;if(n.has(e.purl))return a+=" (deduplicated)",a;n.add(e.purl),r.add(e.purl);let s=r.size===1;for(let u of e.usedBy){let c=hBe(u,t+(s?" ":" "),r,n);c!==""&&(a+=`
|
|
592
|
+
`,a+=c)}return r.delete(e.purl),a}var yV=class e{constructor(t){this.sbom=t;for(let r of this.sbom.components||[]){let n={purl:Z1(r.purl),usedBy:[]};n.purl&&(this.purlToComponent.has(n.purl)||(this.purlToComponent.set(n.purl,n),this.sbomRefToComponent.set(r["bom-ref"],n)))}for(let r of this.sbom.dependencies||[]){let n=this.sbomRefToComponent.get(r.ref);if(n)for(let a of r.dependsOn||[]){let s=this.sbomRefToComponent.get(a);s&&!s.usedBy.includes(n)&&s.usedBy.push(n)}}}static createForSbom(t){return new e(t)}sbomRefToComponent=new Map;purlToComponent=new Map;findUsagesOfComponent(t){if(!this.sbom)return{purl:t,usedBy:[]};let r=this.purlToComponent.get(t);return r?mBe(r):{purl:t,usedBy:[]}}};function mBe(e,t=new Set){let r={purl:e.purl,usedBy:[]};if(t.has(e.purl))return r;t.add(e.purl);for(let n of e.usedBy){let a=mBe(n,new Set(t));r.usedBy.push(a)}return r}function gBe(e,t){let r=new k4.SarifRunBuilder().initSimple({toolDriverName:`${t.name}@${t.version}`,toolDriverVersion:"0.0.1"}),n=new Date().toISOString().split("T")[0];r.run.tool.driver.fullDescription={text:`Security Scan from ${n}`},r.run.tool.driver.properties={"microsoft/qualityDomain":`Security Scan from ${n}`};for(let s of e){let u=Igr(s.severity),c=s.id,l=Ngr(s.refs),d=new k4.SarifRuleBuilder().initSimple({ruleId:c,shortDescriptionText:s.title,fullDescriptionText:s.description,helpUri:l}),_=s.vexStatement,f,v="new",b="";_?(f=[{kind:"external",status:"accepted"}],v="updated",b=`--- INVESTIGATED (${_.status}) --- `,_.status==="under_investigation"&&(f[0].status="underReview",b="--- UNDER INVESTIGATION --- ")):Vd[t.minimumSeverity]>Vd[s.severity]?(f=[{kind:"external",status:"accepted"}],v="updated",b=`--- BELOW MINIMUM SEVERITY '${t.minimumSeverity}' ---`):t.silent&&(f=[{kind:"external",status:"accepted"}],v="updated",b="--- PROJECT SILENT ---"),Object.assign(d.rule,{name:`${b}[${s.severity}] - ${s.title.replace(`[${c}]`,"")}`,messageStrings:{default:{text:s.description,markdown:Bgr(s,l,b)}},properties:{severity:s.severity,scanners:s.scannerSeverity,links:s.refs,tags:["cve","vulnerability","security",`severity_${s.severity.toLowerCase()}`]}}),r.addRule(d);for(let D of s.components){let S=new k4.SarifResultBuilder().initSimple({ruleId:c,level:u,messageText:`${c} [${s.severity}] - ${D}`});S.result.message.id="default",S.result.locations=[{logicalLocations:[{fullyQualifiedName:D}]}],S.result.baselineState=v,S.result.suppressions=f,r.addResult(S)}}let a=new k4.SarifBuilder;return a.addRun(r),a.buildSarifOutput()}function Ngr(e){for(let t of e)if(t.startsWith("https://nvd.nist.gov"))return t;return e[0]}function Igr(e){switch(e){case"CRITICAL":return"error";case"HIGH":return"error";case"MEDIUM":return"warning";case"LOW":return"warning";default:return"note"}}function Bgr(e,t,r){let n=e.vexStatement,a=n?`
|
|
593
593
|
${r}
|
|
594
594
|
${n.justification??""}
|
|
595
595
|
${n.impact_statement??""}
|
|
@@ -617,7 +617,7 @@ Usage tree:
|
|
|
617
617
|
${e.componentTree?.map(s=>gV(s)).join(`
|
|
618
618
|
`)}
|
|
619
619
|
\`\`\`
|
|
620
|
-
`}var xV=require("fs/promises");async function vBe(e,t,r){if("sbomFile"in e)return await(0,xV.copyFile)(e.sbomFile,t),e.sbomFile=t,e;let n=await r.downloadArtifact(e.sbomMavenCoordinates);return await(0,xV.writeFile)(t,n),{...e,sbomFile:t}}var vV=class{constructor(t,r){this.repo=t;this.authn=r}async downloadArtifact(t){let r=this.toArtifactInfo(t);if(this.isSnapshotVersion(r.version)&&!r.timestamp){let s=await this.fetchLatestSnapshotTimestamp(r);r={...r,timestamp:s}}let n=this.toArtifactUrl(r),a=await EI(n,this.authn);return Buffer.from(await a.arrayBuffer())}async fetchLatestSnapshotTimestamp(t){let r=`${this.toArtifactBaseUrl(t)}/maven-metadata.xml`,a=await(await EI(r,this.authn)).text();return Ogr(a,t)}toArtifactUrl(t){let r=this.toArtifactBaseUrl(t),n=this.isSnapshotVersion(t.version)&&t.timestamp?t.version.replace(/SNAPSHOT$/,t.timestamp):t.version;return`${r}/${t.artifactId}-${n}-${t.classifier}.${t.extension}`}toArtifactBaseUrl(t){return`${this.repo}/${t.groupId.replace(/\./g,"/")}/${t.artifactId}/${t.version}`}isSnapshotVersion(t){return t.endsWith("-SNAPSHOT")}toArtifactInfo(t){let r=t.split(":");return{groupId:r[0],artifactId:r[1],version:r[2],classifier:r[3],extension:"json"}}};function Ogr(e,t){if(t.classifier&&t.extension){let a=e.match(new RegExp(`<snapshotVersion>\\s*<classifier>${t.classifier}</classifier>\\s*<extension>${t.extension}</extension>\\s*<value>([^<]+)</value>\\s*<updated>[^<]+</updated>\\s*</snapshotVersion>`)),s=t.version.replace(/SNAPSHOT$/,"");if(a?.[1])return a[1].replace(s,"")}let r=e.match(/<timestamp>([^<]+)<\/timestamp>/),n=e.match(/<buildNumber>([^<]+)<\/buildNumber>/);if(!r||!n)throw new Error(`Failed to get timestamp and build number from ${e} for artifact '${t.artifactId}'`);return`${r[1]}-${n[1]}`}var bV=require("fs/promises"),Hle=require("path");var Kle=class{constructor(t){this.location=t}async read(){let t=await uf(this.location);if(!t)throw new Error("Invalid VEX file");return t}async write(t){await Ale(this.location,t)}async delete(){await(0,bV.unlink)(this.location)}};async function DV(e,t){for(let r of await(0,bV.readdir)(e,{withFileTypes:!0}))r.name.endsWith(".json")?await t(new Kle((0,Hle.resolve)(r.parentPath,r.name))):r.isDirectory()&&await DV((0,Hle.resolve)(r.parentPath,r.name),t)}function Xle(e){let t=e.vulnerability.name;return new Set([t,...e.vulnerability.aliases??[]])}var o5=class e{statements=[];filteredToProducts=[];static async fromUrl(t,r,n=new e){let s=await(await EI(t,r)).json();return n.add(s),n}static async fromFiles(t,r=new e){return await DV(t,async n=>{let a=await n.read();r.add(a)}),r}add(t){Mgr(t);let r=t.timestamp;for(let n of t.statements){n.timestamp=n.timestamp??r;let a=Date.parse(n.timestamp),s=n.vulnerability.name,u=Xle(n),c=new Set(n.products?.map(d=>d["@id"]).filter(d=>!!d)??[]),l=new Gle(a,s,u,c,n);this.statements.push(l)}this.sortStatementsByTimestampNewestFirst()}filterByProduct(t){if(this.assertCorrectProductId(t),this.filteredToProducts.length)return this;let r=new e;return r.filteredToProducts=t.slice(0),r.statements=this.statements.filter(n=>n.matchesAtLeastOneProduct(t)),r}findNotMatchingVulnerabilities(t,r){let n=this.filterByProduct(r??this.filteredToProducts),a=new Set;for(let s of n.statements)a.add(s.vulnName);for(let s of t)a.delete(s);return Array.from(a)}newestVulnerabilityStatement(t,r){let n=this.filterByProduct(r??this.filteredToProducts);for(let a of n.statements)if(a.matchesVulnerability(t))return this.reduceToProductInformation(a,n.filteredToProducts[0])}toVexFileForProduct(t){let r=this.filterByProduct(t??this.filteredToProducts),n=r.statements.map(a=>this.reduceToProductInformation(a,r.filteredToProducts[0]));return this.toVexFile(n)}toVexFile(t){let r=t.filter(a=>a.status!=="under_investigation");if(r.length===0)return;this.sortVexStatementsByTimestampNewestFirst(r);let n=r[0].timestamp;return{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://openvex.dev/docs/public/vex-fc763e6eb63bfbcda20b7cbbddd4e9f8feaaa317fe8d8a6f51a5663a1180343e",author:"conterra",timestamp:n,last_updated:n,version:1,statements:r}}assertCorrectProductId(t){if(!t||t.length===0)throw new Error("Product ID must be provided");if(this.filteredToProducts.length&&!Lgr(this.filteredToProducts,t))throw new Error("Cannot filter to a different product")}reduceToProductInformation(t,r){let n={timestamp:new Date(t.timestamp).toISOString(),...t.statement};if(!r)return n;let a=n.products?.filter(s=>s["@id"]===r);return a?.length||(a=[{"@id":r}]),{...n,products:a}}sortStatementsByTimestampNewestFirst(){this.statements.sort((t,r)=>r.timestamp-t.timestamp)}sortVexStatementsByTimestampNewestFirst(t){t.sort((r,n)=>Date.parse(n.timestamp)-Date.parse(r.timestamp))}};function Lgr(e,t){return e.length===t.length&&e.every((r,n)=>r===t[n])}var Gle=class{constructor(t,r,n,a,s){this.timestamp=t;this.vulnName=r;this.vulnAliases=n;this.products=a;this.statement=s}matchesProduct(t){return this.products.has(t)}matchesAtLeastOneProduct(t){return t.some(this.matchesProduct.bind(this))}matchesVulnerability(t){return this.vulnAliases.has(t)}};function Mgr(e){if(e?.["@context"]!=="https://openvex.dev/ns/v0.2.0")throw new Error("Invalid VEX file format")}var AV=require("path"),xBe=require("fs/promises");var EV=class{constructor(t,r,n){this.project=t;this.outputDir=r;this.useSubDirForProject=n}async lookupOutputFileForWriting(t){let r=this.useSubDirForProject?`${this.project.name}-${this.project.version}`:"",n=`${this.project.name}-${this.project.version}-`,a=this.getFileSuffix(t),s=(0,AV.resolve)(this.outputDir,r,`${n}${a}`),u=(0,AV.dirname)(s);return await cT(u)||await(0,xBe.mkdir)(u,{recursive:!0}),s}getFileSuffix(t){switch(t){case"grype-results":return"scan-grype-results.json";case"trivy-results":return"scan-trivy-results.json";case"ossindex-results":return"scan-ossindex-results.json";case"aggregate-results":return"scan-aggregate-results.json";case"aggregated-sarif-results":return"scan-aggregated-results.sarif.json";case"project-cyclonedx-sbom-file":return"sbom.cdx.json";case"project-openvex-file":return"openvex.vex.json";default:throw new Error(`Unknown output file key: ${t}`)}}};var Yle=require("zx");var CV=require("path"),bBe="anchore/grype";async function DBe(e,t,r){r&&console.log(`Initializing Grype DB in cache directory: ${t}`);let n=`${bBe}:${e||"latest"}`,a=await Yle.$`docker run --rm -v '${t}:/tmp/.cache' -e GRYPE_DB_CACHE_DIR=/tmp/.cache -e TMPDIR=/tmp ${n} db update`.nothrow();if(a.stdout&&console.log(` Grype DB Update: ${a.stdout}`),a.stderr&&console.log(` Grype DB Update error: ${a.stderr}`),a.exitCode!==0)throw new Error(`Grype DB update failed with exit code ${a.exitCode}: ${a.stderr}`)}async function EBe(e,t,r,n,a,s,u){let c=(0,CV.dirname)(r),l=(0,CV.basename)(r),d=[];s||d.push("--quiet");let _=`${bBe}:${e||"latest"}`,f=`${t}:/tmp/.cache`,v=`${c}:/tmp/output`,b=`${n.sbomFile}:/tmp/input.json`,D=`/tmp/output/${l}`,S=await Yle.$`docker run --rm -v ${f} -v ${v} -v ${b} -e GRYPE_DB_CACHE_DIR=/tmp/.cache -e TMPDIR=/tmp -e GRYPE_DB_AUTO_UPDATE=false ${_} sbom:/tmp/input.json -o json --file ${D} --by-cve ${d}`.nothrow();if(S.stdout&&u(` Scan log: ${S.stdout}`),S.stderr&&u(` Scan error: ${S.stderr}`),S.exitCode!==0)throw new Error(`Grype scan failed with exit code ${S.exitCode}: ${S.stderr}`);u(` Grype output file: ${r}`);try{let L=await uf(r);Rgr(a,L)}catch(L){throw new Error(`Grype scan results could not be read from '${r}': ${L}`,{cause:L})}}function Rgr(e,t){if(t)for(let r of t.matches){let n=jgr(r);e.addVulnerability(n,"grype")}}function jgr(e){let t=e.vulnerability,r=t.id,n=Z1(e.artifact.purl),a=Z1(t.dataSource),s=qgr(t.severity);return{id:r,severity:s,scannerSeverity:{grype:s},title:"",description:t.description,components:[n],detectedBy:["grype"],refs:[a]}}function qgr(e){switch(e){case"Negligible":return"LOW";case"Low":return"LOW";case"Medium":return"MEDIUM";case"High":return"HIGH";case"Critical":return"CRITICAL";default:return"UNKNOWN"}}var ABe=require("fs/promises");async function CBe(e,t,r,n,a,s){try{let u={},c="";r.user&&r.token&&(u.Authorization=`Basic ${Buffer.from(`${r.user}:${r.token}`).toString("base64")}`,c="/authorized");let l=`https://ossindex.sonatype.org/api/v3${c}/component-report`,d=await Ugr(t.sbomFile),_=new Set(d.map(b=>b.purl.replace(/\?.*$/,"")));Hgr(_);let f=Array.from(_),v=[];for(let b=0;b<f.length;b+=128){let D=JSON.stringify({coordinates:f.slice(b,b+128)});a&&s(` Sonatype OssIndex request ${l} with body: ${D}`);let L=await(await fetch(l,{method:"POST",headers:{...u,"Content-Type":"application/vnd.ossindex.component-report-request.v1+json"},body:D})).json();Array.isArray(L)?v.push(...L.filter(q=>q.vulnerabilities.length>0)):s(` Sonatype OssIndex Error: ${L.code} - ${L.message}`)}await(0,ABe.writeFile)(e,JSON.stringify(v,null,2)),s(` Sonatype OssIndex output file: ${e}`),Jgr(n,v)}catch(u){throw new Error(`Sonatype OSS Index scan failed: ${u}`,{cause:u})}}async function Ugr(e){return(await uf(e)).components.filter(r=>$gr(r)&&!Vgr(r))}function $gr(e){return!!e.purl}function Vgr(e){return e.group?e.group.startsWith("de.conterra")||e.group.startsWith("org.n52.security"):!1}function Jgr(e,t){if(t)for(let r of t)for(let n of r.vulnerabilities){let a=zgr(n,r.coordinates);e.addVulnerability(a,"ossindex")}}function zgr(e,t){let r=e.cve||e.id,n=Z1(t),a=Z1(e.reference),s=Wgr(e.cvssScore);return{id:r,severity:s,scannerSeverity:{ossindex:s},title:e.title,description:e.description,components:[n],detectedBy:["ossindex"],refs:a?[a]:[]}}function Wgr(e){return e===0?"UNKNOWN":e<4?"LOW":e<7?"MEDIUM":e<9?"HIGH":"CRITICAL"}function Hgr(e){let t=Array.from(e);for(let r of t){let n=r.replace(/(@[^-]+)-.*$/g,"$1");e.add(n)}}var Qle=require("zx");var TV=require("path"),TBe="aquasec/trivy";async function SBe(e,t,r,n){let a=[];r&&(a.push("-e"),a.push(`GITHUB_TOKEN=${r}`));let s=[];s.push("--db-repository"),s.push("public.ecr.aws/aquasecurity/trivy-db,aquasec/trivy-db,ghcr.io/aquasecurity/trivy-db"),n||s.push("--quiet");let u=`${TBe}:${e||"0.69.3"}`,c=await Qle.$`docker run --rm -v '${t}:/.cache' ${a} ${u} ${s} --cache-dir '/.cache' sbom --download-db-only`.nothrow();if(!c.stdout&&!c.stderr&&console.log(" Trivy DB Update: finished"),c.stdout&&console.log(` Trivy DB Update: ${c.stdout}`),c.stderr&&console.log(` Trivy DB Update error: ${c.stderr}`),c.exitCode!==0)throw new Error(`Trivy DB update failed with exit code ${c.exitCode}: ${c.stderr}`)}async function wBe(e,t,r,n,a,s,u){let c=(0,TV.dirname)(r),l=(0,TV.basename)(r),d=[];s||d.push("--quiet");let _=`${TBe}:${e||"latest"}`,f=`${t}:/.cache`,v=`${c}:/tmp/output`,b=`${n.sbomFile}:/tmp/input.json`,D=`/tmp/output/${l}`,S=await Qle.$`docker run --rm -v ${f} -v ${v} -v ${b} ${_} sbom --cache-dir '/.cache' --format json --output ${D} ${d} --skip-db-update /tmp/input.json`.nothrow();if(S.stdout&&u(` Scan log: ${S.stdout}`),S.stderr&&u(` Scan error: ${S.stderr}`),S.exitCode!==0)throw new Error(`Trivy scan failed with exit code ${S.exitCode}: ${S.stderr}`);u(` Trivy output file: ${r}`);try{let L=await uf(r);Kgr(a,L)}catch(L){throw new Error(`Trivy scan results could not be read from '${r}': ${L}`,{cause:L})}}function Kgr(e,t){if(t){for(let r of t.Results??[])if(r.Vulnerabilities)for(let n of r.Vulnerabilities){let a=Ggr(n);e.addVulnerability(a,"trivy")}}}function Ggr(e){let t=e.VulnerabilityID,r=Z1(e.PkgIdentifier.PURL),n=Z1(e.PrimaryURL),a=Xgr(e.Severity);return{id:t,severity:a,scannerSeverity:{trivy:a},title:e.Title,description:e.Description,components:[r],detectedBy:["trivy"],refs:[n]}}function Xgr(e){switch(e){case"UNKNOWN":case"LOW":case"MEDIUM":case"HIGH":case"CRITICAL":return e;default:return"UNKNOWN"}}var SV=class{constructor(t,r,n){this.scanners=t;this.cacheDir=r;this.options=n}async init(t){let r=[];for(let n of this.scanners)switch(n.name){case"grype":r.push(DBe(n.version,this.cacheDir,t));break;case"trivy":r.push(SBe(n.version,this.cacheDir,this.options.trivyGithubToken,t));break;case"ossindex":continue}await Promise.all(r)}async scanProject(t,r,n,a,s){let u=[];for(let c of this.scanners)u.push(this.scanProjectBy(c,t,r,this.cacheDir,n,this.options.ossIndexApiUser,this.options.ossIndexApiToken,a,s));await Promise.all(u)}async scanProjectBy(t,r,n,a,s,u,c,l,d){switch(t.name){case"grype":return EBe(t.version,a,await n.lookupOutputFileForWriting("grype-results"),r,s,l,d);case"trivy":return wBe(t.version,a,await n.lookupOutputFileForWriting("trivy-results"),r,s,l,d);case"ossindex":return CBe(await n.lookupOutputFileForWriting("ossindex-results"),r,{user:u,token:c},s,l,d)}}};async function kBe(e,t,r){await DV(e,async n=>{let a=await n.read(),s=!1,u=a.statements,c=[];for(let l of u){if(r&&!Xle(l).has(r)||!l.products)continue;let d=l.products.findIndex(_=>_["@id"]===t);d!==-1&&(l.products.splice(d,1),s=!0,l.products.length===0&&c.push(l))}if(s){for(let l of c){let d=u.indexOf(l);u.splice(d,1)}if(u.length===0){console.info(`Remove ${t} from ${n.location} and delete file.`),await n.delete();return}console.info(`Remove ${t} from ${n.location}`),await n.write(a)}})}var NI=require("fs/promises"),Zle=require("path");async function PBe(e,t){let{orderBy:r,reportNoLongerDetectedVulnerabilities:n,reportCveDetails:a,outputDirectory:s}={orderBy:"CVE",reportNoLongerDetectedVulnerabilities:!0,reportCveDetails:!1,...t},u=!1,c=!1,l=!1,d=new Map,_=new Map,f=new Map,v=new Map,b=new Map,D=[],S=new Map;for(let C of e.values()){let k=C.project,T=`${k.name}@${k.version}`;if(C.error&&(u=!0,D.push({project:T,error:C.error})),k.silent)continue;let O=Vd[k.minimumSeverity],M=C.newVulns.filter($=>O<=Vd[$.severity]);for(let $ of M){if(c=!0,!d.has($.id))d.set($.id,{id:$.id,title:$.title,severity:$.severity,description:$.description,components:$.components,refs:$.refs});else{let X=d.get($.id);t7r(X,$)}_.has($.id)||_.set($.id,[]),v.has(T)||v.set(T,[]),S.has(T)||S.set(T,new Map),v.get(T).push($.id),_.get($.id).push(T);for(let X of $.componentTree)X.purl&&(S.get(T).has(X.purl)||S.get(T).set(X.purl,X))}for(let $ of C.noLongerDetectedVulns)l=!0,f.has($)||f.set($,[]),b.has(T)||b.set(T,[]),b.get(T).push($),f.get($).push(T)}let L;s&&(L=(0,Zle.join)(s,"scan-summary.txt"),await(0,NI.writeFile)(L,"","utf8"));let q=async C=>{console.log(C),L&&await(0,NI.appendFile)(L,C+`
|
|
620
|
+
`}var xV=require("fs/promises");async function vBe(e,t,r){if("sbomFile"in e)return await(0,xV.copyFile)(e.sbomFile,t),e.sbomFile=t,e;let n=await r.downloadArtifact(e.sbomMavenCoordinates);return await(0,xV.writeFile)(t,n),{...e,sbomFile:t}}var vV=class{constructor(t,r){this.repo=t;this.authn=r}async downloadArtifact(t){let r=this.toArtifactInfo(t);if(this.isSnapshotVersion(r.version)&&!r.timestamp){let s=await this.fetchLatestSnapshotTimestamp(r);r={...r,timestamp:s}}let n=this.toArtifactUrl(r),a=await EI(n,this.authn);return Buffer.from(await a.arrayBuffer())}async fetchLatestSnapshotTimestamp(t){let r=`${this.toArtifactBaseUrl(t)}/maven-metadata.xml`,a=await(await EI(r,this.authn)).text();return Ogr(a,t)}toArtifactUrl(t){let r=this.toArtifactBaseUrl(t),n=this.isSnapshotVersion(t.version)&&t.timestamp?t.version.replace(/SNAPSHOT$/,t.timestamp):t.version;return`${r}/${t.artifactId}-${n}-${t.classifier}.${t.extension}`}toArtifactBaseUrl(t){return`${this.repo}/${t.groupId.replace(/\./g,"/")}/${t.artifactId}/${t.version}`}isSnapshotVersion(t){return t.endsWith("-SNAPSHOT")}toArtifactInfo(t){let r=t.split(":");return{groupId:r[0],artifactId:r[1],version:r[2],classifier:r[3],extension:"json"}}};function Ogr(e,t){if(t.classifier&&t.extension){let a=e.match(new RegExp(`<snapshotVersion>\\s*<classifier>${t.classifier}</classifier>\\s*<extension>${t.extension}</extension>\\s*<value>([^<]+)</value>\\s*<updated>[^<]+</updated>\\s*</snapshotVersion>`)),s=t.version.replace(/SNAPSHOT$/,"");if(a?.[1])return a[1].replace(s,"")}let r=e.match(/<timestamp>([^<]+)<\/timestamp>/),n=e.match(/<buildNumber>([^<]+)<\/buildNumber>/);if(!r||!n)throw new Error(`Failed to get timestamp and build number from ${e} for artifact '${t.artifactId}'`);return`${r[1]}-${n[1]}`}var bV=require("fs/promises"),Hle=require("path");var Kle=class{constructor(t){this.location=t}async read(){let t=await uf(this.location);if(!t)throw new Error("Invalid VEX file");return t}async write(t){await Ale(this.location,t)}async delete(){await(0,bV.unlink)(this.location)}};async function DV(e,t){for(let r of await(0,bV.readdir)(e,{withFileTypes:!0}))r.name.endsWith(".json")?await t(new Kle((0,Hle.resolve)(r.parentPath,r.name))):r.isDirectory()&&await DV((0,Hle.resolve)(r.parentPath,r.name),t)}function Xle(e){let t=e.vulnerability.name;return new Set([t,...e.vulnerability.aliases??[]])}var o5=class e{statements=[];filteredToProducts=[];static async fromUrl(t,r,n=new e){let s=await(await EI(t,r)).json();return n.add(s),n}static async fromFiles(t,r=new e){return await DV(t,async n=>{let a=await n.read();r.add(a)}),r}add(t){Mgr(t);let r=t.timestamp;for(let n of t.statements){n.timestamp=n.timestamp??r;let a=Date.parse(n.timestamp),s=n.vulnerability.name,u=Xle(n),c=new Set(n.products?.map(d=>d["@id"]).filter(d=>!!d)??[]),l=new Gle(a,s,u,c,n);this.statements.push(l)}this.sortStatementsByTimestampNewestFirst()}filterByProduct(t){if(this.assertCorrectProductId(t),this.filteredToProducts.length)return this;let r=new e;return r.filteredToProducts=t.slice(0),r.statements=this.statements.filter(n=>n.matchesAtLeastOneProduct(t)),r}findNotMatchingVulnerabilities(t,r){let n=this.filterByProduct(r??this.filteredToProducts),a=new Set;for(let s of n.statements)a.add(s.vulnName);for(let s of t)a.delete(s);return Array.from(a)}newestVulnerabilityStatement(t,r){let n=this.filterByProduct(r??this.filteredToProducts);for(let a of n.statements)if(a.matchesVulnerability(t))return this.reduceToProductInformation(a,n.filteredToProducts[0])}toVexFileForProduct(t){let r=this.filterByProduct(t??this.filteredToProducts),n=r.statements.map(a=>this.reduceToProductInformation(a,r.filteredToProducts[0]));return this.toVexFile(n)}toVexFile(t){let r=t.filter(a=>a.status!=="under_investigation");if(r.length===0)return;this.sortVexStatementsByTimestampNewestFirst(r);let n=r[0].timestamp;return{"@context":"https://openvex.dev/ns/v0.2.0","@id":"https://openvex.dev/docs/public/vex-fc763e6eb63bfbcda20b7cbbddd4e9f8feaaa317fe8d8a6f51a5663a1180343e",author:"conterra",timestamp:n,last_updated:n,version:1,statements:r}}assertCorrectProductId(t){if(!t||t.length===0)throw new Error("Product ID must be provided");if(this.filteredToProducts.length&&!Lgr(this.filteredToProducts,t))throw new Error("Cannot filter to a different product")}reduceToProductInformation(t,r){let n={timestamp:new Date(t.timestamp).toISOString(),...t.statement};if(!r)return n;let a=n.products?.filter(s=>s["@id"]===r);return a?.length||(a=[{"@id":r}]),{...n,products:a}}sortStatementsByTimestampNewestFirst(){this.statements.sort((t,r)=>r.timestamp-t.timestamp)}sortVexStatementsByTimestampNewestFirst(t){t.sort((r,n)=>Date.parse(n.timestamp)-Date.parse(r.timestamp))}};function Lgr(e,t){return e.length===t.length&&e.every((r,n)=>r===t[n])}var Gle=class{constructor(t,r,n,a,s){this.timestamp=t;this.vulnName=r;this.vulnAliases=n;this.products=a;this.statement=s}matchesProduct(t){return this.products.has(t)}matchesAtLeastOneProduct(t){return t.some(this.matchesProduct.bind(this))}matchesVulnerability(t){return this.vulnAliases.has(t)}};function Mgr(e){if(e?.["@context"]!=="https://openvex.dev/ns/v0.2.0")throw new Error("Invalid VEX file format")}var AV=require("path"),xBe=require("fs/promises");var EV=class{constructor(t,r,n){this.project=t;this.outputDir=r;this.useSubDirForProject=n}async lookupOutputFileForWriting(t){let r=this.useSubDirForProject?`${this.project.name}-${this.project.version}`:"",n=`${this.project.name}-${this.project.version}-`,a=this.getFileSuffix(t),s=(0,AV.resolve)(this.outputDir,r,`${n}${a}`),u=(0,AV.dirname)(s);return await cT(u)||await(0,xBe.mkdir)(u,{recursive:!0}),s}getFileSuffix(t){switch(t){case"grype-results":return"scan-grype-results.json";case"trivy-results":return"scan-trivy-results.json";case"ossindex-results":return"scan-ossindex-results.json";case"aggregate-results":return"scan-aggregate-results.json";case"aggregated-sarif-results":return"scan-aggregated-results.sarif.json";case"project-cyclonedx-sbom-file":return"sbom.cdx.json";case"project-openvex-file":return"openvex.vex.json";default:throw new Error(`Unknown output file key: ${t}`)}}};var Yle=require("zx");var CV=require("path"),bBe="anchore/grype";async function DBe(e,t,r){r&&console.log(`Initializing Grype DB in cache directory: ${t}`);let n=`${bBe}:${e||"latest"}`,a=await Yle.$`docker run --rm -v '${t}:/tmp/.cache' -e GRYPE_DB_CACHE_DIR=/tmp/.cache -e TMPDIR=/tmp ${n} db update`.nothrow();if(a.stdout&&console.log(` Grype DB Update: ${a.stdout}`),a.stderr&&console.log(` Grype DB Update error: ${a.stderr}`),a.exitCode!==0)throw new Error(`Grype DB update failed with exit code ${a.exitCode}: ${a.stderr}`)}async function EBe(e,t,r,n,a,s,u){let c=(0,CV.dirname)(r),l=(0,CV.basename)(r),d=[];s||d.push("--quiet");let _=`${bBe}:${e||"latest"}`,f=`${t}:/tmp/.cache`,v=`${c}:/tmp/output`,b=`${n.sbomFile}:/tmp/input.json`,D=`/tmp/output/${l}`,S=await Yle.$`docker run --rm -v ${f} -v ${v} -v ${b} -e GRYPE_DB_CACHE_DIR=/tmp/.cache -e TMPDIR=/tmp -e GRYPE_DB_AUTO_UPDATE=false ${_} sbom:/tmp/input.json -o json --file ${D} --by-cve ${d}`.nothrow();if(S.stdout&&u(` Scan log: ${S.stdout}`),S.stderr&&u(` Scan error: ${S.stderr}`),S.exitCode!==0)throw new Error(`Grype scan failed with exit code ${S.exitCode}: ${S.stderr}`);u(` Grype output file: ${r}`);try{let L=await uf(r);Rgr(a,L)}catch(L){throw new Error(`Grype scan results could not be read from '${r}': ${L}`,{cause:L})}}function Rgr(e,t){if(t)for(let r of t.matches){let n=jgr(r);e.addVulnerability(n,"grype")}}function jgr(e){let t=e.vulnerability,r=t.id,n=Z1(e.artifact.purl),a=Z1(t.dataSource),s=qgr(t.severity);return{id:r,severity:s,scannerSeverity:{grype:s},title:"",description:t.description,components:[n],detectedBy:["grype"],refs:[a]}}function qgr(e){switch(e){case"Negligible":return"LOW";case"Low":return"LOW";case"Medium":return"MEDIUM";case"High":return"HIGH";case"Critical":return"CRITICAL";default:return"UNKNOWN"}}var ABe=require("fs/promises");async function CBe(e,t,r,n,a,s){try{let u={},c="";r.user&&r.token&&(u.Authorization=`Basic ${Buffer.from(`${r.user}:${r.token}`).toString("base64")}`,c="/authorized");let l=`https://ossindex.sonatype.org/api/v3${c}/component-report`,d=await Ugr(t.sbomFile),_=new Set(d.map(b=>b.purl.replace(/\?.*$/,"")));Hgr(_);let f=Array.from(_),v=[];for(let b=0;b<f.length;b+=128){let D=JSON.stringify({coordinates:f.slice(b,b+128)});a&&s(` Sonatype OssIndex request ${l} with body: ${D}`);let L=await(await fetch(l,{method:"POST",headers:{...u,"Content-Type":"application/vnd.ossindex.component-report-request.v1+json"},body:D})).json();Array.isArray(L)?v.push(...L.filter(q=>q.vulnerabilities.length>0)):s(` Sonatype OssIndex Error: ${L.code} - ${L.message}`)}await(0,ABe.writeFile)(e,JSON.stringify(v,null,2)),s(` Sonatype OssIndex output file: ${e}`),Jgr(n,v)}catch(u){throw new Error(`Sonatype OSS Index scan failed: ${u}`,{cause:u})}}async function Ugr(e){return(await uf(e)).components.filter(r=>$gr(r)&&!Vgr(r))}function $gr(e){return!!e.purl}function Vgr(e){return e.group?e.group.startsWith("de.conterra")||e.group.startsWith("org.n52.security"):!1}function Jgr(e,t){if(t)for(let r of t)for(let n of r.vulnerabilities){let a=zgr(n,r.coordinates);e.addVulnerability(a,"ossindex")}}function zgr(e,t){let r=e.cve||e.id,n=Z1(t),a=Z1(e.reference),s=Wgr(e.cvssScore);return{id:r,severity:s,scannerSeverity:{ossindex:s},title:e.title,description:e.description,components:[n],detectedBy:["ossindex"],refs:a?[a]:[]}}function Wgr(e){return e===0?"UNKNOWN":e<4?"LOW":e<7?"MEDIUM":e<9?"HIGH":"CRITICAL"}function Hgr(e){let t=Array.from(e);for(let r of t){let n=r.replace(/(@[^-]+)-.*$/g,"$1");e.add(n)}}var Qle=require("zx");var TV=require("path"),TBe="aquasec/trivy";async function SBe(e,t,r,n){let a=[];r&&(a.push("-e"),a.push(`GITHUB_TOKEN=${r}`));let s=[];s.push("--db-repository"),s.push("public.ecr.aws/aquasecurity/trivy-db,aquasec/trivy-db,ghcr.io/aquasecurity/trivy-db"),n||s.push("--quiet");let u=`${TBe}:${e||"0.69.3"}`,c=await Qle.$`docker run --rm -v '${t}:/.cache' ${a} ${u} ${s} --cache-dir '/.cache' sbom --download-db-only`.nothrow();if(!c.stdout&&!c.stderr&&console.log(" Trivy DB Update: finished"),c.stdout&&console.log(` Trivy DB Update: ${c.stdout}`),c.stderr&&console.log(` Trivy DB Update error: ${c.stderr}`),c.exitCode!==0)throw new Error(`Trivy DB update failed with exit code ${c.exitCode}: ${c.stderr}`)}async function wBe(e,t,r,n,a,s,u){let c=(0,TV.dirname)(r),l=(0,TV.basename)(r),d=[];s||d.push("--quiet");let _=`${TBe}:${e||"0.69.3"}`,f=`${t}:/.cache`,v=`${c}:/tmp/output`,b=`${n.sbomFile}:/tmp/input.json`,D=`/tmp/output/${l}`,S=await Qle.$`docker run --rm -v ${f} -v ${v} -v ${b} ${_} sbom --cache-dir '/.cache' --format json --output ${D} ${d} --skip-db-update /tmp/input.json`.nothrow();if(S.stdout&&u(` Scan log: ${S.stdout}`),S.stderr&&u(` Scan error: ${S.stderr}`),S.exitCode!==0)throw new Error(`Trivy scan failed with exit code ${S.exitCode}: ${S.stderr}`);u(` Trivy output file: ${r}`);try{let L=await uf(r);Kgr(a,L)}catch(L){throw new Error(`Trivy scan results could not be read from '${r}': ${L}`,{cause:L})}}function Kgr(e,t){if(t){for(let r of t.Results??[])if(r.Vulnerabilities)for(let n of r.Vulnerabilities){let a=Ggr(n);e.addVulnerability(a,"trivy")}}}function Ggr(e){let t=e.VulnerabilityID,r=Z1(e.PkgIdentifier.PURL),n=Z1(e.PrimaryURL),a=Xgr(e.Severity);return{id:t,severity:a,scannerSeverity:{trivy:a},title:e.Title,description:e.Description,components:[r],detectedBy:["trivy"],refs:[n]}}function Xgr(e){switch(e){case"UNKNOWN":case"LOW":case"MEDIUM":case"HIGH":case"CRITICAL":return e;default:return"UNKNOWN"}}var SV=class{constructor(t,r,n){this.scanners=t;this.cacheDir=r;this.options=n}async init(t){let r=[];for(let n of this.scanners)switch(n.name){case"grype":r.push(DBe(n.version,this.cacheDir,t));break;case"trivy":r.push(SBe(n.version,this.cacheDir,this.options.trivyGithubToken,t));break;case"ossindex":continue}await Promise.all(r)}async scanProject(t,r,n,a,s){let u=[];for(let c of this.scanners)u.push(this.scanProjectBy(c,t,r,this.cacheDir,n,this.options.ossIndexApiUser,this.options.ossIndexApiToken,a,s));await Promise.all(u)}async scanProjectBy(t,r,n,a,s,u,c,l,d){switch(t.name){case"grype":return EBe(t.version,a,await n.lookupOutputFileForWriting("grype-results"),r,s,l,d);case"trivy":return wBe(t.version,a,await n.lookupOutputFileForWriting("trivy-results"),r,s,l,d);case"ossindex":return CBe(await n.lookupOutputFileForWriting("ossindex-results"),r,{user:u,token:c},s,l,d)}}};async function kBe(e,t,r){await DV(e,async n=>{let a=await n.read(),s=!1,u=a.statements,c=[];for(let l of u){if(r&&!Xle(l).has(r)||!l.products)continue;let d=l.products.findIndex(_=>_["@id"]===t);d!==-1&&(l.products.splice(d,1),s=!0,l.products.length===0&&c.push(l))}if(s){for(let l of c){let d=u.indexOf(l);u.splice(d,1)}if(u.length===0){console.info(`Remove ${t} from ${n.location} and delete file.`),await n.delete();return}console.info(`Remove ${t} from ${n.location}`),await n.write(a)}})}var NI=require("fs/promises"),Zle=require("path");async function PBe(e,t){let{orderBy:r,reportNoLongerDetectedVulnerabilities:n,reportCveDetails:a,outputDirectory:s}={orderBy:"CVE",reportNoLongerDetectedVulnerabilities:!0,reportCveDetails:!1,...t},u=!1,c=!1,l=!1,d=new Map,_=new Map,f=new Map,v=new Map,b=new Map,D=[],S=new Map;for(let C of e.values()){let k=C.project,T=`${k.name}@${k.version}`;if(C.error&&(u=!0,D.push({project:T,error:C.error})),k.silent)continue;let O=Vd[k.minimumSeverity],M=C.newVulns.filter($=>O<=Vd[$.severity]);for(let $ of M){if(c=!0,!d.has($.id))d.set($.id,{id:$.id,title:$.title,severity:$.severity,description:$.description,components:$.components,refs:$.refs});else{let X=d.get($.id);t7r(X,$)}_.has($.id)||_.set($.id,[]),v.has(T)||v.set(T,[]),S.has(T)||S.set(T,new Map),v.get(T).push($.id),_.get($.id).push(T);for(let X of $.componentTree)X.purl&&(S.get(T).has(X.purl)||S.get(T).set(X.purl,X))}for(let $ of C.noLongerDetectedVulns)l=!0,f.has($)||f.set($,[]),b.has(T)||b.set(T,[]),b.get(T).push($),f.get($).push(T)}let L;s&&(L=(0,Zle.join)(s,"scan-summary.txt"),await(0,NI.writeFile)(L,"","utf8"));let q=async C=>{console.log(C),L&&await(0,NI.appendFile)(L,C+`
|
|
621
621
|
`,"utf8")};switch(await q("=== Scan summary ==="),D.length&&await Ygr(q,D),a&&await e7r(q,d,S),r){case"CVE":{await Zgr(q,_,d,n?f:new Map);break}case"PROJECT":{await Qgr(q,v,n?b:new Map,d);break}}!u&&!c&&(!l||!n)&&await q(" No issues found");let F={errors:D,vulnerabilities:Object.fromEntries(d),vulnerabilityToProject:Object.fromEntries(_.entries()),projectToVulnerability:Object.fromEntries(v.entries()),projectsToComponents:Object.fromEntries(Array.from(S.entries()).map(([C,k])=>[C,Object.fromEntries(k.entries())])),noLongerDetectedVulnerabilities:Object.fromEntries(f)};if(s){let C=(0,Zle.join)(s,"scan-summary.json");await(0,NI.writeFile)(C,JSON.stringify(F,null,2),"utf8")}return{hasError:u,hasNewVuln:c,hasNoLongerDetectedVuln:l}}async function Ygr(e,t){await e(""),await e("- Errors during scan:");for(let{project:r,error:n}of t)await e(` - ${r}:`),await e(` Error: ${n}`)}async function Qgr(e,t,r,n){let a=new Set([...Array.from(t.keys()),...Array.from(r.keys())]),s=Array.from(a.keys()).sort();if(s.length){await e(""),await e("- Vulnerabilities by project:");for(let u of s){await e(` - ${u}:`);let c=t.get(u)??[];for(let d of c.slice().sort(e0e(_=>n.get(_).severity))){let{severity:_}=n.get(d);await e(` - [${_}] ${d}`)}let l=(r.get(u)??[]).slice().sort();for(let d of l)await e(` - ${d} (no longer detected)`)}}}async function Zgr(e,t,r,n){let a=Array.from(t.keys()).sort(e0e(u=>r.get(u).severity));if(a.length){await e(""),await e("- New vulnerabilities:");for(let u of a){let c=t.get(u),{severity:l}=r.get(u);await e(` - [${l}] ${u}`);for(let d of c.slice().sort())await e(` - ${d}`)}}let s=Array.from(n.keys()).sort();if(s.length){await e(""),await e("- Declared but no longer detected vulnerabilities:");for(let u of s){let c=n.get(u);await e(` - ${u}`);for(let l of c.slice().sort())await e(` - ${l}`)}}}async function e7r(e,t,r){if(t.size===0)return;await e(""),await e("- Vulnerability details:");let n=Array.from(t.keys()).sort(e0e(a=>t.get(a).severity));for(let a of n){let s=t.get(a);if(await e(` - [${s.severity}] ${s.id} - ${s.title||""}:`),s.description){await e(" Description:");let u=s.description.split(/\r?\n/);for(let c of u)await e(` ${c}`)}if(s.components.length){await e(" Components:");for(let u of s.components)await e(" - "+u);if(r){for(let u of s.components)for(let[c,l]of r.entries())if(l.has(u)){await e(` Usage Tree of ${u} by ${c} (as example):`),await e(gV(l.get(u)," "));break}}}if(s.refs.length){await e(" Links:");for(let u of s.refs)await e(` - ${u}`)}}}function t7r(e,t){e.title=e.title||t.title,e.severity=Vd[e.severity]>Vd[t.severity]?e.severity:t.severity,e.description=e.description||t.description,e.components=FBe(e.components,t.components),e.refs=FBe(e.refs,t.refs)}function FBe(e,t){let r=new Set([...e,...t]);return Array.from(r)}function e0e(e){return(t,r)=>{let n=e(t),a=e(r),s=Vd[n],u=Vd[a];return s!==u?s>u?-1:1:t.localeCompare(r)}}wV.os.type().startsWith("Windows")&&(0,wV.usePowerShell)();async function NBe(e){let t=await Sle(e),r=t.cacheDir;await cT(r)||await(0,_T.mkdir)(r);let n=t.outDir;await cT(n)&&await Cle(n),await(0,_T.mkdir)(n);let a=await a7r(t,{user:e.vexUrlsUser,pw:e.vexUrlsPw}),s=new vV(t.mavenRepo,{user:e.mavenRepoUser,pw:e.mavenRepoPw}),u=s7r(t,e,r),c=Date.now();console.log("Initializing scanner engines ..."),await u.init(e.verbose),console.log(`Scanner engines initialization took ${Date.now()-c}ms
|
|
622
622
|
`);let l=o7r(e),d=t.projects,_=new Map,f=Date.now();console.log("Scanning projects ...");let v=d.filter(l).map(D=>{let S=new EV(D,n,t.createSubDirsForProject),L=[],q=C=>{L.push(C)};return{scan(){return r7r(D,S,s,u,a,q,_,e,L)}}});await c7r(v),console.log(`Scanning took ${Date.now()-f}ms`),e.autoRemoveUnusedStatements&&await u7r(_,t.vexDir);let b=await PBe(_,{orderBy:t.consoleReport.startsWith("BY_CVE")?"CVE":"PROJECT",reportCveDetails:t.consoleReport.endsWith("_DETAILED"),reportNoLongerDetectedVulnerabilities:t.reportNoLongerDetectedVulnerabilities,outputDirectory:n});if(b.hasError)return 1;if(b.hasNewVuln){if(t.onNewVulnerabilities==="fail")return 1;t.onNewVulnerabilities==="warn"&&(console.log("##vso[task.logissue type=warning;]NEW_VULNERABILITIES_DETECTED"),console.log("##vso[task.complete result=SucceededWithIssues;]"))}if(b.hasNoLongerDetectedVuln){if(t.onNoLongerDetectedVulnerabilities==="fail")return 1;t.onNoLongerDetectedVulnerabilities==="warn"&&(console.log("##vso[task.logissue type=warning;]NO_LONGER_DETECTED_VULNERABILITIES"),console.log("##vso[task.complete result=SucceededWithIssues;]"))}return 0}async function r7r(e,t,r,n,a,s,u,c,l){try{let{unmatchedVulnerabilities:d,noLongerDetectedVulnerabilities:_}=await n7r(e,t,r,n,a,c.verbose,s);u.set(e.purl,{project:e,newVulns:d,noLongerDetectedVulns:_})}catch(d){let _=d;u.set(e.purl,{project:e,error:`${_}`,newVulns:[],noLongerDetectedVulns:[]})}if(c.verbose)for(let d of l)console.log(d)}async function n7r(e,t,r,n,a,s,u){let c=await vBe(e,await t.lookupOutputFileForWriting("project-cyclonedx-sbom-file"),r);u(`Analyzing project: ${c.name} - ${c.version} - ${c.sbomFile}`);let l=await uf(c.sbomFile);if(!l)throw new Error(`Could not read SBOM file ${c.sbomFile} for project ${c.name}`);if(!l.components||l.components.length===0)throw new Error(`SBOM file ${c.sbomFile} for project ${c.name} does not contain any components`);let d=new JR(yV.createForSbom(l));await n.scanProject(c,t,d,s,u);let _=a.filterByProduct([c.purl,...c.purlAliases]),{unmatchedVulnerabilities:f}=d.enhanceWithVexData(_),v=c.detectNoLongerUsedVulnerabilities?_.findNotMatchingVulnerabilities(d.getAllVulnIds()):[];return await i7r(t,c,d,_,u),{unmatchedVulnerabilities:f,noLongerDetectedVulnerabilities:v}}async function i7r(e,t,r,n,a){let s=r.getAllVulnerabilitiesSortedBySeverity(),u=await e.lookupOutputFileForWriting("aggregate-results");await(0,_T.writeFile)(u,JSON.stringify(s,null,2)),a(` Vulnerabilities output file: ${u}`);let c=await e.lookupOutputFileForWriting("aggregated-sarif-results"),l=gBe(s,t);await(0,_T.writeFile)(c,JSON.stringify(l,null,2)),a(` Vuln Sarif output file: ${c}`);let d=n.toVexFile(s.filter(f=>f.vexStatement).map(f=>{let v=f.vexStatement;for(let b of f.components??[])v.products.push({"@id":b});return v}));if(!d)return;let _=await e.lookupOutputFileForWriting("project-openvex-file");await(0,_T.writeFile)(_,JSON.stringify(d,null,2)),a(` OpenVex file: ${_}`)}async function a7r(e,t){let r=e.vexDir,n;await cT(r)?n=await o5.fromFiles(r):n=new o5;for(let a of e.vexUrls)await o5.fromUrl(a,t,n);return n}function s7r(e,t,r){if(t.scannerEngine)return t.scannerEngine;if(e.scanners.length===0)throw new Error("No scanners configured");return new SV(e.scanners,r,t)}function o7r(e){let{reduceToProjectName:t,reduceToProjectVersion:r}=e;return n=>!(!n.enabled||t&&(n.name!==t||r&&n.version!==r))}async function u7r(e,t){for(let r of e.values())if(!r.project.silent)for(let n of r.noLongerDetectedVulns)await kBe(t,r.project.purl,n)}async function c7r(e,t=5){let r=0,n=0,a=0,s=e.length,u,c=new Promise(d=>{u=d});function l(){for(;r<t&&a<s;){let d=e[a++];r++,d.scan().finally(()=>{r--,n++,n>=s?u():l()})}}l(),await c}var IBe=require("zx");IBe.dotenv.config();var BD=process.env;(async()=>{let e=await NBe({workingDir:process.cwd(),reduceToProjectName:process.argv[2],reduceToProjectVersion:process.argv[3],ossIndexApiUser:BD.OSS_INDEX_API_USER,ossIndexApiToken:BD.OSS_INDEX_API_TOKEN,mavenRepoUser:BD.MAVEN_REPO_USER,mavenRepoPw:BD.MAVEN_REPO_PW,trivyGithubToken:BD.TRIVY_GITHUB_TOKEN,vexUrlsUser:BD.VEX_URLS_USER,vexUrlsPw:BD.VEX_URLS_PW,verbose:BD.VERBOSE==="true",autoRemoveUnusedStatements:BD.AUTO_REMOVE_UNUSED_STATEMENTS==="true"});process.exitCode=e})();
|
|
623
623
|
/*! Bundled license information:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conterra/vuln-scan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "con terra vulnerability scan process",
|
|
5
5
|
"author": "con terra GmbH",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"prettier": "^3.8.1",
|
|
49
49
|
"rimraf": "6.1.3",
|
|
50
50
|
"typescript": "5.9.3",
|
|
51
|
-
"typescript-eslint": "8.57.
|
|
52
|
-
"vitest": "4.1.
|
|
51
|
+
"typescript-eslint": "8.57.2",
|
|
52
|
+
"vitest": "4.1.1",
|
|
53
53
|
"@inquirer/prompts": "8.3.2"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|