compact-yarn-audit
Advanced tools
Comparing version 4.0.3 to 4.0.4
import { EOL } from "node:os"; | ||
import { terseAdvisoryLog2Table } from "./terse-advisory-to-table.js"; | ||
export default function format(pTerseEntries) { | ||
if (pTerseEntries.length > 0) { | ||
return terseAdvisoryLog2Table(pTerseEntries); | ||
} | ||
else { | ||
return `${EOL} no vulnerabilities found ${EOL}`; | ||
} | ||
if (pTerseEntries.length > 0) { | ||
return terseAdvisoryLog2Table(pTerseEntries); | ||
} else { | ||
return `${EOL} no vulnerabilities found ${EOL}`; | ||
} | ||
} |
@@ -7,13 +7,13 @@ #!/usr/bin/env node | ||
process.stdin | ||
.pipe(ndjson.parse()) | ||
.on("data", (pLogEntry) => { | ||
lAdvisoryLog.add(pLogEntry); | ||
}) | ||
.on("error", (pError) => { | ||
console.error(pError); | ||
process.exitCode = 1; | ||
process.exit(); | ||
}) | ||
.on("end", () => { | ||
console.log(format(lAdvisoryLog.get())); | ||
}); | ||
.pipe(ndjson.parse()) | ||
.on("data", (pLogEntry) => { | ||
lAdvisoryLog.add(pLogEntry); | ||
}) | ||
.on("error", (pError) => { | ||
console.error(pError); | ||
process.exitCode = 1; | ||
process.exit(); | ||
}) | ||
.on("end", () => { | ||
console.log(format(lAdvisoryLog.get())); | ||
}); |
function extractUsefulAttributes(pLogEntry) { | ||
const lFixable = pLogEntry.data.advisory.patched_versions !== "<0.0.0"; | ||
const lVia = pLogEntry.data.resolution.path.split(">").shift() ?? "?"; | ||
return { | ||
severity: pLogEntry.data.advisory.severity, | ||
title: pLogEntry.data.advisory.title, | ||
fixable: lFixable, | ||
fixString: lFixable | ||
? `"${pLogEntry.data.advisory.module_name}": "${pLogEntry.data.advisory.patched_versions}"` | ||
: "no fix available", | ||
module_name: pLogEntry.data.advisory.module_name, | ||
via: lVia === pLogEntry.data.advisory.module_name ? "." : lVia, | ||
}; | ||
const lFixable = pLogEntry.data.advisory.patched_versions !== "<0.0.0"; | ||
const lVia = pLogEntry.data.resolution.path.split(">").shift() ?? "?"; | ||
return { | ||
severity: pLogEntry.data.advisory.severity, | ||
title: pLogEntry.data.advisory.title, | ||
fixable: lFixable, | ||
fixString: lFixable | ||
? `"${pLogEntry.data.advisory.module_name}": "${pLogEntry.data.advisory.patched_versions}"` | ||
: "no fix available", | ||
module_name: pLogEntry.data.advisory.module_name, | ||
via: lVia === pLogEntry.data.advisory.module_name ? "." : lVia, | ||
}; | ||
} | ||
function severity2Order(pSeverity) { | ||
const lSeverity2Order = { | ||
critical: 1, | ||
high: 2, | ||
moderate: 3, | ||
low: 4, | ||
info: 5, | ||
}; | ||
return lSeverity2Order[pSeverity] || -1; | ||
const lSeverity2Order = { | ||
critical: 1, | ||
high: 2, | ||
moderate: 3, | ||
low: 4, | ||
info: 5, | ||
}; | ||
return lSeverity2Order[pSeverity] || -1; | ||
} | ||
function getKey(pEntry) { | ||
return `${severity2Order(pEntry.severity)}|${pEntry.module_name}`; | ||
return `${severity2Order(pEntry.severity)}|${pEntry.module_name}`; | ||
} | ||
function orderEntry(pEntryLeft, pEntryRight) { | ||
return getKey(pEntryLeft) > getKey(pEntryRight) ? 1 : -1; | ||
return getKey(pEntryLeft) > getKey(pEntryRight) ? 1 : -1; | ||
} | ||
export class TerseAdvisoryLog { | ||
log = new Set(); | ||
constructor() { | ||
this.log = new Set(); | ||
} | ||
add(pEntry) { | ||
if (pEntry.type === "auditAdvisory") { | ||
const lUsefulAttributes = extractUsefulAttributes(pEntry); | ||
this.log.add(JSON.stringify(lUsefulAttributes)); | ||
} | ||
} | ||
get() { | ||
return Array.from(this.log) | ||
.map((pStringifiedEntry) => JSON.parse(pStringifiedEntry)) | ||
.sort(orderEntry); | ||
} | ||
log = new Set(); | ||
constructor() { | ||
this.log = new Set(); | ||
} | ||
add(pEntry) { | ||
if (pEntry.type === "auditAdvisory") { | ||
const lUsefulAttributes = extractUsefulAttributes(pEntry); | ||
this.log.add(JSON.stringify(lUsefulAttributes)); | ||
} | ||
} | ||
get() { | ||
return Array.from(this.log) | ||
.map((pStringifiedEntry) => JSON.parse(pStringifiedEntry)) | ||
.sort(orderEntry); | ||
} | ||
} |
import { EOL } from "node:os"; | ||
import chalk from "chalk"; | ||
function colorBySeverity(pSeverity, pString) { | ||
const lSeverity2ChalkFunction = new Map([ | ||
["critical", chalk.red], | ||
["high", chalk.magenta], | ||
["moderate", chalk.yellow], | ||
["info", chalk.blue], | ||
]); | ||
const lFunction = lSeverity2ChalkFunction.get(pSeverity) || ((pX) => pX); | ||
return lFunction(pString); | ||
const lSeverity2ChalkFunction = new Map([ | ||
["critical", chalk.red], | ||
["high", chalk.magenta], | ||
["moderate", chalk.yellow], | ||
["info", chalk.blue], | ||
]); | ||
const lFunction = lSeverity2ChalkFunction.get(pSeverity) || ((pX) => pX); | ||
return lFunction(pString); | ||
} | ||
function getColumnWidth(pTerseEntries, pColumnName) { | ||
return pTerseEntries.reduce((pAll, pEntry) => Math.max(pAll, pEntry[pColumnName].length), 0); | ||
return pTerseEntries.reduce( | ||
(pAll, pEntry) => Math.max(pAll, pEntry[pColumnName].length), | ||
0, | ||
); | ||
} | ||
function getColumnWidths(pTerseEntries, pWidthAvailable) { | ||
const lColumns = ["severity", "title", "module_name", "via", "fixString"]; | ||
const lReturnValue = new Map(lColumns.map((pColumn) => { | ||
return [pColumn, getColumnWidth(pTerseEntries, pColumn)]; | ||
})); | ||
const lAllColumnsLength = Array.from(lReturnValue.values()).reduce((pAll, pLength) => { | ||
return pAll + pLength; | ||
}, 0); | ||
const lMinimumTitleColumnWidth = 14; | ||
const lSpacesPerColumn = 2; | ||
const lAvailableForTitle = Math.min(lReturnValue.get("title"), Math.max(lMinimumTitleColumnWidth, pWidthAvailable - | ||
(lAllColumnsLength - lReturnValue.get("title")) - | ||
lSpacesPerColumn * lColumns.length)); | ||
lReturnValue.set("title", lAvailableForTitle); | ||
return lReturnValue; | ||
const lColumns = ["severity", "title", "module_name", "via", "fixString"]; | ||
const lReturnValue = new Map( | ||
lColumns.map((pColumn) => { | ||
return [pColumn, getColumnWidth(pTerseEntries, pColumn)]; | ||
}), | ||
); | ||
const lAllColumnsLength = Array.from(lReturnValue.values()).reduce( | ||
(pAll, pLength) => { | ||
return pAll + pLength; | ||
}, | ||
0, | ||
); | ||
const lMinimumTitleColumnWidth = 14; | ||
const lSpacesPerColumn = 2; | ||
const lAvailableForTitle = Math.min( | ||
lReturnValue.get("title"), | ||
Math.max( | ||
lMinimumTitleColumnWidth, | ||
pWidthAvailable - | ||
(lAllColumnsLength - lReturnValue.get("title")) - | ||
lSpacesPerColumn * lColumns.length, | ||
), | ||
); | ||
lReturnValue.set("title", lAvailableForTitle); | ||
return lReturnValue; | ||
} | ||
function truncateTitle(pTitle, pWidth) { | ||
let lReturnValue = pTitle.padEnd(pWidth).slice(0, pWidth); | ||
if (pTitle.length > pWidth) { | ||
lReturnValue = `${lReturnValue.slice(0, -1)}…`; | ||
} | ||
return lReturnValue; | ||
let lReturnValue = pTitle.padEnd(pWidth).slice(0, pWidth); | ||
if (pTitle.length > pWidth) { | ||
lReturnValue = `${lReturnValue.slice(0, -1)}…`; | ||
} | ||
return lReturnValue; | ||
} | ||
export function terseAdvisoryLog2Table(pTerseEntries, pColumnsAvailable = process.stdout.columns) { | ||
const lColumnWidths = getColumnWidths(pTerseEntries, pColumnsAvailable); | ||
const lTitle = chalk.bold(`${"severity".padEnd(lColumnWidths.get("severity"))} ` + | ||
`${"title".padEnd(lColumnWidths.get("title"))} ` + | ||
`${"module".padEnd(lColumnWidths.get("module_name"))} ` + | ||
`${"via".padEnd(lColumnWidths.get("via"))} ` + | ||
`"resolutions" string`); | ||
const lCells = pTerseEntries | ||
.map((pEntry) => { | ||
return (`${colorBySeverity(pEntry.severity, `${pEntry.severity.padEnd(lColumnWidths.get("severity"))} `)}` + | ||
`${truncateTitle(pEntry.title, lColumnWidths.get("title"))} ` + | ||
`${pEntry.module_name.padEnd(lColumnWidths.get("module_name"))} ` + | ||
`${pEntry.via.padEnd(lColumnWidths.get("via"))} ` + | ||
`${pEntry.fixString}`); | ||
}) | ||
.join(EOL); | ||
return lTitle + EOL + lCells; | ||
export function terseAdvisoryLog2Table( | ||
pTerseEntries, | ||
pColumnsAvailable = process.stdout.columns, | ||
) { | ||
const lColumnWidths = getColumnWidths(pTerseEntries, pColumnsAvailable); | ||
const lTitle = chalk.bold( | ||
`${"severity".padEnd(lColumnWidths.get("severity"))} ` + | ||
`${"title".padEnd(lColumnWidths.get("title"))} ` + | ||
`${"module".padEnd(lColumnWidths.get("module_name"))} ` + | ||
`${"via".padEnd(lColumnWidths.get("via"))} ` + | ||
`"resolutions" string`, | ||
); | ||
const lCells = pTerseEntries | ||
.map((pEntry) => { | ||
return ( | ||
`${colorBySeverity(pEntry.severity, `${pEntry.severity.padEnd(lColumnWidths.get("severity"))} `)}` + | ||
`${truncateTitle(pEntry.title, lColumnWidths.get("title"))} ` + | ||
`${pEntry.module_name.padEnd(lColumnWidths.get("module_name"))} ` + | ||
`${pEntry.via.padEnd(lColumnWidths.get("via"))} ` + | ||
`${pEntry.fixString}` | ||
); | ||
}) | ||
.join(EOL); | ||
return lTitle + EOL + lCells; | ||
} |
{ | ||
"name": "compact-yarn-audit", | ||
"version": "4.0.3", | ||
"description": "Presents output from yarn audit in a compact table", | ||
"engines": { | ||
"node": "^18.17||>=20" | ||
}, | ||
"license": "MIT", | ||
"homepage": "https://github.com/sverweij/compact-yarn-audit", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/sverweij/compact-yarn-audit.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/sverweij/compact-yarn-audit/issues" | ||
}, | ||
"author": "Sander Verweij (https://sverweij.github.io/)", | ||
"bin": { | ||
"compact-yarn-audit": "dist/index.js" | ||
}, | ||
"type": "module", | ||
"keywords": [ | ||
"yarn", | ||
"yarn-audit" | ||
], | ||
"dependencies": { | ||
"chalk": "^5.3.0", | ||
"ndjson": "^2.0.0" | ||
}, | ||
"overrides": { | ||
"semver": "^7.5.4" | ||
}, | ||
"resolutions": { | ||
"semver": "^7.5.4" | ||
}, | ||
"files": [ | ||
"dist", | ||
"package.json", | ||
"README.md" | ||
], | ||
"scripts": { | ||
"test": "echo for test, build and static analysis scripts: see the github repository" | ||
} | ||
"name": "compact-yarn-audit", | ||
"version": "4.0.4", | ||
"description": "Presents output from yarn audit in a compact table", | ||
"engines": { | ||
"node": "^18.17||>=20" | ||
}, | ||
"license": "MIT", | ||
"homepage": "https://github.com/sverweij/compact-yarn-audit", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/sverweij/compact-yarn-audit.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/sverweij/compact-yarn-audit/issues" | ||
}, | ||
"author": "Sander Verweij (https://sverweij.github.io/)", | ||
"bin": { | ||
"compact-yarn-audit": "dist/index.js" | ||
}, | ||
"type": "module", | ||
"keywords": [ | ||
"yarn", | ||
"yarn-audit" | ||
], | ||
"dependencies": { | ||
"chalk": "^5.3.0", | ||
"ndjson": "^2.0.0" | ||
}, | ||
"overrides": { | ||
"semver": "^7.5.4" | ||
}, | ||
"resolutions": { | ||
"semver": "^7.5.4" | ||
}, | ||
"files": [ | ||
"dist", | ||
"package.json", | ||
"README.md" | ||
], | ||
"scripts": { | ||
"test": "echo for test, build and static analysis scripts: see the github repository" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
151
10053