137 lines
3.1 KiB
TypeScript
137 lines
3.1 KiB
TypeScript
import chalk from 'next/dist/compiled/chalk'
|
|
import path from 'path'
|
|
|
|
// eslint-disable-next-line no-shadow
|
|
export enum MessageSeverity {
|
|
Warning = 1,
|
|
Error = 2,
|
|
}
|
|
|
|
interface LintMessage {
|
|
ruleId: string | null
|
|
severity: 1 | 2
|
|
message: string
|
|
line: number
|
|
column: number
|
|
}
|
|
|
|
export interface LintResult {
|
|
filePath: string
|
|
messages: LintMessage[]
|
|
errorCount: number
|
|
warningCount: number
|
|
output?: string
|
|
source?: string
|
|
}
|
|
|
|
function pluginCount(messages: LintMessage[]): {
|
|
nextPluginErrorCount: number
|
|
nextPluginWarningCount: number
|
|
} {
|
|
let nextPluginWarningCount = 0
|
|
let nextPluginErrorCount = 0
|
|
|
|
for (let i = 0; i < messages.length; i++) {
|
|
const { severity, ruleId } = messages[i]
|
|
|
|
if (ruleId?.includes('@next/next')) {
|
|
if (severity === MessageSeverity.Warning) {
|
|
nextPluginWarningCount += 1
|
|
} else {
|
|
nextPluginErrorCount += 1
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
nextPluginErrorCount,
|
|
nextPluginWarningCount,
|
|
}
|
|
}
|
|
|
|
function formatMessage(
|
|
dir: string,
|
|
messages: LintMessage[],
|
|
filePath: string
|
|
): string {
|
|
let fileName = path.posix.normalize(
|
|
path.relative(dir, filePath).replace(/\\/g, '/')
|
|
)
|
|
|
|
if (!fileName.startsWith('.')) {
|
|
fileName = './' + fileName
|
|
}
|
|
|
|
let output = '\n' + chalk.cyan(fileName)
|
|
|
|
for (let i = 0; i < messages.length; i++) {
|
|
const { message, severity, line, column, ruleId } = messages[i]
|
|
|
|
output = output + '\n'
|
|
|
|
if (line && column) {
|
|
output =
|
|
output +
|
|
chalk.yellow(line.toString()) +
|
|
':' +
|
|
chalk.yellow(column.toString()) +
|
|
' '
|
|
}
|
|
|
|
if (severity === MessageSeverity.Warning) {
|
|
output += chalk.yellow.bold('Warning') + ': '
|
|
} else {
|
|
output += chalk.red.bold('Error') + ': '
|
|
}
|
|
|
|
output += message
|
|
|
|
if (ruleId) {
|
|
output += ' ' + chalk.gray.bold(ruleId)
|
|
}
|
|
}
|
|
|
|
return output
|
|
}
|
|
|
|
export function formatResults(
|
|
baseDir: string,
|
|
results: LintResult[],
|
|
format: (r: LintResult[]) => string
|
|
): {
|
|
output: string
|
|
totalNextPluginErrorCount: number
|
|
totalNextPluginWarningCount: number
|
|
} {
|
|
let totalNextPluginErrorCount = 0
|
|
let totalNextPluginWarningCount = 0
|
|
let resultsWithMessages = results.filter(({ messages }) => messages?.length)
|
|
|
|
// Track number of Next.js plugin errors and warnings
|
|
resultsWithMessages.forEach(({ messages }) => {
|
|
const res = pluginCount(messages)
|
|
totalNextPluginErrorCount += res.nextPluginErrorCount
|
|
totalNextPluginWarningCount += res.nextPluginWarningCount
|
|
})
|
|
|
|
// Use user defined formatter or Next.js's built-in custom formatter
|
|
const output = format
|
|
? format(resultsWithMessages)
|
|
: resultsWithMessages
|
|
.map(({ messages, filePath }) =>
|
|
formatMessage(baseDir, messages, filePath)
|
|
)
|
|
.join('\n')
|
|
|
|
return {
|
|
output:
|
|
resultsWithMessages.length > 0
|
|
? output +
|
|
`\n\n${chalk.cyan(
|
|
'info'
|
|
)} - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules`
|
|
: '',
|
|
totalNextPluginErrorCount,
|
|
totalNextPluginWarningCount,
|
|
}
|
|
}
|