{"version":3,"sources":["../src/formatters/github.ts","../src/formatters/json.ts","../src/formatters/pretty.ts","../src/formatters/index.ts","../src/collapse.ts","../src/framework-filter.ts","../src/presets.ts","../src/severity.ts","../src/lint.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { LintDiagnostic, LintResult } from '../types.ts';\n\nconst MAX_ANNOTATIONS = 50;\n\nfunction severityToGitHub(severity: LintDiagnostic['severity']): string {\n  if (severity === 'error') return 'error';\n  if (severity === 'warning') return 'warning';\n  return 'notice';\n}\n\nexport function formatGitHub(results: LintResult[]): string {\n  const lines: string[] = [];\n  let count = 0;\n\n  for (const result of results) {\n    const file = result.filePath ?? '<stdin>';\n\n    for (const d of result.diagnostics) {\n      if (count >= MAX_ANNOTATIONS) break;\n\n      const level = d.suppressedByFramework ? 'notice' : severityToGitHub(d.severity);\n      const line = d.position?.start.line ?? 1;\n      const col = d.position?.start.column ?? 1;\n      const variantCount = d.variants.length;\n      const suffix = `[${d.family} ${variantCount}/${d.familySize}]`;\n\n      lines.push(\n        `::${level} file=${file},line=${line},col=${col},title=${d.title}::${d.message} ${suffix}`\n      );\n      count++;\n    }\n\n    if (count >= MAX_ANNOTATIONS) break;\n  }\n\n  return lines.join('\\n');\n}\n","import type { LintResult } from '../types.ts';\n\nexport function formatJson(results: LintResult[]): string {\n  return JSON.stringify(results, null, 2);\n}\n","import pc from 'picocolors';\n\nimport type { LintDiagnostic, LintResult } from '../types.ts';\n\nexport interface PrettyFormatterOpts {\n  /** When true, expand collapsed diagnostics to one line per variant. */\n  verbose?: boolean;\n}\n\nfunction severityColor(severity: LintDiagnostic['severity'], text: string): string {\n  if (severity === 'error') return pc.red(text);\n  if (severity === 'warning') return pc.yellow(text);\n  return pc.dim(text);\n}\n\nfunction variantSummary(d: LintDiagnostic): string {\n  const n = d.variants.length;\n  const total = d.familySize;\n  if (total <= 1) return '';\n  if (n >= total) return `(${total}/${total} variants)`;\n  return `(${n}/${total} variants: ${d.variants.join(', ')})`;\n}\n\nfunction baseMessage(d: LintDiagnostic): string {\n  const summary = variantSummary(d);\n  return summary ? `${d.message} ${summary}` : d.message;\n}\n\nfunction formatLine(d: LintDiagnostic, msg: string): string {\n  const loc = d.position ? `${d.position.start.line}:${d.position.start.column}` : '0:0';\n  const sev = severityColor(d.severity, d.severity);\n  return `  ${loc}  ${sev}  ${msg}  ${pc.dim(`[${d.family}]`)}`;\n}\n\nfunction formatDiagnostic(d: LintDiagnostic, verbose: boolean): string[] {\n  if (!verbose || d.variants.length <= 1) {\n    return [formatLine(d, baseMessage(d))];\n  }\n  // Expand one line per variant when --verbose\n  return d.variants.map((variant) => formatLine(d, `${d.message} [${d.family}.${variant}]`));\n}\n\nfunction sortByLine(diagnostics: LintDiagnostic[]): LintDiagnostic[] {\n  return [...diagnostics].sort((a, b) => {\n    const aLine = a.position?.start.line ?? 0;\n    const bLine = b.position?.start.line ?? 0;\n    return aLine - bLine;\n  });\n}\n\nexport function formatPretty(results: LintResult[], opts?: PrettyFormatterOpts): string {\n  const verbose = opts?.verbose === true;\n  const lines: string[] = [];\n\n  let totalErrors = 0;\n  let totalWarnings = 0;\n\n  for (const result of results) {\n    totalErrors += result.errorCount;\n    totalWarnings += result.warningCount;\n\n    if (result.diagnostics.length === 0) continue;\n\n    const filePath = result.filePath ?? '<stdin>';\n    const visible = result.diagnostics.filter((d) => d.suppressedByFramework !== true);\n    const suppressed = result.diagnostics.filter((d) => d.suppressedByFramework === true);\n\n    lines.push('');\n    lines.push(pc.underline(filePath));\n\n    for (const d of sortByLine(visible)) {\n      for (const line of formatDiagnostic(d, verbose)) {\n        lines.push(line);\n      }\n    }\n\n    if (suppressed.length > 0) {\n      lines.push('');\n      lines.push(pc.dim('── Ignored (framework) ──'));\n      for (const d of sortByLine(suppressed)) {\n        lines.push(pc.dim(formatLine(d, baseMessage(d))));\n      }\n    }\n  }\n\n  const parts: string[] = [];\n  if (totalErrors > 0) parts.push(`${totalErrors} error${totalErrors === 1 ? '' : 's'}`);\n  if (totalWarnings > 0) parts.push(`${totalWarnings} warning${totalWarnings === 1 ? '' : 's'}`);\n\n  if (parts.length > 0) {\n    lines.push('');\n    lines.push(`${pc.red('\\u2716')} ${parts.join(', ')}`);\n  }\n\n  lines.push('');\n  return lines.join('\\n');\n}\n","import type { LintResult } from '../types.ts';\nimport { formatGitHub } from './github.ts';\nimport { formatJson } from './json.ts';\nimport { formatPretty, type PrettyFormatterOpts } from './pretty.ts';\n\nexport interface FormatterOpts extends PrettyFormatterOpts {}\n\nexport type Formatter = (results: LintResult[], opts?: FormatterOpts) => string;\n\nconst formatters: Record<string, Formatter> = {\n  pretty: formatPretty,\n  json: formatJson,\n  github: formatGitHub,\n};\n\nexport function getFormatter(name: string): Formatter {\n  const formatter = formatters[name];\n  if (!formatter) {\n    throw new Error(`Unknown format \"${name}\". Valid: ${Object.keys(formatters).join(', ')}`);\n  }\n  return formatter;\n}\n\nexport { formatGitHub } from './github.ts';\nexport { formatJson } from './json.ts';\nexport { formatPretty } from './pretty.ts';\n","import type { LintDiagnostic, Severity, SupportLevel } from './types.ts';\n\n/**\n * Internal per-variant row emitted by the caniemail pass, before collapsing by family.\n * Not exported from the package — only used between the caniemail call and `collapseByFamily`.\n */\nexport interface ProtoDiagnostic {\n  severity: Severity;\n  title: string;\n  message: string;\n  notes: string[];\n  support: SupportLevel;\n  /** Full caniemail client identifier — e.g., \"gmail.android\". */\n  client: string;\n  position?: LintDiagnostic['position'];\n}\n\n/**\n * Mirrored from caniemail@1.0.5 `clientNames` — we can't deep-import it because\n * caniemail's package.json `exports` field only publishes `.`. Update this list when\n * caniemail adds/removes clients.\n */\nconst CANIEMAIL_CLIENT_NAMES = [\n  'apple-mail.macos',\n  'apple-mail.ios',\n  'gmail.desktop-webmail',\n  'gmail.ios',\n  'gmail.android',\n  'gmail.mobile-webmail',\n  'orange.desktop-webmail',\n  'orange.ios',\n  'orange.android',\n  'outlook.windows',\n  'outlook.windows-mail',\n  'outlook.macos',\n  'outlook.ios',\n  'outlook.android',\n  'yahoo.desktop-webmail',\n  'yahoo.ios',\n  'yahoo.android',\n  'aol.desktop-webmail',\n  'aol.ios',\n  'aol.android',\n  'samsung-email.android',\n  'sfr.desktop-webmail',\n  'sfr.ios',\n  'sfr.android',\n  'thunderbird.macos',\n  'protonmail.desktop-webmail',\n  'protonmail.ios',\n  'protonmail.android',\n  'hey.desktop-webmail',\n  'mail-ru.desktop-webmail',\n  'fastmail.desktop-webmail',\n  'laposte.desktop-webmail',\n] as const;\n\nfunction familyOf(client: string): string {\n  const dot = client.indexOf('.');\n  return dot === -1 ? client : client.slice(0, dot);\n}\n\nfunction variantOf(client: string): string {\n  const dot = client.indexOf('.');\n  return dot === -1 ? '' : client.slice(dot + 1);\n}\n\n/**\n * Family sizes derived once from the canonical client list.\n * Example: { gmail: 4, outlook: 5, 'apple-mail': 2, ... }\n */\nexport const FAMILY_SIZES: Record<string, number> = (() => {\n  const sizes: Record<string, number> = {};\n  for (const client of CANIEMAIL_CLIENT_NAMES) {\n    const family = familyOf(client);\n    sizes[family] = (sizes[family] ?? 0) + 1;\n  }\n  return sizes;\n})();\n\nfunction positionKey(position: ProtoDiagnostic['position']): string {\n  if (!position) return '-';\n  return `${position.start.line}:${position.start.column}-${position.end.line}:${position.end.column}`;\n}\n\n/**\n * Group ProtoDiagnostics by (title, family, position). Each group collapses to a single\n * LintDiagnostic carrying all matched variants and the family's total size.\n *\n * Collapse key: `title × family × position`. Diagnostics at different positions stay\n * distinct; diagnostics missing position collapse within family+title.\n */\nexport function collapseByFamily(protos: ProtoDiagnostic[]): LintDiagnostic[] {\n  const groups = new Map<string, LintDiagnostic>();\n  const order: string[] = [];\n\n  for (const proto of protos) {\n    const family = familyOf(proto.client);\n    const variant = variantOf(proto.client);\n    const key = `${proto.title}|${family}|${positionKey(proto.position)}`;\n\n    const existing = groups.get(key);\n    if (existing) {\n      if (variant && !existing.variants.includes(variant)) {\n        existing.variants.push(variant);\n      }\n      continue;\n    }\n\n    groups.set(key, {\n      severity: proto.severity,\n      title: proto.title,\n      message: proto.message,\n      notes: proto.notes,\n      support: proto.support,\n      family,\n      variants: variant ? [variant] : [],\n      familySize: FAMILY_SIZES[family] ?? 1,\n      position: proto.position,\n    });\n    order.push(key);\n  }\n\n  return order.map((key) => groups.get(key) as LintDiagnostic);\n}\n","import type { LintDiagnostic } from './types.ts';\n\ntype FrameworkRule = 'preview' | 'preload-image' | 'target-blank';\n\ninterface Region {\n  /** Inclusive start offset in the raw html string. */\n  start: number;\n  /** Exclusive end offset in the raw html string. */\n  end: number;\n  rule: FrameworkRule;\n  /** If set, only diagnostics with this title match inside this region. */\n  titleMatch?: string;\n}\n\n/**\n * Convert a 1-indexed (line, col) position to a 0-indexed character offset in the\n * raw html string. Returns -1 if the position is out of bounds.\n */\nfunction offsetOf(html: string, line: number, col: number): number {\n  let offset = 0;\n  let currentLine = 1;\n  while (currentLine < line) {\n    const nl = html.indexOf('\\n', offset);\n    if (nl === -1) return -1;\n    offset = nl + 1;\n    currentLine++;\n  }\n  return offset + (col - 1);\n}\n\n/**\n * Find the character range `[openStart, closeEnd)` spanning a tag and its matching\n * closing tag (e.g., `<div ...>...</div>`). Uses naive linear lookup — sufficient\n * for react-email's well-formed output. Returns the end of the opening tag only if\n * no closing tag is found (e.g., self-closing or malformed).\n */\nfunction rangeOfTag(html: string, tagName: string, openEnd: number): number {\n  const closeTag = `</${tagName}>`;\n  const lowerHtml = html.toLowerCase();\n  const closeIdx = lowerHtml.indexOf(closeTag.toLowerCase(), openEnd);\n  if (closeIdx === -1) return openEnd;\n  return closeIdx + closeTag.length;\n}\n\nfunction findPreviewRegions(html: string): Region[] {\n  // Match any opening tag carrying `data-skip-in-text=\"true\"` (react-email uses this\n  // on <Preview> and plain-text-only markup).\n  const re = /<(\\w+)\\b[^>]*\\bdata-skip-in-text\\s*=\\s*(?:\"true\"|'true'|true)[^>]*>/gi;\n  const regions: Region[] = [];\n  let m: RegExpExecArray | null;\n  m = re.exec(html);\n  while (m !== null) {\n    const tagName = m[1];\n    const openStart = m.index;\n    const openEnd = openStart + m[0].length;\n    const end = rangeOfTag(html, tagName, openEnd);\n    regions.push({ start: openStart, end, rule: 'preview' });\n    m = re.exec(html);\n  }\n  return regions;\n}\n\nfunction findPreloadImageRegions(html: string): Region[] {\n  // Match `<link rel=\"preload\" as=\"image\" ...>` in any attribute order. Self-closing or not.\n  const re = /<link\\b[^>]*?>/gi;\n  const regions: Region[] = [];\n  let m: RegExpExecArray | null;\n  m = re.exec(html);\n  while (m !== null) {\n    const tag = m[0];\n    if (/\\brel\\s*=\\s*[\"']?preload[\"']?/i.test(tag) && /\\bas\\s*=\\s*[\"']?image[\"']?/i.test(tag)) {\n      regions.push({ start: m.index, end: m.index + tag.length, rule: 'preload-image' });\n    }\n    m = re.exec(html);\n  }\n  return regions;\n}\n\nfunction findTargetBlankRegions(html: string): Region[] {\n  // Match `<a ... target=\"_blank\" ...>...</a>` regions; title-filtered so only the\n  // target-attribute diagnostic inside gets marked.\n  const re = /<a\\b[^>]*?\\btarget\\s*=\\s*(?:\"_blank\"|'_blank'|_blank)[^>]*?>/gi;\n  const regions: Region[] = [];\n  let m: RegExpExecArray | null;\n  m = re.exec(html);\n  while (m !== null) {\n    const openStart = m.index;\n    const openEnd = openStart + m[0].length;\n    const end = rangeOfTag(html, 'a', openEnd);\n    regions.push({ start: openStart, end, rule: 'target-blank', titleMatch: 'target attribute' });\n    m = re.exec(html);\n  }\n  return regions;\n}\n\n/**\n * Mark diagnostics that fall inside framework-known regions as `suppressedByFramework`.\n *\n * Does NOT remove marked diagnostics from the array — `lint()` owns the keep/drop\n * decision based on `config.showIgnored`. This keeps the filter testable in isolation\n * (input n diagnostics → output n diagnostics, some annotated).\n *\n * Match strategy: regex-based structural matching on the raw html string. Three rules:\n *   (a) `<... data-skip-in-text=\"true\" ...>` → `frameworkRule: \"preview\"`\n *   (b) `<link rel=\"preload\" as=\"image\" ...>` → `frameworkRule: \"preload-image\"`\n *   (c) `<a ... target=\"_blank\" ...>` with `title === \"target attribute\"` →\n *       `frameworkRule: \"target-blank\"`\n *\n * Fallback for diagnostics missing position: if `title === \"target attribute\"` and the\n * html contains any `<a ... target=\"_blank\">`, mark it anyway. Documented inline —\n * rare but possible when caniemail fails to emit position data.\n */\nexport function applyFrameworkFilter(\n  diagnostics: LintDiagnostic[],\n  html: string,\n  framework: 'react-email'\n): LintDiagnostic[] {\n  if (framework !== 'react-email') return diagnostics;\n\n  const regions: Region[] = [\n    ...findPreviewRegions(html),\n    ...findPreloadImageRegions(html),\n    ...findTargetBlankRegions(html),\n  ];\n\n  return diagnostics.map((d) => {\n    const offset = d.position ? offsetOf(html, d.position.start.line, d.position.start.column) : -1;\n\n    for (const region of regions) {\n      if (region.titleMatch && d.title !== region.titleMatch) continue;\n\n      if (offset >= 0 && offset >= region.start && offset < region.end) {\n        return { ...d, suppressedByFramework: true, frameworkRule: region.rule };\n      }\n\n      // Fallback for title-matched rules when position is missing: any target-blank\n      // region in the html suppresses the title-attribute diagnostic.\n      if (\n        offset === -1 &&\n        region.titleMatch &&\n        d.title === region.titleMatch &&\n        region.rule === 'target-blank'\n      ) {\n        return { ...d, suppressedByFramework: true, frameworkRule: region.rule };\n      }\n    }\n\n    return d;\n  });\n}\n","import type { CanIEmailOptions } from 'caniemail';\n\ntype ClientGlobs = CanIEmailOptions['clients'];\n\nconst presets: Record<string, ClientGlobs> = {\n  gmail: ['gmail.*'],\n  outlook: ['outlook.*'],\n  'apple-mail': ['apple-mail.*'],\n  yahoo: ['yahoo.*'],\n  'all-clients': ['*'],\n};\n\nexport const PRESET_NAMES = Object.keys(presets);\n\nexport function resolvePreset(name: string): ClientGlobs {\n  const names = name\n    .split(',')\n    .map((n) => n.trim())\n    .filter((n) => n.length > 0);\n\n  if (names.length === 0) {\n    throw new Error(`Empty preset. Valid: ${PRESET_NAMES.join(', ')}`);\n  }\n\n  const clients = new Set<ClientGlobs[number]>();\n  for (const n of names) {\n    const preset = presets[n];\n    if (!preset) {\n      throw new Error(`Unknown preset \"${n}\". Valid: ${PRESET_NAMES.join(', ')}`);\n    }\n    for (const glob of preset) {\n      clients.add(glob);\n    }\n  }\n\n  return [...clients];\n}\n\n/** Split a comma-separated list into trimmed, non-empty entries. */\nfunction splitList(value: string): string[] {\n  return value\n    .split(',')\n    .map((v) => v.trim())\n    .filter((v) => v.length > 0);\n}\n\n/**\n * Predicate that answers \"should this client be linted?\".\n *\n * Exclusion is applied to the results rather than the request, because\n * caniemail's glob syntax has no negation and the helpers that expand a glob\n * to concrete client names (`parseClients`, `clientNames`) are not re-exported\n * from its package root -- its `exports` map only exposes `.` and the raw JSON.\n * Filtering what comes back needs neither.\n *\n * Accepted forms, matching the glob shapes caniemail itself takes:\n * `orange` (bare provider, the shape people type), `orange.ios`, `*.ios`, `*`.\n */\nexport function makeClientFilter(exclude?: string): (client: string) => boolean {\n  if (!exclude) {\n    return () => true;\n  }\n\n  const patterns = splitList(exclude);\n  if (patterns.length === 0) {\n    return () => true;\n  }\n\n  const matches = (pattern: string, client: string): boolean => {\n    if (pattern === '*') {\n      return true;\n    }\n    const [provider, platform] = pattern.includes('.')\n      ? pattern.split('.')\n      : [pattern, '*'];\n    const [clientProvider, clientPlatform] = client.split('.');\n    return (\n      (provider === '*' || provider === clientProvider) &&\n      (platform === '*' || platform === clientPlatform)\n    );\n  };\n\n  return (client: string) => !patterns.some((p) => matches(p, client));\n}\n","import type { ProtoDiagnostic } from './collapse.ts';\n\n/**\n * Matches `<a ... target=\"_blank\" ...>` tags. Case-insensitive on tag/attr; quote-agnostic.\n * Lets us tell when the author actually used target=\"_blank\" (which gmail forces anyway)\n * vs target=\"_self\" (the real authoring mistake for gmail).\n */\nconst A_TARGET_BLANK_RE = /<a\\b[^>]*?\\btarget\\s*=\\s*(?:\"_blank\"|'_blank'|_blank)[^>]*?>/i;\n\n/**\n * Matches a bare `transform` property in a style attribute (not `text-transform`).\n * caniemail incorrectly reports `text-transform` with the title \"transform\".\n * If the element only uses `text-transform` and not bare `transform`, the diagnostic\n * is a false positive.\n */\nconst BARE_TRANSFORM_RE = /(?<![a-z-])transform\\s*:/i;\n\n/**\n * Extract the opening tag at (line, column) from the HTML string.\n * Returns the full `<tag ...>` string, or undefined if not found.\n */\nfunction extractElement(html: string, line: number, column: number): string | undefined {\n  const lines = html.split('\\n');\n  if (line < 1 || line > lines.length) return undefined;\n  const offset = lines.slice(0, line - 1).reduce((sum, l) => sum + l.length + 1, 0) + (column - 1);\n  if (html[offset] !== '<') return undefined;\n  const close = html.indexOf('>', offset);\n  if (close === -1) return undefined;\n  return html.slice(offset, close + 1);\n}\n\nfunction appendNoteToMessage(message: string, notes: string[]): string {\n  if (notes.length === 0) return message;\n  return `${message} — ${notes[0]}`;\n}\n\n/**\n * Apply project-specific severity and message rules to a ProtoDiagnostic.\n *\n * Rules (applied in order):\n *   (a) `title === \"cursor\"` → `severity: \"info\"` (cosmetic-only in email).\n *   (b) `title === \"target attribute\"` AND `family === \"gmail\"` AND note mentions\n *       \"forced\": if html already uses `target=\"_blank\"`, drop to `\"info\"`\n *       (rank-don't-suppress — gmail forces this anyway). Otherwise downgrade to\n *       `\"warning\"` because the author's intent might be `_self` which gmail breaks.\n *   (c) `support === \"partial\"` stays at its existing severity (warning from the\n *       caniemail bucket) — no-op safety.\n *\n * Also enriches `message` with the first resolved note when present:\n *   `\"<message> — <first note>\"`.\n *\n * Pure function: returns a new proto with adjusted severity/message. Runs per-proto\n * (before collapse) so that identically-transformed diagnostics collapse together.\n */\nexport function applySeverityRules(proto: ProtoDiagnostic, html: string): ProtoDiagnostic {\n  const message = appendNoteToMessage(proto.message, proto.notes);\n  const family = proto.client.split('.')[0];\n\n  if (proto.title === 'cursor') {\n    return { ...proto, severity: 'info', message };\n  }\n\n  // caniemail reports `text-transform` as \"transform\" (false positive).\n  // Check the actual element: if it has `text-transform` but no bare `transform:`,\n  // suppress by downgrading to info.\n  if (proto.title === 'transform' && proto.position) {\n    const element = extractElement(html, proto.position.start.line, proto.position.start.column);\n    if (element && !BARE_TRANSFORM_RE.test(element)) {\n      return { ...proto, severity: 'info', message };\n    }\n  }\n\n  if (\n    proto.title === 'target attribute' &&\n    family === 'gmail' &&\n    proto.notes.some((n) => n.toLowerCase().includes('forced'))\n  ) {\n    const severity = A_TARGET_BLANK_RE.test(html) ? 'info' : 'warning';\n    return { ...proto, severity, message };\n  }\n\n  return { ...proto, message };\n}\n","import { caniemail, formatIssue } from 'caniemail';\n\nimport { collapseByFamily, type ProtoDiagnostic } from './collapse.ts';\nimport { applyFrameworkFilter } from './framework-filter.ts';\nimport { makeClientFilter, resolvePreset } from './presets.ts';\nimport { applySeverityRules } from './severity.ts';\nimport type { LintConfig, LintDiagnostic, LintResult } from './types.ts';\n\nexport function lint(html: string, config?: LintConfig): LintResult {\n  const clients = resolvePreset(config?.preset ?? 'all-clients');\n  const keepClient = makeClientFilter(config?.exclude);\n  const result = caniemail({ html, clients });\n\n  const protos: ProtoDiagnostic[] = [];\n\n  for (const [client, issues] of result.issues.errors) {\n    if (!keepClient(client)) {\n      continue;\n    }\n    for (const issue of issues) {\n      const formatted = formatIssue({ client, issue, issueType: 'error' });\n      protos.push(\n        applySeverityRules(\n          {\n            severity: 'error',\n            title: issue.title,\n            message: formatted.message,\n            notes: formatted.notes,\n            support: issue.support,\n            client,\n            position: issue.position\n              ? {\n                  start: { line: issue.position.start.line, column: issue.position.start.column },\n                  end: { line: issue.position.end.line, column: issue.position.end.column },\n                }\n              : undefined,\n          },\n          html\n        )\n      );\n    }\n  }\n\n  for (const [client, issues] of result.issues.warnings) {\n    if (!keepClient(client)) {\n      continue;\n    }\n    for (const issue of issues) {\n      const formatted = formatIssue({ client, issue, issueType: 'warning' });\n      protos.push(\n        applySeverityRules(\n          {\n            severity: 'warning',\n            title: issue.title,\n            message: formatted.message,\n            notes: formatted.notes,\n            support: issue.support,\n            client,\n            position: issue.position\n              ? {\n                  start: { line: issue.position.start.line, column: issue.position.start.column },\n                  end: { line: issue.position.end.line, column: issue.position.end.column },\n                }\n              : undefined,\n          },\n          html\n        )\n      );\n    }\n  }\n\n  let diagnostics = collapseByFamily(protos);\n\n  if (config?.framework) {\n    diagnostics = applyFrameworkFilter(diagnostics, html, config.framework);\n    diagnostics = finalizeFrameworkFilter(diagnostics, config.showIgnored === true);\n  }\n\n  const errorCount = diagnostics.filter((d) => d.severity === 'error').length;\n  const warningCount = diagnostics.filter((d) => d.severity === 'warning').length;\n\n  return {\n    diagnostics,\n    errorCount,\n    warningCount,\n    success: errorCount === 0,\n  };\n}\n\n/**\n * After the framework filter marks diagnostics, either drop them (default) or keep\n * them but downgrade severity to `info` so counts don't lie and formatters can render\n * them in a separate section.\n */\nfunction finalizeFrameworkFilter(\n  diagnostics: LintDiagnostic[],\n  showIgnored: boolean\n): LintDiagnostic[] {\n  if (!showIgnored) {\n    return diagnostics.filter((d) => d.suppressedByFramework !== true);\n  }\n  return diagnostics.map((d) =>\n    d.suppressedByFramework ? { ...d, severity: 'info' as const } : d\n  );\n}\n"]}