html-validate
Version:
Offline HTML5 validator and linter
263 lines (255 loc) • 7.24 kB
JavaScript
import fs from 'node:fs';
import path from 'node:path';
import kleur from 'kleur';
import minimist from 'minimist';
import { a2 as name, v as version, n as SchemaValidationError, o as isUserError, a3 as bugs } from './core.js';
import { M as Mode, m as modeToFlag, C as CLI, h as haveImportMetaResolve, I as ImportResolveMissingError, l as lint, i as init, p as printConfig, d as dump, a as handleSchemaValidationError } from './cli.js';
import 'ajv';
import './elements.js';
import './meta-helper.js';
import './utils/natural-join.js';
import '@sidvind/better-ajv-errors';
import '@html-validate/stylish';
import 'semver';
import './core-nodejs.js';
import 'node:fs/promises';
import 'node:url';
import 'node:module';
import 'node:path/posix';
import 'glob';
import 'prompts';
function getMode(argv2) {
if (argv2["init"]) {
return Mode.INIT;
}
if (argv2["dump-events"]) {
return Mode.DUMP_EVENTS;
}
if (argv2["dump-source"]) {
return Mode.DUMP_SOURCE;
}
if (argv2["dump-tokens"]) {
return Mode.DUMP_TOKENS;
}
if (argv2["dump-tree"]) {
return Mode.DUMP_TREE;
}
if (argv2["print-config"]) {
return Mode.PRINT_CONFIG;
}
return Mode.LINT;
}
function requiresFilename(mode) {
switch (mode) {
case Mode.LINT:
return true;
case Mode.INIT:
return false;
case Mode.DUMP_EVENTS:
case Mode.DUMP_TOKENS:
case Mode.DUMP_TREE:
case Mode.DUMP_SOURCE:
case Mode.PRINT_CONFIG:
return true;
}
}
function handleUserError(err) {
const formatted = err.prettyFormat();
if (formatted) {
console.error();
console.error(formatted);
return;
}
console.error(kleur.red("Caught exception:"));
console.group();
{
console.error(err.prettyFormat() ?? err);
}
console.groupEnd();
}
function handleUnknownError(err) {
console.error(kleur.red("Caught exception:"));
console.group();
{
console.error(err);
}
console.groupEnd();
const bugUrl = `${bugs}?issuable_template=Bug`;
console.error(kleur.red(`This is a bug in ${name}-${version}.`));
console.error(
kleur.red(
[
`Please file a bug at ${bugUrl}`,
`and include this message in full and if possible the content of the`,
`file being parsed (or a reduced testcase).`
].join("\n")
)
);
}
const argv = minimist(process.argv.slice(2), {
string: [
"c",
"config",
"ext",
"f",
"formatter",
"max-warnings",
"p",
"preset",
"rule",
"stdin-filename"
],
boolean: [
"init",
"dump-events",
"dump-source",
"dump-tokens",
"dump-tree",
"h",
"help",
"print-config",
"stdin",
"version"
],
alias: {
c: "config",
f: "formatter",
p: "preset",
h: "help"
},
default: {
ext: "html",
formatter: "stylish"
},
unknown: (opt) => {
if (opt.startsWith("-")) {
process.stderr.write(`unknown option ${opt}
`);
process.exit(1);
}
return true;
}
});
function showUsage() {
process.stdout.write(`${name}-${version}
Usage: html-validate [OPTIONS] [FILENAME..] [DIR..]
Common options:
--ext=STRING specify file extensions (commaseparated).
-f, --formatter=FORMATTER specify the formatter to use.
--max-warnings=INT number of warnings to trigger nonzero exit code
-p, --preset=STRING configuration preset to use, use
comma-separator for multiple presets. (default:
"recommended")
--rule=RULE:SEVERITY set additional rule, use comma separator for
multiple.
--stdin process markup from stdin.
--stdin-filename=STRING specify filename to report when using stdin
Miscellaneous:
-c, --config=STRING use custom configuration file.
--init initialize project with a new configuration
--print-config output configuration for given file.
-h, --help show help.
--version show version.
Debugging options:
--dump-events output events during parsing.
--dump-source output post-transformed source data.
--dump-tokens output tokens from lexing stage.
--dump-tree output nodes from the dom tree.
Formatters:
Multiple formatters can be specified with a comma-separated list,
e.g. "json,checkstyle" to enable both.
To capture output to a file use "formatter=/path/to/file",
e.g. "checkstyle=dist/html-validate.xml"
`);
}
function showVersion() {
process.stdout.write(`${name}-${version}
`);
}
if (argv.stdin) {
argv._.push("-");
}
if (argv.version) {
showVersion();
process.exit();
}
if (argv.help) {
showUsage();
process.exit();
}
if (argv._.length === 0) {
const mode = getMode(argv);
if (mode === Mode.LINT) {
showUsage();
process.exit(0);
} else if (requiresFilename(mode)) {
const flag = modeToFlag(mode);
console.error(`\`${flag}\` requires a filename.`);
process.exit(1);
}
}
if (typeof argv.config !== "undefined") {
const checkPath = path.resolve(argv.config);
if (!fs.existsSync(checkPath)) {
console.error(`The file "${argv.config}" was not found.`);
console.error(`The location this file was checked for at was: "${checkPath}"`);
process.exit(1);
}
}
async function run() {
const cli = new CLI({
configFile: argv.config,
preset: argv.preset,
rules: argv.rule
});
const mode = getMode(argv);
const formatter = await cli.getFormatter(argv.formatter);
const maxWarnings = parseInt(argv["max-warnings"] ?? "-1", 10);
const htmlvalidate = await cli.getValidator();
if (isNaN(maxWarnings)) {
console.error(`Invalid value "${String(argv["max-warnings"])}" given to --max-warnings`);
process.exit(1);
}
const extensions = argv.ext.split(",").map((cur) => {
return cur.startsWith(".") ? cur.slice(1) : cur;
});
const files = await cli.expandFiles(argv._, { extensions });
if (files.length === 0 && mode !== Mode.INIT) {
console.error("No files matching patterns", argv._);
process.exit(1);
}
try {
if (!haveImportMetaResolve()) {
throw new ImportResolveMissingError();
}
let success;
if (mode === Mode.LINT) {
success = await lint(htmlvalidate, process.stdout, files, {
formatter,
maxWarnings,
stdinFilename: argv["stdin-filename"] ?? false
});
} else if (mode === Mode.INIT) {
success = await init(cli, process.stdout, { cwd: process.cwd() });
} else if (mode === Mode.PRINT_CONFIG) {
success = await printConfig(htmlvalidate, process.stdout, files);
} else {
success = await dump(htmlvalidate, process.stdout, files, mode);
}
process.exit(success ? 0 : 1);
} catch (err) {
if (err instanceof SchemaValidationError) {
handleSchemaValidationError(console, err);
} else if (isUserError(err)) {
handleUserError(err);
} else {
handleUnknownError(err);
}
process.exit(1);
}
}
run().catch((err) => {
console.error(err);
process.exit(1);
});
//# sourceMappingURL=html-validate.js.map