mirror of
https://github.com/theoludwig/html-w3c-validator.git
synced 2024-10-29 22:17:28 +01:00
parent
3a44eca5b1
commit
6ca7722fcf
2
example/package-lock.json
generated
2
example/package-lock.json
generated
@ -20,6 +20,7 @@
|
||||
"chalk": "5.1.2",
|
||||
"clipanion": "3.1.0",
|
||||
"html-validator": "6.0.1",
|
||||
"log-symbols": "5.1.0",
|
||||
"ora": "6.1.2",
|
||||
"read-pkg": "7.1.0",
|
||||
"table": "6.8.0"
|
||||
@ -1759,6 +1760,7 @@
|
||||
"html-validator": "6.0.1",
|
||||
"husky": "8.0.1",
|
||||
"lint-staged": "13.0.3",
|
||||
"log-symbols": "5.1.0",
|
||||
"markdownlint-cli": "0.32.2",
|
||||
"mock-fs": "5.1.4",
|
||||
"ora": "6.1.2",
|
||||
|
1
package-lock.json
generated
1
package-lock.json
generated
@ -13,6 +13,7 @@
|
||||
"chalk": "5.1.2",
|
||||
"clipanion": "3.1.0",
|
||||
"html-validator": "6.0.1",
|
||||
"log-symbols": "5.1.0",
|
||||
"ora": "6.1.2",
|
||||
"read-pkg": "7.1.0",
|
||||
"table": "6.8.0"
|
||||
|
@ -47,6 +47,7 @@
|
||||
"chalk": "5.1.2",
|
||||
"clipanion": "3.1.0",
|
||||
"html-validator": "6.0.1",
|
||||
"log-symbols": "5.1.0",
|
||||
"ora": "6.1.2",
|
||||
"read-pkg": "7.1.0",
|
||||
"table": "6.8.0"
|
||||
|
@ -4,6 +4,7 @@ import fs from 'node:fs'
|
||||
import { Command } from 'clipanion'
|
||||
import chalk from 'chalk'
|
||||
import ora from 'ora'
|
||||
import logSymbols from 'log-symbols'
|
||||
import type {
|
||||
ValidationMessageLocationObject,
|
||||
ParsedJsonAsValidationResults
|
||||
@ -26,6 +27,21 @@ interface Error {
|
||||
messagesTable: string[][]
|
||||
}
|
||||
|
||||
interface Result {
|
||||
data: string
|
||||
isSuccess: boolean
|
||||
}
|
||||
|
||||
const printResults = (results: Result[]): void => {
|
||||
for (const result of results) {
|
||||
if (result.isSuccess) {
|
||||
console.log(logSymbols.success, result.data)
|
||||
} else {
|
||||
console.log(logSymbols.error, result.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class HTMLValidatorCommand extends Command {
|
||||
static usage = {
|
||||
description:
|
||||
@ -40,7 +56,6 @@ export class HTMLValidatorCommand extends Command {
|
||||
`No config file found at ${configPath}. Please create ${CONFIG_FILE_NAME}.`
|
||||
)
|
||||
}
|
||||
|
||||
const configData = await fs.promises.readFile(configPath, {
|
||||
encoding: 'utf-8'
|
||||
})
|
||||
@ -74,72 +89,75 @@ export class HTMLValidatorCommand extends Command {
|
||||
const dataToValidate = [...urls, ...files]
|
||||
const errors: Error[] = []
|
||||
let isValid = true
|
||||
for (const { data, type } of dataToValidate) {
|
||||
const loader = ora(`Validating ${data}`).start()
|
||||
try {
|
||||
const options = {
|
||||
format: 'json' as 'json' | undefined
|
||||
}
|
||||
let result: ParsedJsonAsValidationResults | undefined
|
||||
if (type === 'url') {
|
||||
result = await validateHTML({
|
||||
url: data,
|
||||
isLocal: true,
|
||||
...options
|
||||
})
|
||||
} else if (type === 'file') {
|
||||
const htmlPath = path.resolve(CURRENT_DIRECTORY, data)
|
||||
if (!(await isExistingPath(htmlPath))) {
|
||||
throw new Error(
|
||||
`No file found at ${htmlPath}. Please check the path.`
|
||||
)
|
||||
const loader = ora(`Validating HTML (W3C)...`).start()
|
||||
const results: Result[] = []
|
||||
await Promise.all(
|
||||
dataToValidate.map(async ({ data, type }) => {
|
||||
try {
|
||||
const options = {
|
||||
format: 'json' as 'json' | undefined
|
||||
}
|
||||
const html = await fs.promises.readFile(htmlPath, {
|
||||
encoding: 'utf-8'
|
||||
})
|
||||
result = await validateHTML({
|
||||
data: html,
|
||||
...options
|
||||
})
|
||||
} else {
|
||||
throw new Error('Invalid type')
|
||||
}
|
||||
const hasErrors = result.messages.some((message) => {
|
||||
return message.type === 'error'
|
||||
})
|
||||
if (!hasErrors) {
|
||||
loader.succeed()
|
||||
} else {
|
||||
loader.fail()
|
||||
const messagesTable: string[][] = []
|
||||
for (const message of result.messages) {
|
||||
if (message.type === 'error') {
|
||||
const row: string[] = []
|
||||
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)
|
||||
let result: ParsedJsonAsValidationResults | undefined
|
||||
if (type === 'url') {
|
||||
result = await validateHTML({
|
||||
url: data,
|
||||
isLocal: true,
|
||||
...options
|
||||
})
|
||||
} else if (type === 'file') {
|
||||
const htmlPath = path.resolve(CURRENT_DIRECTORY, data)
|
||||
if (!(await isExistingPath(htmlPath))) {
|
||||
throw new Error(
|
||||
`No file found at ${htmlPath}. Please check the path.`
|
||||
)
|
||||
}
|
||||
const html = await fs.promises.readFile(htmlPath, {
|
||||
encoding: 'utf-8'
|
||||
})
|
||||
result = await validateHTML({
|
||||
data: html,
|
||||
...options
|
||||
})
|
||||
} else {
|
||||
throw new Error('Invalid type')
|
||||
}
|
||||
errors.push({ data, messagesTable })
|
||||
const hasErrors = result.messages.some((message) => {
|
||||
return message.type === 'error'
|
||||
})
|
||||
if (!hasErrors) {
|
||||
results.push({ data, isSuccess: true })
|
||||
} else {
|
||||
results.push({ data, isSuccess: false })
|
||||
const messagesTable: string[][] = []
|
||||
for (const message of result.messages) {
|
||||
if (message.type === 'error') {
|
||||
const row: string[] = []
|
||||
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 })
|
||||
isValid = false
|
||||
}
|
||||
} catch (error) {
|
||||
isValid = false
|
||||
if (error instanceof Error) {
|
||||
const messagesTable: string[][] = [[error.message]]
|
||||
errors.push({ data, messagesTable })
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
loader.fail()
|
||||
isValid = false
|
||||
if (error instanceof Error) {
|
||||
const messagesTable: string[][] = [[error.message]]
|
||||
errors.push({ data, messagesTable })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
)
|
||||
if (!isValid) {
|
||||
loader.fail()
|
||||
printResults(results)
|
||||
for (const error of errors) {
|
||||
console.error(`\n${error.data}`)
|
||||
console.error(table(error.messagesTable))
|
||||
@ -148,10 +166,10 @@ export class HTMLValidatorCommand extends Command {
|
||||
console.error()
|
||||
throw new Error('HTML validation (W3C) failed!')
|
||||
}
|
||||
console.log()
|
||||
console.log(
|
||||
loader.succeed(
|
||||
`${chalk.bold.green('Success:')} HTML validation (W3C) passed! 🎉`
|
||||
)
|
||||
printResults(results)
|
||||
return 0
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
|
Loading…
Reference in New Issue
Block a user