1
1
mirror of https://github.com/theoludwig/html-w3c-validator.git synced 2024-07-20 07:30:11 +02:00

feat: ability to specify the severity of the validator

fixes #4
This commit is contained in:
Théo LUDWIG 2023-07-02 13:05:33 +02:00
parent a8841b24fd
commit 29203985e4
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
2 changed files with 64 additions and 18 deletions

View File

@ -71,7 +71,10 @@ npm install --save-dev html-w3c-validator start-server-and-test
"urls": ["http://127.0.0.1:3000/", "http://127.0.0.1:3000/about"], "urls": ["http://127.0.0.1:3000/", "http://127.0.0.1:3000/about"],
// You can also specify HTML files instead of URLs // You can also specify HTML files instead of URLs
"files": ["./index.html", "./about.html"] "files": ["./index.html", "./about.html"],
// Specify the severities of the validator (default: ["error"])
"severities": ["info", "warning", "error"]
} }
``` ```

View File

@ -17,9 +17,14 @@ import { isExistingPath } from './utils/isExistingPath.js'
const CURRENT_DIRECTORY = process.cwd() const CURRENT_DIRECTORY = process.cwd()
const CONFIG_FILE_NAME = '.html-w3c-validatorrc.json' const CONFIG_FILE_NAME = '.html-w3c-validatorrc.json'
const severities = ['error', 'warning', 'info'] as const
export type Severity = (typeof severities)[number]
interface Config { interface Config {
urls?: string[] urls?: string[]
files?: string[] files?: string[]
severities?: Severity[]
} }
interface Error { interface Error {
@ -53,7 +58,7 @@ export class HTMLValidatorCommand extends Command {
try { try {
if (!(await isExistingPath(configPath))) { if (!(await isExistingPath(configPath))) {
throw new Error( throw new Error(
`No config file found at ${configPath}. Please create ${CONFIG_FILE_NAME}.` `No config file found at ${configPath}. Please create "${CONFIG_FILE_NAME}".`
) )
} }
const configData = await fs.promises.readFile(configPath, { const configData = await fs.promises.readFile(configPath, {
@ -66,12 +71,19 @@ export class HTMLValidatorCommand extends Command {
} catch { } catch {
isValidConfig = false isValidConfig = false
} }
isValidConfig =
isValidConfig &&
(Array.isArray(config.urls) || Array.isArray(config.urls))
if (!isValidConfig) { if (!isValidConfig) {
throw new Error( throw new Error(
`Invalid config file at ${configPath}. Please check the syntax.` `Invalid config file at "${configPath}". Please check the JSON syntax.`
)
}
if (config.urls != null && !Array.isArray(config.urls)) {
throw new Error(
`Invalid config file at "${configPath}". Please include an array of URLs.`
)
}
if (config.files != null && !Array.isArray(config.files)) {
throw new Error(
`Invalid config file at "${configPath}". Please include an array of files.`
) )
} }
const urls = const urls =
@ -87,6 +99,28 @@ export class HTMLValidatorCommand extends Command {
return { type: 'file', data: file } return { type: 'file', data: file }
}) })
const dataToValidate = [...urls, ...files] const dataToValidate = [...urls, ...files]
if (dataToValidate.length === 0) {
throw new Error(
`Invalid config file at "${configPath}". Please add URLs or files.`
)
}
const configSeverities: Severity[] = config.severities ?? ['error']
for (const severity of configSeverities) {
if (!severities.includes(severity)) {
throw new Error(
`Invalid config file at "${configPath}". Please add valid severities (${severities.join(
', '
)}).`
)
}
}
if (configSeverities.length === 0) {
throw new Error(
`Invalid config file at "${configPath}". Please add valid severities (${severities.join(
', '
)}).`
)
}
const errors: Error[] = [] const errors: Error[] = []
let isValid = true let isValid = true
const loader = ora(`Validating HTML (W3C)...`).start() const loader = ora(`Validating HTML (W3C)...`).start()
@ -108,7 +142,7 @@ export class HTMLValidatorCommand extends Command {
const htmlPath = path.resolve(CURRENT_DIRECTORY, data) const htmlPath = path.resolve(CURRENT_DIRECTORY, data)
if (!(await isExistingPath(htmlPath))) { if (!(await isExistingPath(htmlPath))) {
throw new Error( throw new Error(
`No file found at ${htmlPath}. Please check the path.` `No file found at "${htmlPath}". Please check the path.`
) )
} }
const html = await fs.promises.readFile(htmlPath, { const html = await fs.promises.readFile(htmlPath, {
@ -122,7 +156,10 @@ export class HTMLValidatorCommand extends Command {
throw new Error('Invalid type') throw new Error('Invalid type')
} }
const hasErrors = result.messages.some((message) => { const hasErrors = result.messages.some((message) => {
return message.type === 'error' return (
configSeverities.includes(message.type as Severity) ||
configSeverities.includes(message.subType as Severity)
)
}) })
if (!hasErrors) { if (!hasErrors) {
results.push({ data, isSuccess: true }) results.push({ data, isSuccess: true })
@ -130,18 +167,24 @@ export class HTMLValidatorCommand extends Command {
results.push({ data, isSuccess: false }) results.push({ data, isSuccess: false })
const messagesTable: string[][] = [] const messagesTable: string[][] = []
for (const message of result.messages) { for (const message of result.messages) {
if (message.type === 'error') { const row: string[] = []
const row: string[] = [] if (message.type === 'info') {
row.push(chalk.red(message.type)) if (message.subType === 'warning') {
row.push(message.message) row.push(chalk.yellow(message.subType))
const violation = message as ValidationMessageLocationObject } else {
if (violation.extract != null) { row.push(chalk.blue(message.type))
row.push(
`line: ${violation.lastLine}, column: ${violation.firstColumn}-${violation.lastColumn}`
)
} }
messagesTable.push(row) } else {
row.push(chalk.red(message.type))
} }
row.push(message.message)
const violation = message as ValidationMessageLocationObject
if (violation.extract != null) {
row.push(
`line: ${violation.lastLine}, column: ${violation.firstColumn}-${violation.lastColumn}`
)
}
messagesTable.push(row)
} }
errors.push({ data, messagesTable }) errors.push({ data, messagesTable })
isValid = false isValid = false