lintpage 0.4.1 → 0.5.1

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"formatter-CuMgo6fc.mjs","names":[],"sources":["../src/formatter.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { PageResult, Severity } from '@lintpage/core';\n\nexport type Format = 'text' | 'json' | 'github';\n\n// ── Text formatter ─────────────────────────────────────────────\n\nconst SEVERITY_ICON: Record<Severity, string> = {\n CRITICAL: chalk.red.bold('✗'),\n WARNING: chalk.yellow('⚠'),\n INFO: chalk.blue('ℹ'),\n};\n\nfunction buildVerdict(\n counts: { crit: number; warn: number; info: number },\n status: PageResult['overallStatus'],\n): string {\n const w = `${counts.warn} ${counts.warn === 1 ? 'warning' : 'warnings'}`;\n if (status === 'FAIL') {\n return `DEPLOY BLOCKED · ${counts.crit} critical · ${w} · ${counts.info} info`;\n }\n if (status === 'AI-FAIL') {\n return `AI VISIBILITY FAIL · ${counts.crit} AI critical · ${w} · ${counts.info} info`;\n }\n return `READY TO SHIP · ${w} · ${counts.info} info`;\n}\n\nexport function formatText(result: PageResult, quiet: boolean): string {\n const lines: string[] = [];\n const counts = {\n crit: result.results.filter((r) => r.severity === 'CRITICAL').length,\n warn: result.results.filter((r) => r.severity === 'WARNING').length,\n info: result.results.filter((r) => r.severity === 'INFO').length,\n };\n\n if (quiet) {\n lines.push(\n ` ${chalk.red.bold(`${counts.crit} critical`)} ${chalk.yellow(\n `${counts.warn} ${counts.warn === 1 ? 'warning' : 'warnings'}`,\n )} ${chalk.blue(`${counts.info} info`)}`,\n );\n lines.push('');\n return lines.join('\\n');\n }\n\n lines.push('');\n\n if (result.results.length === 0) {\n lines.push(chalk.green(' No issues found.'));\n lines.push('');\n } else {\n const sorted = [...result.results].sort(\n (a, b) => severityRank(b.severity) - severityRank(a.severity),\n );\n sorted.forEach((issue, idx) => {\n const icon = SEVERITY_ICON[issue.severity];\n const path = `${issue.category.toLowerCase()}/${issue.ruleId}`;\n lines.push(`${icon} ${chalk.bold(path)} — ${issue.message}`);\n if (issue.fix) {\n lines.push(` ${chalk.dim(issue.fix)}`);\n }\n if (idx < sorted.length - 1) {\n lines.push('');\n }\n });\n lines.push('');\n }\n\n const verdict = buildVerdict(counts, result.overallStatus);\n const colour =\n result.overallStatus === 'FAIL'\n ? chalk.red.bold\n : result.overallStatus === 'AI-FAIL'\n ? chalk.yellow.bold\n : chalk.green.bold;\n lines.push(colour(verdict));\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction severityRank(s: Severity): number {\n return s === 'CRITICAL' ? 3 : s === 'WARNING' ? 2 : 1;\n}\n\n// ── JSON formatter ─────────────────────────────────────────────\n\nexport function formatJson(result: PageResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n// ── GitHub Actions formatter ───────────────────────────────────\n\nconst GH_LEVEL: Record<Severity, string> = {\n CRITICAL: 'error',\n WARNING: 'warning',\n INFO: 'notice',\n};\n\n/**\n * Sanitize a string for use in GitHub Actions workflow commands.\n * Escapes characters that could break or inject annotations.\n * @see https://github.com/actions/toolkit/blob/main/packages/core/src/command.ts\n */\nfunction sanitizeAnnotation(str: string): string {\n return str\n .replace(/%/g, '%25')\n .replace(/\\r/g, '%0D')\n .replace(/\\n/g, '%0A')\n .replace(/:/g, '%3A')\n .replace(/,/g, '%2C');\n}\n\nexport function formatGithub(result: PageResult): string {\n const lines: string[] = [];\n\n for (const issue of result.results) {\n const level = GH_LEVEL[issue.severity];\n const title = sanitizeAnnotation(`[${issue.ruleId}] ${issue.ruleName}`);\n const message = sanitizeAnnotation(issue.message);\n // GitHub annotation format: ::level title=TITLE::MESSAGE\n lines.push(`::${level} title=${title}::${message}`);\n }\n\n // Summary annotation\n const counts = {\n crit: result.results.filter((r) => r.severity === 'CRITICAL').length,\n warn: result.results.filter((r) => r.severity === 'WARNING').length,\n info: result.results.filter((r) => r.severity === 'INFO').length,\n };\n const verdict = buildVerdict(counts, result.overallStatus);\n const summaryMessage = sanitizeAnnotation(`${result.url} — ${verdict}`);\n lines.push(`::notice title=LintPage Verdict::${summaryMessage}`);\n\n return lines.join('\\n');\n}\n\n// ── Dispatcher ─────────────────────────────────────────────────\n\nexport function format(\n result: PageResult,\n fmt: Format,\n quiet: boolean\n): string {\n switch (fmt) {\n case 'json':\n return formatJson(result);\n case 'github':\n return formatGithub(result);\n case 'text':\n default:\n return formatText(result, quiet);\n }\n}\n"],"mappings":"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"}