{"version":3,"file":"cli.js","names":["strip"],"sources":["../../../src/checkers/oxlint/cli.ts"],"sourcesContent":["import { execFile } from 'node:child_process'\nimport { stripVTControlCharacters as strip } from 'node:util'\nimport colors from 'picocolors'\nimport { createFrame, offsetRangeToBabelLocation } from '../../codeFrame.js'\nimport { consoleLog, type NormalizedDiagnostic } from '../../logger.js'\nimport { normalizePath, readSources } from '../../sources.js'\nimport { DiagnosticLevel } from '../../types.js'\nimport { parseArgsStringToArgv } from '../stylelint/argv.js'\n\nconst severityMap = {\n error: DiagnosticLevel.Error,\n warning: DiagnosticLevel.Warning,\n info: DiagnosticLevel.Suggestion,\n} as const\n\nexport function mapSeverity(s: string): DiagnosticLevel {\n return severityMap[s as keyof typeof severityMap] ?? DiagnosticLevel.Error\n}\n\nexport function getOxlintCommand(command: string) {\n const parsed = parseArgsStringToArgv(command)\n\n const index = parsed.findIndex((p) => p === '--format' || p === '-f')\n if (index === -1) {\n parsed.push('--format', 'json')\n } else {\n consoleLog(\n colors.yellow(\n 'vite-plugin-checker will force append \"--format json\" to the flags in dev mode, please don\\'t use \"--format\" or \"-f\" flag in \"config.oxlint.lintCommand\".',\n ),\n 'warn',\n )\n\n parsed.splice(index, 2, '--format', 'json')\n }\n\n return parsed\n}\n\nexport function runOxlint(argv: string[], cwd: string) {\n return new Promise((resolve, _reject) => {\n try {\n const child = execFile(\n argv[0]!,\n argv.slice(1),\n {\n cwd,\n maxBuffer: Number.POSITIVE_INFINITY,\n // Required on Windows so execFile can resolve .cmd/.bat shims in\n // node_modules/.bin. Node >=18.20/20.12/22 auto-quotes argv under\n // shell:true, preserving the no-splitting guarantee.\n shell: process.platform === 'win32',\n },\n (_error, stdout, _stderr) => {\n parseOxlintOutput(stdout, cwd)\n .then(resolve)\n .catch(() => resolve([]))\n },\n )\n child.on('error', (error) => {\n logSpawnError(error)\n resolve([])\n })\n } catch (error) {\n logSpawnError(error)\n resolve([])\n }\n })\n}\n\nfunction logSpawnError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error)\n consoleLog(\n colors.yellow(`vite-plugin-checker failed to spawn oxlint: ${message}`),\n 'warn',\n )\n}\n\ntype Span = { offset: number; length: number }\ntype Entry = {\n file: string\n span: Span\n code: string\n message: string\n severity: string\n}\n\nasync function parseOxlintOutput(\n output: string,\n cwd: string,\n): Promise {\n const parsed = safeParseOxlint(output)\n if (!parsed) return []\n\n const entries = getEntries(parsed, cwd)\n if (entries.length === 0) return []\n\n const files = getUniqueFiles(entries)\n const sourceCache = await readSources(files)\n\n return buildDiagnostics(entries, sourceCache)\n}\n\nfunction safeParseOxlint(output: string): OxlintOutput | null {\n try {\n return JSON.parse(output)\n } catch {\n return null\n }\n}\n\nfunction getEntries(parsed: OxlintOutput, cwd: string) {\n return parsed.diagnostics.flatMap(\n ({ filename, labels, code, message, severity }) => {\n const file = normalizePath(filename, cwd)\n\n const [label] = labels\n if (!label) return []\n\n return [\n {\n file,\n span: label.span,\n code,\n message,\n severity,\n },\n ] as Entry[]\n },\n )\n}\n\nfunction getUniqueFiles(entries: Entry[]) {\n return [...new Set(entries.map((e) => e.file))]\n}\n\nfunction buildDiagnostics(entries: Entry[], sources: Map) {\n return entries.flatMap((entry) => {\n const source = sources.get(entry.file)\n if (!source) return []\n\n const loc = offsetRangeToBabelLocation(\n source,\n entry.span.offset,\n entry.span.length,\n )\n const codeFrame = createFrame(source, loc)\n\n return [\n {\n message: `${entry.code}: ${entry.message}`,\n conclusion: '',\n level: mapSeverity(entry.severity),\n checker: 'oxlint',\n id: entry.file,\n codeFrame,\n stripedCodeFrame: codeFrame && strip(codeFrame),\n loc,\n },\n ] as NormalizedDiagnostic[]\n })\n}\n\ntype OxlintOutput = {\n diagnostics: Diagnostic[]\n number_of_files: number\n number_of_rules: number\n threads_count: number\n start_time: number\n}\n\ntype Diagnostic = {\n message: string\n code: string\n severity: string\n causes: unknown[]\n url: string\n help: string\n filename: string\n labels: Label[]\n related: unknown[]\n}\n\ntype Label = {\n label: string\n span: Record<'offset' | 'length' | 'line' | 'column', number>\n}\n"],"mappings":";;;;;;;;;AASA,MAAM,cAAc;CAClB,OAAA;CACA,SAAA;CACA,MAAA;AACF;AAEA,SAAgB,YAAY,GAA4B;CACtD,OAAO,YAAY,MAAA;AACrB;AAEA,SAAgB,iBAAiB,SAAiB;CAChD,MAAM,SAAS,sBAAsB,OAAO;CAE5C,MAAM,QAAQ,OAAO,WAAW,MAAM,MAAM,cAAc,MAAM,IAAI;CACpE,IAAI,UAAU,IACZ,OAAO,KAAK,YAAY,MAAM;MACzB;EACL,WACE,OAAO,OACL,kKACF,GACA,MACF;EAEA,OAAO,OAAO,OAAO,GAAG,YAAY,MAAM;CAC5C;CAEA,OAAO;AACT;AAEA,SAAgB,UAAU,MAAgB,KAAa;CACrD,OAAO,IAAI,SAAiC,SAAS,YAAY;EAC/D,IAAI;GAkBF,SAhBE,KAAK,IACL,KAAK,MAAM,CAAC,GACZ;IACE;IACA,WAAW,OAAO;IAIlB,OAAO,QAAQ,aAAa;GAC9B,IACC,QAAQ,QAAQ,YAAY;IAC3B,kBAAkB,QAAQ,GAAG,CAAC,CAC3B,KAAK,OAAO,CAAC,CACb,YAAY,QAAQ,CAAC,CAAC,CAAC;GAC5B,CAEE,CAAC,CAAC,GAAG,UAAU,UAAU;IAC3B,cAAc,KAAK;IACnB,QAAQ,CAAC,CAAC;GACZ,CAAC;EACH,SAAS,OAAO;GACd,cAAc,KAAK;GACnB,QAAQ,CAAC,CAAC;EACZ;CACF,CAAC;AACH;AAEA,SAAS,cAAc,OAAgB;CACrC,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,WACE,OAAO,OAAO,+CAA+C,SAAS,GACtE,MACF;AACF;AAWA,eAAe,kBACb,QACA,KACiC;CACjC,MAAM,SAAS,gBAAgB,MAAM;CACrC,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,MAAM,UAAU,WAAW,QAAQ,GAAG;CACtC,IAAI,QAAQ,WAAW,GAAG,OAAO,CAAC;CAKlC,OAAO,iBAAiB,SAAS,MAFP,YADZ,eAAe,OACa,CAAC,CAEC;AAC9C;AAEA,SAAS,gBAAgB,QAAqC;CAC5D,IAAI;EACF,OAAO,KAAK,MAAM,MAAM;CAC1B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,WAAW,QAAsB,KAAa;CACrD,OAAO,OAAO,YAAY,SACvB,EAAE,UAAU,QAAQ,MAAM,SAAS,eAAe;EACjD,MAAM,OAAO,cAAc,UAAU,GAAG;EAExC,MAAM,CAAC,SAAS;EAChB,IAAI,CAAC,OAAO,OAAO,CAAC;EAEpB,OAAO,CACL;GACE;GACA,MAAM,MAAM;GACZ;GACA;GACA;EACF,CACF;CACF,CACF;AACF;AAEA,SAAS,eAAe,SAAkB;CACxC,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC;AAChD;AAEA,SAAS,iBAAiB,SAAkB,SAA8B;CACxE,OAAO,QAAQ,SAAS,UAAU;EAChC,MAAM,SAAS,QAAQ,IAAI,MAAM,IAAI;EACrC,IAAI,CAAC,QAAQ,OAAO,CAAC;EAErB,MAAM,MAAM,2BACV,QACA,MAAM,KAAK,QACX,MAAM,KAAK,MACb;EACA,MAAM,YAAY,YAAY,QAAQ,GAAG;EAEzC,OAAO,CACL;GACE,SAAS,GAAG,MAAM,KAAK,IAAI,MAAM;GACjC,YAAY;GACZ,OAAO,YAAY,MAAM,QAAQ;GACjC,SAAS;GACT,IAAI,MAAM;GACV;GACA,kBAAkB,aAAaA,yBAAM,SAAS;GAC9C;EACF,CACF;CACF,CAAC;AACH"}