UNPKG

markdown-code

Version:

Keep code examples in Markdown synchronized with actual source files

100 lines (97 loc) 2.78 kB
// src/formatter.ts import { resolve } from "path"; import pc from "picocolors"; function getIssueColor(type) { switch (type) { case "sync-needed": return pc.yellow; case "file-missing": return pc.cyan; case "invalid-path": case "load-failed": return pc.red; default: return pc.white; } } function getPluralForm(type) { const pluralMap = { "sync-needed": "sync-needed", "file-missing": "file-missing", "invalid-path": "invalid-paths", "load-failed": "load-failed" }; return pluralMap[type] ?? `${type}s`; } function formatIssue(issue) { const { line, column, type, message, ruleId } = issue; const position = pc.dim(`${line}:${column}`.padEnd(6)); const colorFn = getIssueColor(type); const severity = colorFn(type.padEnd(12)); const rule = ruleId ? pc.dim(` ${ruleId}`) : ""; return ` ${position} ${severity} ${message}${rule}`; } function formatFileIssues(fileIssues) { const { filePath, issues } = fileIssues; if (issues.length === 0) { return ""; } const absolutePath = pc.dim(resolve(filePath)); const formattedIssues = issues.map(formatIssue).join("\n"); return `${absolutePath} ${formattedIssues}`; } function formatSummary(allFileIssues) { const totalIssues = allFileIssues.reduce( (sum, file) => sum + file.issues.length, 0 ); if (totalIssues === 0) { return ""; } const issueCountsByType = allFileIssues.reduce( (counts, file) => { file.issues.forEach((issue) => { counts[issue.type] = (counts[issue.type] ?? 0) + 1; }); return counts; }, {} ); const problemsText = totalIssues === 1 ? "problem" : "problems"; let summary = pc.bold(pc.red(`\u2716 ${totalIssues} ${problemsText}`)); const parts = []; Object.entries(issueCountsByType).forEach(([type, count]) => { const label = count === 1 ? type : getPluralForm(type); const colorFn = getIssueColor(type); parts.push(colorFn(`${count} ${label}`)); }); if (parts.length > 0) { summary += pc.dim(` (${parts.join(", ")})`); } return summary; } function format(fileIssues) { const formattedFiles = fileIssues.filter((file) => file.issues.length > 0).map(formatFileIssues).filter((formatted) => formatted !== ""); if (formattedFiles.length === 0) { return ""; } const summary = formatSummary(fileIssues); return `${formattedFiles.join("\n\n")} ${summary}`; } function hasErrors(fileIssues) { return fileIssues.some( (file) => file.issues.some( (issue) => issue.type === "sync-needed" || issue.type === "invalid-path" || issue.type === "load-failed" ) ); } function hasIssues(fileIssues) { return fileIssues.some((file) => file.issues.length > 0); } export { format, hasErrors, hasIssues };