UNPKG

twoslash-eslint

Version:
85 lines (80 loc) 2.5 kB
'use strict'; const eslint = require('eslint'); const twoslashProtocol = require('twoslash-protocol'); function createTwoslasher(options) { const { includeDocs = true, mergeMessages = true } = options; const linter = new eslint.Linter({ cwd: options.cwd, configType: "flat" }); let docsMap; function getDocsMap() { if (!docsMap) { docsMap = /* @__PURE__ */ new Map(); for (const config of options.eslintConfig) { Object.entries(config.plugins || {}).forEach(([pluginName, plugin]) => { Object.entries(plugin?.rules || {}).forEach(([ruleName, rule]) => { if ("meta" in rule) { const docs = rule.meta?.docs?.url; if (docs) docsMap.set(`${pluginName}/${ruleName}`, docs); } }); }); } } return docsMap; } return (code, file) => { const filename = file?.includes(".") ? file : `index.${file ?? "ts"}`; const messages = linter.verify( options.eslintCodePreprocess?.(code) || code, options.eslintConfig, { filename } ); const pc = twoslashProtocol.createPositionConverter(code); const raws = messages.map((message) => { const start = pc.posToIndex(message.line - 1, message.column - 1); const end = message.endLine != null && message.endColumn != null ? pc.posToIndex(message.endLine - 1, message.endColumn - 1) : start + 1; let text = message.message; if (message.ruleId) { const link = includeDocs && getDocsMap().get(message.ruleId); text += link ? ` ([${message.ruleId}](${link}))` : ` (${message.ruleId})`; } return { type: "error", id: message.ruleId || "", code: 0, text, start, length: end - start, level: message.severity === 2 ? "error" : "warning", filename }; }); let merged = []; if (mergeMessages) { for (const current of raws) { const existing = merged.find((r) => r.start === current.start && r.length === current.length); if (existing) { existing.text += ` ${current.text}`; continue; } merged.push(current); } } else { merged = raws; } const nodes = twoslashProtocol.resolveNodePositions(merged, code).filter((i) => i.line < pc.lines.length); const results = { code, nodes }; return results; }; } exports.createTwoslasher = createTwoslasher;