html-validate 10.1.1 → 10.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli.js +200 -202
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +350 -314
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/html-validate.js +1 -2
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest.js +1 -1
- package/dist/cjs/jest.js.map +1 -1
- package/dist/cjs/matchers-jestonly.js +1 -1
- package/dist/cjs/matchers-jestonly.js.map +1 -1
- package/dist/cjs/matchers.js.map +1 -1
- package/dist/cjs/test-utils.js +2 -2
- package/dist/cjs/test-utils.js.map +2 -2
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/cjs/vitest.js.map +1 -1
- package/dist/esm/browser.js +1 -1
- package/dist/esm/cli.js +200 -201
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/core-browser.js.map +1 -1
- package/dist/esm/core-nodejs.js.map +1 -1
- package/dist/esm/core.js +351 -315
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/html-validate.js +1 -2
- package/dist/esm/html-validate.js.map +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/jest.js +1 -1
- package/dist/esm/jest.js.map +1 -1
- package/dist/esm/matchers-jestonly.js +1 -1
- package/dist/esm/matchers-jestonly.js.map +1 -1
- package/dist/esm/matchers.js.map +1 -1
- package/dist/esm/test-utils.js +1 -1
- package/dist/esm/test-utils.js.map +1 -1
- package/dist/esm/vitest.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +1 -1
package/dist/esm/cli.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { l as legacyRequire, F as FileSystemConfigLoader, e as esmResolver, H as HtmlValidate } from './core-nodejs.js';
|
|
2
|
-
import { g as getFormatter$1, U as UserError, e as ensureError,
|
|
2
|
+
import { g as getFormatter$1, U as UserError, e as ensureError, d as deepmerge, i as ignore, B as Reporter, J as engines } from './core.js';
|
|
3
3
|
import path$1 from 'node:path/posix';
|
|
4
|
-
import fs from 'fs';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { globSync } from 'glob';
|
|
7
7
|
import prompts from 'prompts';
|
|
8
8
|
import './meta-helper.js';
|
|
9
|
-
import fs$1 from 'node:fs';
|
|
10
|
-
import betterAjvErrors from '@sidvind/better-ajv-errors';
|
|
11
9
|
import kleur from 'kleur';
|
|
10
|
+
import betterAjvErrors from '@sidvind/better-ajv-errors';
|
|
12
11
|
|
|
13
12
|
const DEFAULT_EXTENSIONS = ["html"];
|
|
14
13
|
function isDirectory(filename) {
|
|
@@ -99,55 +98,34 @@ function getFormatter(formatters) {
|
|
|
99
98
|
};
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Clear cache
|
|
117
|
-
*/
|
|
118
|
-
clearCache() {
|
|
119
|
-
this.cacheIgnore.clear();
|
|
120
|
-
}
|
|
121
|
-
match(target) {
|
|
122
|
-
let current = path.dirname(target);
|
|
123
|
-
while (true) {
|
|
124
|
-
const relative = path.relative(current, target);
|
|
125
|
-
const filename = path.join(current, ".htmlvalidateignore");
|
|
126
|
-
const ig = this.parseFile(filename);
|
|
127
|
-
if (ig?.ignores(relative)) {
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
const child = current;
|
|
131
|
-
current = path.dirname(current);
|
|
132
|
-
if (current === child) {
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return false;
|
|
101
|
+
function parseSeverity(ruleId, severity) {
|
|
102
|
+
switch (severity) {
|
|
103
|
+
case "off":
|
|
104
|
+
case "0":
|
|
105
|
+
return "off";
|
|
106
|
+
case "warn":
|
|
107
|
+
case "1":
|
|
108
|
+
return "warn";
|
|
109
|
+
case "error":
|
|
110
|
+
case "2":
|
|
111
|
+
return "error";
|
|
112
|
+
default:
|
|
113
|
+
throw new Error(`Invalid severity "${severity}" for rule "${ruleId}"`);
|
|
137
114
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const ig = ignore().add(content);
|
|
148
|
-
this.cacheIgnore.set(filename, ig);
|
|
149
|
-
return ig;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function parseItem(value) {
|
|
118
|
+
const [ruleId, severity = "error"] = value.split(":", 2);
|
|
119
|
+
return { ruleId, severity: parseSeverity(ruleId, severity) };
|
|
120
|
+
}
|
|
121
|
+
function getRuleConfig(values) {
|
|
122
|
+
if (typeof values === "string") {
|
|
123
|
+
return getRuleConfig([values]);
|
|
150
124
|
}
|
|
125
|
+
return values.reduce((parsedRules, value) => {
|
|
126
|
+
const { ruleId, severity } = parseItem(value.trim());
|
|
127
|
+
return { [ruleId]: severity, ...parsedRules };
|
|
128
|
+
}, {});
|
|
151
129
|
}
|
|
152
130
|
|
|
153
131
|
const frameworkConfig = {
|
|
@@ -223,34 +201,55 @@ async function init$1(cwd) {
|
|
|
223
201
|
};
|
|
224
202
|
}
|
|
225
203
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
case "warn":
|
|
232
|
-
case "1":
|
|
233
|
-
return "warn";
|
|
234
|
-
case "error":
|
|
235
|
-
case "2":
|
|
236
|
-
return "error";
|
|
237
|
-
default:
|
|
238
|
-
throw new Error(`Invalid severity "${severity}" for rule "${ruleId}"`);
|
|
204
|
+
class IsIgnored {
|
|
205
|
+
/** Cache for parsed .htmlvalidateignore files */
|
|
206
|
+
cacheIgnore;
|
|
207
|
+
constructor() {
|
|
208
|
+
this.cacheIgnore = /* @__PURE__ */ new Map();
|
|
239
209
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Searches ".htmlvalidateignore" files from filesystem and returns `true` if
|
|
212
|
+
* one of them contains a pattern matching given filename.
|
|
213
|
+
*/
|
|
214
|
+
isIgnored(filename) {
|
|
215
|
+
return this.match(filename);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Clear cache
|
|
219
|
+
*/
|
|
220
|
+
clearCache() {
|
|
221
|
+
this.cacheIgnore.clear();
|
|
222
|
+
}
|
|
223
|
+
match(target) {
|
|
224
|
+
let current = path.dirname(target);
|
|
225
|
+
while (true) {
|
|
226
|
+
const relative = path.relative(current, target);
|
|
227
|
+
const filename = path.join(current, ".htmlvalidateignore");
|
|
228
|
+
const ig = this.parseFile(filename);
|
|
229
|
+
if (ig?.ignores(relative)) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
const child = current;
|
|
233
|
+
current = path.dirname(current);
|
|
234
|
+
if (current === child) {
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
parseFile(filename) {
|
|
241
|
+
if (this.cacheIgnore.has(filename)) {
|
|
242
|
+
return this.cacheIgnore.get(filename);
|
|
243
|
+
}
|
|
244
|
+
if (!fs.existsSync(filename)) {
|
|
245
|
+
this.cacheIgnore.set(filename, void 0);
|
|
246
|
+
return void 0;
|
|
247
|
+
}
|
|
248
|
+
const content = fs.readFileSync(filename, "utf-8");
|
|
249
|
+
const ig = ignore().add(content);
|
|
250
|
+
this.cacheIgnore.set(filename, ig);
|
|
251
|
+
return ig;
|
|
249
252
|
}
|
|
250
|
-
return values.reduce((parsedRules, value) => {
|
|
251
|
-
const { ruleId, severity } = parseItem(value.trim());
|
|
252
|
-
return { [ruleId]: severity, ...parsedRules };
|
|
253
|
-
}, {});
|
|
254
253
|
}
|
|
255
254
|
|
|
256
255
|
const resolver = esmResolver();
|
|
@@ -378,51 +377,53 @@ class CLI {
|
|
|
378
377
|
}
|
|
379
378
|
}
|
|
380
379
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
380
|
+
const jsonIgnored = [
|
|
381
|
+
"annotation",
|
|
382
|
+
"blockedRules",
|
|
383
|
+
"cache",
|
|
384
|
+
"closed",
|
|
385
|
+
"depth",
|
|
386
|
+
"disabledRules",
|
|
387
|
+
"nodeType",
|
|
388
|
+
"unique",
|
|
389
|
+
"voidElement"
|
|
390
|
+
];
|
|
391
|
+
const jsonFiltered = [
|
|
392
|
+
"childNodes",
|
|
393
|
+
"children",
|
|
394
|
+
"data",
|
|
395
|
+
"meta",
|
|
396
|
+
"metaElement",
|
|
397
|
+
"originalData",
|
|
398
|
+
"parent"
|
|
399
|
+
];
|
|
400
|
+
function isLocation(key, value) {
|
|
401
|
+
return Boolean(value && (key === "location" || key.endsWith("Location")));
|
|
391
402
|
}
|
|
392
|
-
function
|
|
393
|
-
|
|
394
|
-
const filename = path.relative(process.cwd(), err.filename);
|
|
395
|
-
console.error(kleur.red(`A configuration error was found in "${filename}":`));
|
|
396
|
-
} else {
|
|
397
|
-
console.error(kleur.red(`A configuration error was found:`));
|
|
398
|
-
}
|
|
399
|
-
console.group();
|
|
400
|
-
{
|
|
401
|
-
console.error(prettyError(err));
|
|
402
|
-
}
|
|
403
|
-
console.groupEnd();
|
|
403
|
+
function isIgnored(key) {
|
|
404
|
+
return key.startsWith("_") || jsonIgnored.includes(key);
|
|
404
405
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
406
|
+
function isFiltered(key, value) {
|
|
407
|
+
return Boolean(value && jsonFiltered.includes(key));
|
|
408
|
+
}
|
|
409
|
+
function eventReplacer(key, value) {
|
|
410
|
+
if (isLocation(key, value)) {
|
|
411
|
+
const filename = value.filename;
|
|
412
|
+
const line = String(value.line);
|
|
413
|
+
const column = String(value.column);
|
|
414
|
+
return `${filename}:${line}:${column}`;
|
|
412
415
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
return [
|
|
418
|
-
kleur.red(`Error: ${message}.`),
|
|
419
|
-
"",
|
|
420
|
-
`Either ensure you are running a supported NodeJS version:`,
|
|
421
|
-
` Current: ${currentVersion}`,
|
|
422
|
-
` Required: ${requiredVersion.join(", ")} or later`,
|
|
423
|
-
`Or set NODE_OPTIONS="--experimental-import-meta-resolve"`
|
|
424
|
-
].join("\n");
|
|
416
|
+
if (isIgnored(key)) {
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
419
|
+
if (isFiltered(key, value)) {
|
|
420
|
+
return "[truncated]";
|
|
425
421
|
}
|
|
422
|
+
return value;
|
|
423
|
+
}
|
|
424
|
+
function eventFormatter(entry) {
|
|
425
|
+
const strdata = JSON.stringify(entry.data, eventReplacer, 2);
|
|
426
|
+
return `${entry.event}: ${strdata}`;
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
var Mode = /* @__PURE__ */ ((Mode2) => {
|
|
@@ -454,6 +455,48 @@ function modeToFlag(mode) {
|
|
|
454
455
|
}
|
|
455
456
|
}
|
|
456
457
|
|
|
458
|
+
async function dump(htmlvalidate, output, files, mode) {
|
|
459
|
+
let lines;
|
|
460
|
+
switch (mode) {
|
|
461
|
+
case Mode.DUMP_EVENTS:
|
|
462
|
+
lines = files.map(async (filename) => {
|
|
463
|
+
const lines2 = await htmlvalidate.dumpEvents(filename);
|
|
464
|
+
return lines2.map(eventFormatter);
|
|
465
|
+
});
|
|
466
|
+
break;
|
|
467
|
+
case Mode.DUMP_TOKENS:
|
|
468
|
+
lines = files.map(async (filename) => {
|
|
469
|
+
const lines2 = await htmlvalidate.dumpTokens(filename);
|
|
470
|
+
return lines2.map((entry) => {
|
|
471
|
+
const data = JSON.stringify(entry.data);
|
|
472
|
+
return `TOKEN: ${entry.token}
|
|
473
|
+
Data: ${data}
|
|
474
|
+
Location: ${entry.location}`;
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
break;
|
|
478
|
+
case Mode.DUMP_TREE:
|
|
479
|
+
lines = files.map((filename) => htmlvalidate.dumpTree(filename));
|
|
480
|
+
break;
|
|
481
|
+
case Mode.DUMP_SOURCE:
|
|
482
|
+
lines = files.map((filename) => htmlvalidate.dumpSource(filename));
|
|
483
|
+
break;
|
|
484
|
+
default:
|
|
485
|
+
throw new Error(`Unknown mode "${String(mode)}"`);
|
|
486
|
+
}
|
|
487
|
+
const flat = (await Promise.all(lines)).reduce((s, c) => s.concat(c), []);
|
|
488
|
+
output.write(flat.join("\n"));
|
|
489
|
+
output.write("\n");
|
|
490
|
+
return Promise.resolve(true);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async function init(cli, output, options) {
|
|
494
|
+
const result = await cli.init(options.cwd);
|
|
495
|
+
output.write(`Configuration written to "${result.filename}"
|
|
496
|
+
`);
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
|
|
457
500
|
function renameStdin(report, filename) {
|
|
458
501
|
const stdin = report.results.find((cur) => cur.filePath === "/dev/stdin");
|
|
459
502
|
if (stdin) {
|
|
@@ -488,13 +531,6 @@ html-validate found too many warnings (maximum: ${String(options.maxWarnings)}).
|
|
|
488
531
|
return merged.valid;
|
|
489
532
|
}
|
|
490
533
|
|
|
491
|
-
async function init(cli, output, options) {
|
|
492
|
-
const result = await cli.init(options.cwd);
|
|
493
|
-
output.write(`Configuration written to "${result.filename}"
|
|
494
|
-
`);
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
534
|
async function printConfig(htmlvalidate, output, files) {
|
|
499
535
|
if (files.length > 1) {
|
|
500
536
|
output.write(`\`--print-config\` expected a single filename but got multiple:
|
|
@@ -514,88 +550,51 @@ async function printConfig(htmlvalidate, output, files) {
|
|
|
514
550
|
return true;
|
|
515
551
|
}
|
|
516
552
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
"closed",
|
|
522
|
-
"depth",
|
|
523
|
-
"disabledRules",
|
|
524
|
-
"nodeType",
|
|
525
|
-
"unique",
|
|
526
|
-
"voidElement"
|
|
527
|
-
];
|
|
528
|
-
const jsonFiltered = [
|
|
529
|
-
"childNodes",
|
|
530
|
-
"children",
|
|
531
|
-
"data",
|
|
532
|
-
"meta",
|
|
533
|
-
"metaElement",
|
|
534
|
-
"originalData",
|
|
535
|
-
"parent"
|
|
536
|
-
];
|
|
537
|
-
function isLocation(key, value) {
|
|
538
|
-
return Boolean(value && (key === "location" || key.endsWith("Location")));
|
|
539
|
-
}
|
|
540
|
-
function isIgnored(key) {
|
|
541
|
-
return key.startsWith("_") || jsonIgnored.includes(key);
|
|
542
|
-
}
|
|
543
|
-
function isFiltered(key, value) {
|
|
544
|
-
return Boolean(value && jsonFiltered.includes(key));
|
|
545
|
-
}
|
|
546
|
-
function eventReplacer(key, value) {
|
|
547
|
-
if (isLocation(key, value)) {
|
|
548
|
-
const filename = value.filename;
|
|
549
|
-
const line = String(value.line);
|
|
550
|
-
const column = String(value.column);
|
|
551
|
-
return `${filename}:${line}:${column}`;
|
|
553
|
+
function prettyError(err) {
|
|
554
|
+
let json;
|
|
555
|
+
if (err.filename && fs.existsSync(err.filename)) {
|
|
556
|
+
json = fs.readFileSync(err.filename, "utf-8");
|
|
552
557
|
}
|
|
553
|
-
|
|
554
|
-
|
|
558
|
+
return betterAjvErrors(err.schema, err.obj, err.errors, {
|
|
559
|
+
format: "cli",
|
|
560
|
+
indent: 2,
|
|
561
|
+
json
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
function handleSchemaValidationError(console, err) {
|
|
565
|
+
if (err.filename) {
|
|
566
|
+
const filename = path.relative(process.cwd(), err.filename);
|
|
567
|
+
console.error(kleur.red(`A configuration error was found in "${filename}":`));
|
|
568
|
+
} else {
|
|
569
|
+
console.error(kleur.red(`A configuration error was found:`));
|
|
555
570
|
}
|
|
556
|
-
|
|
557
|
-
|
|
571
|
+
console.group();
|
|
572
|
+
{
|
|
573
|
+
console.error(prettyError(err));
|
|
558
574
|
}
|
|
559
|
-
|
|
560
|
-
}
|
|
561
|
-
function eventFormatter(entry) {
|
|
562
|
-
const strdata = JSON.stringify(entry.data, eventReplacer, 2);
|
|
563
|
-
return `${entry.event}: ${strdata}`;
|
|
575
|
+
console.groupEnd();
|
|
564
576
|
}
|
|
565
577
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
break;
|
|
586
|
-
case Mode.DUMP_TREE:
|
|
587
|
-
lines = files.map((filename) => htmlvalidate.dumpTree(filename));
|
|
588
|
-
break;
|
|
589
|
-
case Mode.DUMP_SOURCE:
|
|
590
|
-
lines = files.map((filename) => htmlvalidate.dumpSource(filename));
|
|
591
|
-
break;
|
|
592
|
-
default:
|
|
593
|
-
throw new Error(`Unknown mode "${String(mode)}"`);
|
|
578
|
+
class ImportResolveMissingError extends UserError {
|
|
579
|
+
constructor() {
|
|
580
|
+
const message = `import.meta.resolve(..) is not available on this system`;
|
|
581
|
+
super(message);
|
|
582
|
+
Error.captureStackTrace(this, ImportResolveMissingError);
|
|
583
|
+
this.name = ImportResolveMissingError.name;
|
|
584
|
+
}
|
|
585
|
+
prettyFormat() {
|
|
586
|
+
const { message } = this;
|
|
587
|
+
const currentVersion = process.version;
|
|
588
|
+
const requiredVersion = engines.node.split("||").map((it) => `v${it.replace(/^[^\d]+/, "").trim()}`);
|
|
589
|
+
return [
|
|
590
|
+
kleur.red(`Error: ${message}.`),
|
|
591
|
+
"",
|
|
592
|
+
`Either ensure you are running a supported NodeJS version:`,
|
|
593
|
+
` Current: ${currentVersion}`,
|
|
594
|
+
` Required: ${requiredVersion.join(", ")} or later`,
|
|
595
|
+
`Or set NODE_OPTIONS="--experimental-import-meta-resolve"`
|
|
596
|
+
].join("\n");
|
|
594
597
|
}
|
|
595
|
-
const flat = (await Promise.all(lines)).reduce((s, c) => s.concat(c), []);
|
|
596
|
-
output.write(flat.join("\n"));
|
|
597
|
-
output.write("\n");
|
|
598
|
-
return Promise.resolve(true);
|
|
599
598
|
}
|
|
600
599
|
|
|
601
600
|
function haveImportMetaResolve() {
|