@cyclonedx/cdxgen
Version:
Creates CycloneDX Software Bill of Materials (SBOM) from source or container image
50 lines (46 loc) • 1.49 kB
JavaScript
function escapeMarkdownText(value) {
return String(value ?? "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/([\\`*_{}\[\]()#+!|])/g, "\\$1")
.replace(/\r?\n/g, "<br>")
.trim();
}
function escapeMarkdownCell(value) {
return escapeMarkdownText(value);
}
/**
* Format annotation properties as a markdown table for CycloneDX annotations.
*
* @param {{ name: string, value: string }[]} properties annotation properties
* @returns {string} markdown table text
*/
export function propertiesToMarkdownTable(properties) {
if (!properties?.length) {
return "";
}
const lines = ["| Property | Value |", "| --- | --- |"];
for (const property of properties) {
lines.push(
`| ${escapeMarkdownCell(property?.name)} | ${escapeMarkdownCell(property?.value)} |`,
);
}
return lines.join("\n");
}
/**
* Build production-ready markdown annotation text.
*
* @param {string} message leading message text
* @param {{ name: string, value: string }[]} properties annotation properties
* @param {string[]} [details] optional detail lines shown before the table
* @returns {string} annotation text
*/
export function buildAnnotationText(message, properties, details = []) {
const lines = [message, ...details.filter(Boolean)].map(escapeMarkdownText);
const markdownTable = propertiesToMarkdownTable(properties);
if (markdownTable) {
lines.push("", markdownTable);
}
return lines.join("\n");
}