{"version":3,"sources":["../src/logger.ts"],"sourcesContent":["import { createRequire } from 'node:module'\nimport os from 'node:os'\nimport { stripVTControlCharacters as strip } from 'node:util'\nimport { parentPort } from 'node:worker_threads'\nimport type { SourceLocation } from '@babel/code-frame'\nimport colors from 'picocolors'\n\nimport { WS_CHECKER_ERROR_EVENT } from './client/index.js'\nimport {\n createFrame,\n lineColLocToBabelLoc,\n tsLikeLocToBabelLoc,\n} from './codeFrame.js'\nimport {\n ACTION_TYPES,\n type ClientDiagnosticPayload,\n DiagnosticLevel,\n type DiagnosticToRuntime,\n} from './types.js'\nimport { isMainThread } from './utils.js'\n\nconst _require = createRequire(import.meta.url)\n\nimport type { ESLint } from 'eslint'\nimport type Stylelint from 'stylelint'\nimport type {\n flattenDiagnosticMessageText as flattenDiagnosticMessageTextType,\n Diagnostic as TsDiagnostic,\n} from 'typescript'\n\nexport interface NormalizedDiagnostic {\n /** error message */\n message?: string\n /** error conclusion */\n conclusion?: string\n /** error stack */\n stack?: string | string[]\n /** file name */\n id?: string\n /** checker diagnostic source */\n checker: string\n /** raw code frame generated by @babel/code-frame */\n codeFrame?: string\n /** code frame, but striped */\n stripedCodeFrame?: string\n /** error code location */\n loc?: SourceLocation\n /** error level */\n level?: DiagnosticLevel\n}\n\nconst defaultLogLevel = [\n DiagnosticLevel.Warning,\n DiagnosticLevel.Error,\n DiagnosticLevel.Suggestion,\n DiagnosticLevel.Message,\n]\n\nexport function filterLogLevel(\n diagnostics: NormalizedDiagnostic,\n level?: DiagnosticLevel[],\n): NormalizedDiagnostic | null\nexport function filterLogLevel(\n diagnostics: NormalizedDiagnostic[],\n level?: DiagnosticLevel[],\n): NormalizedDiagnostic[]\nexport function filterLogLevel(\n diagnostics: NormalizedDiagnostic | NormalizedDiagnostic[],\n level: DiagnosticLevel[] = defaultLogLevel,\n): NormalizedDiagnostic | null | NormalizedDiagnostic[] {\n if (Array.isArray(diagnostics)) {\n return diagnostics.filter((d) => {\n if (typeof d.level !== 'number') return false\n return level.includes(d.level)\n })\n }\n if (!diagnostics.level) return null\n return level.includes(diagnostics.level) ? diagnostics : null\n}\n\nexport function diagnosticToTerminalLog(\n d: NormalizedDiagnostic,\n name?: 'TypeScript' | 'vue-tsc' | 'ESLint' | 'Stylelint' | 'Biome' | 'oxlint',\n): string {\n const nameInLabel = name ? `(${name})` : ''\n const boldBlack = (str: string) => colors.bold(colors.black(str))\n\n const labelMap: Record = {\n [DiagnosticLevel.Error]: boldBlack(\n colors.bgRedBright(` ERROR${nameInLabel} `),\n ),\n [DiagnosticLevel.Warning]: boldBlack(\n colors.bgYellowBright(` WARNING${nameInLabel} `),\n ),\n [DiagnosticLevel.Suggestion]: boldBlack(\n colors.bgBlueBright(` SUGGESTION${nameInLabel} `),\n ),\n [DiagnosticLevel.Message]: boldBlack(\n colors.bgCyanBright(` MESSAGE${nameInLabel} `),\n ),\n }\n\n const levelLabel = labelMap[d.level ?? DiagnosticLevel.Error]\n const fileLabel = `${boldBlack(colors.bgCyanBright(' FILE '))} `\n const position = d.loc\n ? `${colors.yellow(d.loc.start.line)}:${colors.yellow(d.loc.start.column || '')}`\n : ''\n\n return [\n `${levelLabel} ${d.message}`,\n `${fileLabel + d.id}:${position}${os.EOL}`,\n d.codeFrame + os.EOL,\n d.conclusion,\n ]\n .filter(Boolean)\n .join(os.EOL)\n}\n\nexport function diagnosticToConsoleLevel(d: NormalizedDiagnostic) {\n if (!d) return 'error'\n if (d.level === DiagnosticLevel.Message) return 'info'\n if (d.level === DiagnosticLevel.Suggestion) return 'info'\n if (d.level === DiagnosticLevel.Warning) return 'warn'\n return 'error'\n}\n\nexport function diagnosticToRuntimeError(\n d: NormalizedDiagnostic,\n): DiagnosticToRuntime\nexport function diagnosticToRuntimeError(\n d: NormalizedDiagnostic[],\n): DiagnosticToRuntime[]\nexport function diagnosticToRuntimeError(\n diagnostics: NormalizedDiagnostic | NormalizedDiagnostic[],\n): DiagnosticToRuntime | DiagnosticToRuntime[] {\n const diagnosticsArray = Array.isArray(diagnostics)\n ? diagnostics\n : [diagnostics]\n\n const results: DiagnosticToRuntime[] = diagnosticsArray.map((d) => {\n let loc: DiagnosticToRuntime['loc']\n if (d.loc) {\n loc = {\n file: d.id ?? '',\n line: d.loc.start.line,\n column: typeof d.loc.start.column === 'number' ? d.loc.start.column : 0,\n }\n }\n\n return {\n message: d.message ?? '',\n stack:\n typeof d.stack === 'string'\n ? d.stack\n : Array.isArray(d.stack)\n ? d.stack.join(os.EOL)\n : '',\n id: d.id,\n frame: d.stripedCodeFrame,\n checkerId: d.checker,\n level: d.level,\n loc,\n }\n })\n\n return Array.isArray(diagnostics) ? results : results[0]!\n}\n\nexport function toClientPayload(\n id: string,\n diagnostics: DiagnosticToRuntime[],\n): ClientDiagnosticPayload {\n return {\n event: WS_CHECKER_ERROR_EVENT,\n data: {\n checkerId: id,\n diagnostics,\n },\n }\n}\n\nexport function wrapCheckerSummary(\n checkerName: string,\n rawSummary: string,\n): string {\n return `[${checkerName}] ${rawSummary}`\n}\n\nexport function composeCheckerSummary(\n checkerName: string,\n errorCount: number,\n warningCount: number,\n): string {\n const message = `Found ${errorCount} error${\n errorCount > 1 ? 's' : ''\n } and ${warningCount} warning${warningCount > 1 ? 's' : ''}`\n\n const hasError = errorCount > 0\n const hasWarning = warningCount > 0\n const color = hasError ? 'red' : hasWarning ? 'yellow' : 'green'\n return colors[color](wrapCheckerSummary(checkerName, message))\n}\n\n/* ------------------------------- TypeScript ------------------------------- */\n\nexport function normalizeTsDiagnostic(d: TsDiagnostic): NormalizedDiagnostic {\n const fileName = d.file?.fileName\n const {\n flattenDiagnosticMessageText,\n }: {\n flattenDiagnosticMessageText: typeof flattenDiagnosticMessageTextType\n } = _require('typescript')\n\n const message = flattenDiagnosticMessageText(d.messageText, os.EOL)\n\n let loc: SourceLocation | undefined\n const pos =\n d.start === undefined\n ? null\n : d.file?.getLineAndCharacterOfPosition?.(d.start)\n if (\n pos &&\n d.file &&\n typeof d.start === 'number' &&\n typeof d.length === 'number'\n ) {\n loc = tsLikeLocToBabelLoc({\n start: pos,\n end: d.file.getLineAndCharacterOfPosition(d.start + d.length),\n })\n }\n\n let codeFrame: string | undefined\n if (loc) {\n codeFrame = createFrame(d.file!.text, loc)\n }\n\n return {\n message,\n conclusion: '',\n codeFrame,\n stripedCodeFrame: codeFrame && strip(codeFrame),\n id: fileName,\n checker: 'TypeScript',\n loc,\n level: d.category as any as DiagnosticLevel,\n }\n}\n\n/* --------------------------------- vue-tsc -------------------------------- */\n\nexport function normalizeVueTscDiagnostic(\n d: TsDiagnostic,\n): NormalizedDiagnostic {\n const diagnostic = normalizeTsDiagnostic(d)\n diagnostic.checker = 'vue-tsc'\n return diagnostic\n}\n\n/* --------------------------------- ESLint --------------------------------- */\n\nconst isNormalizedDiagnostic = (\n d: NormalizedDiagnostic | null | undefined,\n): d is NormalizedDiagnostic => {\n return Boolean(d)\n}\n\nexport function normalizeEslintDiagnostic(\n diagnostic: ESLint.LintResult,\n): NormalizedDiagnostic[] {\n return diagnostic.messages\n .map((d) => {\n let level = DiagnosticLevel.Error\n switch (d.severity as number) {\n case 0: // off, ignore this\n level = DiagnosticLevel.Error\n return null\n case 1: // warn\n level = DiagnosticLevel.Warning\n break\n case 2: // error\n level = DiagnosticLevel.Error\n break\n }\n\n const loc = lineColLocToBabelLoc(d)\n\n const codeFrame = createFrame(diagnostic.source ?? '', loc)\n\n return {\n message: `${d.message} (${d.ruleId})`,\n conclusion: '',\n codeFrame,\n stripedCodeFrame: codeFrame && strip(codeFrame),\n id: diagnostic.filePath,\n checker: 'ESLint',\n loc,\n level,\n } as any as NormalizedDiagnostic\n })\n .filter(isNormalizedDiagnostic)\n}\n\n/* --------------------------------- Stylelint --------------------------------- */\n\nexport function normalizeStylelintDiagnostic(\n diagnostic: Stylelint.LintResult,\n): NormalizedDiagnostic[] {\n return diagnostic.warnings\n .map((d) => {\n let level = DiagnosticLevel.Error\n switch (d.severity) {\n case 'warning': // warn\n level = DiagnosticLevel.Warning\n break\n case 'error': // error\n level = DiagnosticLevel.Error\n break\n default:\n level = DiagnosticLevel.Error\n return null\n }\n\n const loc = lineColLocToBabelLoc(d)\n\n const codeFrame = createFrame(diagnostic._postcssResult?.css ?? '', loc)\n\n return {\n message: `${d.text} (${d.rule})`,\n conclusion: '',\n codeFrame,\n stripedCodeFrame: codeFrame && strip(codeFrame),\n id: diagnostic.source,\n checker: 'Stylelint',\n loc,\n level,\n } as any as NormalizedDiagnostic\n })\n .filter(isNormalizedDiagnostic)\n}\n\n/* ------------------------------ miscellaneous ----------------------------- */\nexport function ensureCall(callback: CallableFunction) {\n setTimeout(() => {\n callback()\n })\n}\n\nexport function consoleLog(value: string, level: 'info' | 'warn' | 'error') {\n if (isMainThread) {\n console[level](value)\n } else {\n parentPort?.postMessage({\n type: ACTION_TYPES.console,\n level: level,\n payload: value,\n })\n }\n}\n"],"mappings":"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","names":[]}