UNPKG

1.45 kBJavaScriptView Raw
1'use strict';
2const fs = require('fs');
3const equalLength = require('equal-length');
4const codeExcerpt = require('code-excerpt');
5const truncate = require('cli-truncate');
6const chalk = require('./chalk').get();
7
8const formatLineNumber = (lineNumber, maxLineNumber) =>
9 ' '.repeat(Math.max(0, String(maxLineNumber).length - String(lineNumber).length)) + lineNumber;
10
11module.exports = (source, options = {}) => {
12 if (!source.isWithinProject || source.isDependency) {
13 return null;
14 }
15
16 const {file, line} = source;
17 const maxWidth = options.maxWidth || 80;
18
19 let contents;
20 try {
21 contents = fs.readFileSync(file, 'utf8');
22 } catch {
23 return null;
24 }
25
26 const excerpt = codeExcerpt(contents, line, {around: 1});
27 if (!excerpt) {
28 return null;
29 }
30
31 const lines = excerpt.map(item => ({
32 line: item.line,
33 value: truncate(item.value, maxWidth - String(line).length - 5)
34 }));
35
36 const joinedLines = lines.map(line => line.value).join('\n');
37 const extendedLines = equalLength(joinedLines).split('\n');
38
39 return lines
40 .map((item, index) => ({
41 line: item.line,
42 value: extendedLines[index]
43 }))
44 .map(item => {
45 const isErrorSource = item.line === line;
46
47 const lineNumber = formatLineNumber(item.line, line) + ':';
48 const coloredLineNumber = isErrorSource ? lineNumber : chalk.grey(lineNumber);
49 const result = ` ${coloredLineNumber} ${item.value}`;
50
51 return isErrorSource ? chalk.bgRed(result) : result;
52 })
53 .join('\n');
54};