html-validate 7.18.1 → 8.0.1

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/core.js CHANGED
@@ -1,14 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var fs = require('fs');
4
- var espree = require('espree');
5
- var walk = require('acorn-walk');
6
3
  var path = require('path');
7
- var semver = require('semver');
8
- var kleur = require('kleur');
9
4
  var Ajv = require('ajv');
10
5
  var deepmerge = require('deepmerge');
11
6
  var elements = require('./elements.js');
7
+ var fs = require('fs');
8
+ var semver = require('semver');
9
+ var kleur = require('kleur');
12
10
  var rulesHelper = require('./rules-helper.js');
13
11
  var betterAjvErrors = require('@sidvind/better-ajv-errors');
14
12
  var codeFrame = require('@babel/code-frame');
@@ -16,32 +14,12 @@ var stylish$2 = require('@html-validate/stylish');
16
14
 
17
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
16
 
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
21
- var n = Object.create(null);
22
- if (e) {
23
- Object.keys(e).forEach(function (k) {
24
- if (k !== 'default') {
25
- var d = Object.getOwnPropertyDescriptor(e, k);
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- });
32
- }
33
- n.default = e;
34
- return Object.freeze(n);
35
- }
36
-
37
- var fs__default = /*#__PURE__*/_interopDefault(fs);
38
- var espree__namespace = /*#__PURE__*/_interopNamespace(espree);
39
- var walk__namespace = /*#__PURE__*/_interopNamespace(walk);
40
17
  var path__default = /*#__PURE__*/_interopDefault(path);
41
- var semver__default = /*#__PURE__*/_interopDefault(semver);
42
- var kleur__default = /*#__PURE__*/_interopDefault(kleur);
43
18
  var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
44
19
  var deepmerge__default = /*#__PURE__*/_interopDefault(deepmerge);
20
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
21
+ var semver__default = /*#__PURE__*/_interopDefault(semver);
22
+ var kleur__default = /*#__PURE__*/_interopDefault(kleur);
45
23
  var betterAjvErrors__default = /*#__PURE__*/_interopDefault(betterAjvErrors);
46
24
 
47
25
  const $schema$2 = "http://json-schema.org/draft-06/schema#";
@@ -3188,232 +3166,11 @@ var configurationSchema = {
3188
3166
  properties: properties
3189
3167
  };
3190
3168
 
3191
- /* eslint-disable @typescript-eslint/no-non-null-assertion -- declarations say
3192
- * location fields are optional but they are always present when `{loc: true}` */
3193
- function joinTemplateLiteral(nodes) {
3194
- let offset = nodes[0].start + 1;
3195
- let output = "";
3196
- for (const node of nodes) {
3197
- output += " ".repeat(node.start + 1 - offset);
3198
- output += node.value.raw;
3199
- offset = node.end - 2;
3200
- }
3201
- return output;
3202
- }
3203
- /**
3204
- * Compute source offset from line and column and the given markup.
3205
- *
3206
- * @param position - Line and column.
3207
- * @param data - Source markup.
3208
- * @returns The byte offset into the markup which line and column corresponds to.
3209
- */
3210
- function computeOffset(position, data) {
3211
- let line = position.line;
3212
- let column = position.column + 1;
3213
- for (let i = 0; i < data.length; i++) {
3214
- if (line > 1) {
3215
- /* not yet on the correct line */
3216
- if (data[i] === "\n") {
3217
- line--;
3218
- }
3219
- }
3220
- else if (column > 1) {
3221
- /* not yet on the correct column */
3222
- column--;
3223
- }
3224
- else {
3225
- /* line/column found, return current position */
3226
- return i;
3227
- }
3228
- }
3229
- /* istanbul ignore next: should never reach this line unless espree passes bad
3230
- * positions, no sane way to test */
3231
- throw new Error("Failed to compute location offset from position");
3232
- }
3233
- function extractLiteral(node, filename, data) {
3234
- switch (node.type) {
3235
- /* ignored nodes */
3236
- case "FunctionExpression":
3237
- case "Identifier":
3238
- return null;
3239
- case "Literal":
3240
- if (typeof node.value !== "string") {
3241
- return null;
3242
- }
3243
- return {
3244
- data: node.value.toString(),
3245
- filename,
3246
- line: node.loc.start.line,
3247
- column: node.loc.start.column + 1,
3248
- offset: computeOffset(node.loc.start, data) + 1,
3249
- };
3250
- case "TemplateLiteral":
3251
- return {
3252
- data: joinTemplateLiteral(node.quasis),
3253
- filename,
3254
- line: node.loc.start.line,
3255
- column: node.loc.start.column + 1,
3256
- offset: computeOffset(node.loc.start, data) + 1,
3257
- };
3258
- case "TaggedTemplateExpression":
3259
- return {
3260
- data: joinTemplateLiteral(node.quasi.quasis),
3261
- filename,
3262
- line: node.quasi.loc.start.line,
3263
- column: node.quasi.loc.start.column + 1,
3264
- offset: computeOffset(node.quasi.loc.start, data) + 1,
3265
- };
3266
- case "ArrowFunctionExpression": {
3267
- const whitelist = ["Literal", "TemplateLiteral"];
3268
- if (whitelist.includes(node.body.type)) {
3269
- return extractLiteral(node.body, filename, data);
3270
- }
3271
- else {
3272
- return null;
3273
- }
3274
- }
3275
- /* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
3276
- default: {
3277
- const loc = node.loc.start;
3278
- const context = `${filename}:${loc.line}:${loc.column}`;
3279
- throw new Error(`Unhandled node type "${node.type}" at "${context}" in extractLiteral`);
3280
- }
3281
- }
3282
- }
3283
- function compareKey(node, key, filename) {
3284
- switch (node.type) {
3285
- case "Identifier":
3286
- return node.name === key;
3287
- case "Literal":
3288
- return node.value === key;
3289
- /* istanbul ignore next: this only provides a better error, all currently known nodes are tested */
3290
- default: {
3291
- const loc = node.loc.start;
3292
- const context = `${filename}:${loc.line}:${loc.column}`;
3293
- throw new Error(`Unhandled node type "${node.type}" at "${context}" in compareKey`);
3294
- }
3295
- }
3296
- }
3297
- /**
3298
- * @public
3299
- */
3300
- class TemplateExtractor {
3301
- constructor(ast, filename, data) {
3302
- this.ast = ast;
3303
- this.filename = filename;
3304
- this.data = data;
3305
- }
3306
- static fromFilename(filename) {
3307
- const source = fs__default.default.readFileSync(filename, "utf-8");
3308
- const ast = espree__namespace.parse(source, {
3309
- ecmaVersion: 2017,
3310
- sourceType: "module",
3311
- loc: true,
3312
- });
3313
- return new TemplateExtractor(ast, filename, source);
3314
- }
3315
- /**
3316
- * Create a new [[TemplateExtractor]] from javascript source code.
3317
- *
3318
- * `Source` offsets will be relative to the string, i.e. offset 0 is the first
3319
- * character of the string. If the string is only a subset of a larger string
3320
- * the offsets must be adjusted manually.
3321
- *
3322
- * @param source - Source code.
3323
- * @param filename - Optional filename to set in the resulting
3324
- * `Source`. Defauls to `"inline"`.
3325
- */
3326
- static fromString(source, filename) {
3327
- const ast = espree__namespace.parse(source, {
3328
- ecmaVersion: 2017,
3329
- sourceType: "module",
3330
- loc: true,
3331
- });
3332
- return new TemplateExtractor(ast, filename || "inline", source);
3333
- }
3334
- /**
3335
- * Convenience function to create a [[Source]] instance from an existing file.
3336
- *
3337
- * @param filename - Filename with javascript source code. The file must exist
3338
- * and be readable by the user.
3339
- * @returns An array of Source's suitable for passing to [[Engine]] linting
3340
- * functions.
3341
- */
3342
- static createSource(filename) {
3343
- const data = fs__default.default.readFileSync(filename, "utf-8");
3344
- return [
3345
- {
3346
- column: 1,
3347
- data,
3348
- filename,
3349
- line: 1,
3350
- offset: 0,
3351
- },
3352
- ];
3353
- }
3354
- /**
3355
- * Extract object properties.
3356
- *
3357
- * Given a key `"template"` this method finds all objects literals with a
3358
- * `"template"` property and creates a [[Source]] instance with proper offsets
3359
- * with the value of the property. For instance:
3360
- *
3361
- * ```
3362
- * const myObj = {
3363
- * foo: 'bar',
3364
- * };
3365
- * ```
3366
- *
3367
- * The above snippet would yield a `Source` with the content `bar`.
3368
- *
3369
- */
3370
- extractObjectProperty(key) {
3371
- const result = [];
3372
- const { filename, data } = this;
3373
- const node = this.ast;
3374
- walk__namespace.simple(node, {
3375
- Property(node) {
3376
- if (compareKey(node.key, key, filename)) {
3377
- const source = extractLiteral(node.value, filename, data);
3378
- if (source) {
3379
- source.filename = filename;
3380
- result.push(source);
3381
- }
3382
- }
3383
- },
3384
- });
3385
- return result;
3386
- }
3387
- }
3388
-
3389
3169
  var TRANSFORMER_API;
3390
3170
  (function (TRANSFORMER_API) {
3391
3171
  TRANSFORMER_API[TRANSFORMER_API["VERSION"] = 1] = "VERSION";
3392
3172
  })(TRANSFORMER_API || (TRANSFORMER_API = {}));
3393
3173
 
3394
- /**
3395
- * Similar to `require(..)` but removes the cached copy first.
3396
- */
3397
- function requireUncached(require, moduleId) {
3398
- const filename = require.resolve(moduleId);
3399
- /* remove references from the parent module to prevent memory leak */
3400
- const m = require.cache[filename];
3401
- if (m && m.parent) {
3402
- const { parent } = m;
3403
- for (let i = parent.children.length - 1; i >= 0; i--) {
3404
- if (parent.children[i].id === filename) {
3405
- parent.children.splice(i, 1);
3406
- }
3407
- }
3408
- }
3409
- /* remove old module from cache */
3410
- delete require.cache[filename];
3411
- /* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
3412
- return require(filename);
3413
- }
3414
-
3415
- const legacyRequire = require;
3416
-
3417
3174
  /**
3418
3175
  * @public
3419
3176
  */
@@ -3431,11 +3188,6 @@ function parseSeverity(value) {
3431
3188
  case 0:
3432
3189
  case "off":
3433
3190
  return exports.Severity.DISABLED;
3434
- /* istanbul ignore next: deprecated code which will be removed later */
3435
- case "disable":
3436
- // eslint-disable-next-line no-console -- expected to log
3437
- console.warn(`Deprecated alias "disabled" will be removed, replace with severity "off"`);
3438
- return exports.Severity.DISABLED;
3439
3191
  case 1:
3440
3192
  case "warn":
3441
3193
  return exports.Severity.WARN;
@@ -3770,6 +3522,8 @@ class Rule {
3770
3522
  * Called when requesting additional documentation for a rule. Some rules
3771
3523
  * provide additional context to provide context-aware suggestions.
3772
3524
  *
3525
+ * @public
3526
+ * @virtual
3773
3527
  * @param context - Error context given by a reported error.
3774
3528
  * @returns Rule documentation and url with additional details or `null` if no
3775
3529
  * additional documentation is available.
@@ -3780,15 +3534,15 @@ class Rule {
3780
3534
  }
3781
3535
  }
3782
3536
 
3783
- var Style$2;
3537
+ var Style$1;
3784
3538
  (function (Style) {
3785
3539
  Style["EXTERNAL"] = "external";
3786
3540
  Style["RELATIVE_BASE"] = "relative-base";
3787
3541
  Style["RELATIVE_PATH"] = "relative-path";
3788
3542
  Style["ABSOLUTE"] = "absolute";
3789
3543
  Style["ANCHOR"] = "anchor";
3790
- })(Style$2 || (Style$2 = {}));
3791
- const defaults$w = {
3544
+ })(Style$1 || (Style$1 = {}));
3545
+ const defaults$v = {
3792
3546
  allowExternal: true,
3793
3547
  allowRelative: true,
3794
3548
  allowAbsolute: true,
@@ -3801,11 +3555,11 @@ const mapping$1 = {
3801
3555
  script: "src",
3802
3556
  };
3803
3557
  const description = {
3804
- [Style$2.EXTERNAL]: "External links are not allowed by current configuration.",
3805
- [Style$2.RELATIVE_BASE]: "Links relative to <base> are not allowed by current configuration.",
3806
- [Style$2.RELATIVE_PATH]: "Relative links are not allowed by current configuration.",
3807
- [Style$2.ABSOLUTE]: "Absolute links are not allowed by current configuration.",
3808
- [Style$2.ANCHOR]: null,
3558
+ [Style$1.EXTERNAL]: "External links are not allowed by current configuration.",
3559
+ [Style$1.RELATIVE_BASE]: "Links relative to <base> are not allowed by current configuration.",
3560
+ [Style$1.RELATIVE_PATH]: "Relative links are not allowed by current configuration.",
3561
+ [Style$1.ABSOLUTE]: "Absolute links are not allowed by current configuration.",
3562
+ [Style$1.ANCHOR]: null,
3809
3563
  };
3810
3564
  function parseAllow(value) {
3811
3565
  if (typeof value === "boolean") {
@@ -3832,7 +3586,7 @@ function matchList(value, list) {
3832
3586
  }
3833
3587
  class AllowedLinks extends Rule {
3834
3588
  constructor(options) {
3835
- super({ ...defaults$w, ...options });
3589
+ super({ ...defaults$v, ...options });
3836
3590
  this.allowExternal = parseAllow(this.options.allowExternal);
3837
3591
  this.allowRelative = parseAllow(this.options.allowRelative);
3838
3592
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -3878,19 +3632,19 @@ class AllowedLinks extends Rule {
3878
3632
  const link = event.value.toString();
3879
3633
  const style = this.getStyle(link);
3880
3634
  switch (style) {
3881
- case Style$2.ANCHOR:
3635
+ case Style$1.ANCHOR:
3882
3636
  /* anchor links are always allowed by this rule */
3883
3637
  break;
3884
- case Style$2.ABSOLUTE:
3638
+ case Style$1.ABSOLUTE:
3885
3639
  this.handleAbsolute(link, event, style);
3886
3640
  break;
3887
- case Style$2.EXTERNAL:
3641
+ case Style$1.EXTERNAL:
3888
3642
  this.handleExternal(link, event, style);
3889
3643
  break;
3890
- case Style$2.RELATIVE_BASE:
3644
+ case Style$1.RELATIVE_BASE:
3891
3645
  this.handleRelativeBase(link, event, style);
3892
3646
  break;
3893
- case Style$2.RELATIVE_PATH:
3647
+ case Style$1.RELATIVE_PATH:
3894
3648
  this.handleRelativePath(link, event, style);
3895
3649
  break;
3896
3650
  }
@@ -3908,21 +3662,21 @@ class AllowedLinks extends Rule {
3908
3662
  getStyle(value) {
3909
3663
  /* http://example.net or //example.net */
3910
3664
  if (value.match(/^([a-z]+:)?\/\//g)) {
3911
- return Style$2.EXTERNAL;
3665
+ return Style$1.EXTERNAL;
3912
3666
  }
3913
3667
  switch (value[0]) {
3914
3668
  /* /foo/bar */
3915
3669
  case "/":
3916
- return Style$2.ABSOLUTE;
3670
+ return Style$1.ABSOLUTE;
3917
3671
  /* ../foo/bar */
3918
3672
  case ".":
3919
- return Style$2.RELATIVE_PATH;
3673
+ return Style$1.RELATIVE_PATH;
3920
3674
  /* #foo */
3921
3675
  case "#":
3922
- return Style$2.ANCHOR;
3676
+ return Style$1.ANCHOR;
3923
3677
  /* foo/bar */
3924
3678
  default:
3925
- return Style$2.RELATIVE_BASE;
3679
+ return Style$1.RELATIVE_BASE;
3926
3680
  }
3927
3681
  }
3928
3682
  handleAbsolute(target, event, style) {
@@ -3980,7 +3734,7 @@ var RuleContext$1;
3980
3734
  RuleContext["MISSING_ALT"] = "missing-alt";
3981
3735
  RuleContext["MISSING_HREF"] = "missing-href";
3982
3736
  })(RuleContext$1 || (RuleContext$1 = {}));
3983
- const defaults$v = {
3737
+ const defaults$u = {
3984
3738
  accessible: true,
3985
3739
  };
3986
3740
  function findByTarget(target, siblings) {
@@ -4018,7 +3772,7 @@ function getDescription$1(context) {
4018
3772
  }
4019
3773
  class AreaAlt extends Rule {
4020
3774
  constructor(options) {
4021
- super({ ...defaults$v, ...options });
3775
+ super({ ...defaults$u, ...options });
4022
3776
  }
4023
3777
  static schema() {
4024
3778
  return {
@@ -4198,13 +3952,13 @@ class ConfigError extends UserError {
4198
3952
  }
4199
3953
  }
4200
3954
 
4201
- const defaults$u = {
3955
+ const defaults$t = {
4202
3956
  style: "lowercase",
4203
3957
  ignoreForeign: true,
4204
3958
  };
4205
3959
  class AttrCase extends Rule {
4206
3960
  constructor(options) {
4207
- super({ ...defaults$u, ...options });
3961
+ super({ ...defaults$t, ...options });
4208
3962
  this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
4209
3963
  }
4210
3964
  static schema() {
@@ -4552,7 +4306,7 @@ class AttrDelimiter extends Rule {
4552
4306
  }
4553
4307
 
4554
4308
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4555
- const defaults$t = {
4309
+ const defaults$s = {
4556
4310
  pattern: DEFAULT_PATTERN,
4557
4311
  ignoreForeign: true,
4558
4312
  };
@@ -4589,7 +4343,7 @@ function generateDescription(name, pattern) {
4589
4343
  }
4590
4344
  class AttrPattern extends Rule {
4591
4345
  constructor(options) {
4592
- super({ ...defaults$t, ...options });
4346
+ super({ ...defaults$s, ...options });
4593
4347
  this.pattern = generateRegexp(this.options.pattern);
4594
4348
  }
4595
4349
  static schema() {
@@ -4650,7 +4404,7 @@ var QuoteStyle;
4650
4404
  QuoteStyle["AUTO_QUOTE"] = "auto";
4651
4405
  QuoteStyle["ANY_QUOTE"] = "any";
4652
4406
  })(QuoteStyle || (QuoteStyle = {}));
4653
- const defaults$s = {
4407
+ const defaults$r = {
4654
4408
  style: "auto",
4655
4409
  unquoted: false,
4656
4410
  };
@@ -4717,8 +4471,8 @@ class AttrQuotes extends Rule {
4717
4471
  };
4718
4472
  }
4719
4473
  constructor(options) {
4720
- super({ ...defaults$s, ...options });
4721
- this.style = parseStyle$4(this.options.style);
4474
+ super({ ...defaults$r, ...options });
4475
+ this.style = parseStyle$3(this.options.style);
4722
4476
  }
4723
4477
  setup() {
4724
4478
  this.on("attr", (event) => {
@@ -4765,7 +4519,7 @@ class AttrQuotes extends Rule {
4765
4519
  }
4766
4520
  }
4767
4521
  }
4768
- function parseStyle$4(style) {
4522
+ function parseStyle$3(style) {
4769
4523
  switch (style.toLowerCase()) {
4770
4524
  case "auto":
4771
4525
  return QuoteStyle.AUTO_QUOTE;
@@ -4887,13 +4641,13 @@ class AttributeAllowedValues extends Rule {
4887
4641
  }
4888
4642
  }
4889
4643
 
4890
- const defaults$r = {
4644
+ const defaults$q = {
4891
4645
  style: "omit",
4892
4646
  };
4893
4647
  class AttributeBooleanStyle extends Rule {
4894
4648
  constructor(options) {
4895
- super({ ...defaults$r, ...options });
4896
- this.hasInvalidStyle = parseStyle$3(this.options.style);
4649
+ super({ ...defaults$q, ...options });
4650
+ this.hasInvalidStyle = parseStyle$2(this.options.style);
4897
4651
  }
4898
4652
  static schema() {
4899
4653
  return {
@@ -4941,7 +4695,7 @@ class AttributeBooleanStyle extends Rule {
4941
4695
  return Boolean((_a = rules[attr.key]) === null || _a === void 0 ? void 0 : _a.boolean);
4942
4696
  }
4943
4697
  }
4944
- function parseStyle$3(style) {
4698
+ function parseStyle$2(style) {
4945
4699
  switch (style.toLowerCase()) {
4946
4700
  case "omit":
4947
4701
  return (attr) => attr.value !== null;
@@ -4968,13 +4722,13 @@ function reportMessage$1(attr, style) {
4968
4722
  return "";
4969
4723
  }
4970
4724
 
4971
- const defaults$q = {
4725
+ const defaults$p = {
4972
4726
  style: "omit",
4973
4727
  };
4974
4728
  class AttributeEmptyStyle extends Rule {
4975
4729
  constructor(options) {
4976
- super({ ...defaults$q, ...options });
4977
- this.hasInvalidStyle = parseStyle$2(this.options.style);
4730
+ super({ ...defaults$p, ...options });
4731
+ this.hasInvalidStyle = parseStyle$1(this.options.style);
4978
4732
  }
4979
4733
  static schema() {
4980
4734
  return {
@@ -5032,7 +4786,7 @@ function isEmptyValue(attr) {
5032
4786
  }
5033
4787
  return attr.value === null || attr.value === "";
5034
4788
  }
5035
- function parseStyle$2(style) {
4789
+ function parseStyle$1(style) {
5036
4790
  switch (style.toLowerCase()) {
5037
4791
  case "omit":
5038
4792
  return (attr) => attr.value !== null;
@@ -5129,12 +4883,12 @@ function describePattern(pattern) {
5129
4883
  }
5130
4884
  }
5131
4885
 
5132
- const defaults$p = {
4886
+ const defaults$o = {
5133
4887
  pattern: "kebabcase",
5134
4888
  };
5135
4889
  class ClassPattern extends Rule {
5136
4890
  constructor(options) {
5137
- super({ ...defaults$p, ...options });
4891
+ super({ ...defaults$o, ...options });
5138
4892
  this.pattern = parsePattern(this.options.pattern);
5139
4893
  }
5140
4894
  static schema() {
@@ -5243,13 +4997,13 @@ class CloseOrder extends Rule {
5243
4997
  }
5244
4998
  }
5245
4999
 
5246
- const defaults$o = {
5000
+ const defaults$n = {
5247
5001
  include: null,
5248
5002
  exclude: null,
5249
5003
  };
5250
5004
  class Deprecated extends Rule {
5251
5005
  constructor(options) {
5252
- super({ ...defaults$o, ...options });
5006
+ super({ ...defaults$n, ...options });
5253
5007
  }
5254
5008
  static schema() {
5255
5009
  return {
@@ -5412,12 +5166,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5412
5166
  }
5413
5167
  };
5414
5168
 
5415
- const defaults$n = {
5169
+ const defaults$m = {
5416
5170
  style: "uppercase",
5417
5171
  };
5418
5172
  class DoctypeStyle extends Rule {
5419
5173
  constructor(options) {
5420
- super({ ...defaults$n, ...options });
5174
+ super({ ...defaults$m, ...options });
5421
5175
  }
5422
5176
  static schema() {
5423
5177
  return {
@@ -5449,12 +5203,12 @@ class DoctypeStyle extends Rule {
5449
5203
  }
5450
5204
  }
5451
5205
 
5452
- const defaults$m = {
5206
+ const defaults$l = {
5453
5207
  style: "lowercase",
5454
5208
  };
5455
5209
  class ElementCase extends Rule {
5456
5210
  constructor(options) {
5457
- super({ ...defaults$m, ...options });
5211
+ super({ ...defaults$l, ...options });
5458
5212
  this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
5459
5213
  }
5460
5214
  static schema() {
@@ -5520,14 +5274,14 @@ class ElementCase extends Rule {
5520
5274
  }
5521
5275
  }
5522
5276
 
5523
- const defaults$l = {
5277
+ const defaults$k = {
5524
5278
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5525
5279
  whitelist: [],
5526
5280
  blacklist: [],
5527
5281
  };
5528
5282
  class ElementName extends Rule {
5529
5283
  constructor(options) {
5530
- super({ ...defaults$l, ...options });
5284
+ super({ ...defaults$k, ...options });
5531
5285
  /* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
5532
5286
  this.pattern = new RegExp(this.options.pattern);
5533
5287
  }
@@ -5568,7 +5322,7 @@ class ElementName extends Rule {
5568
5322
  ...context.blacklist.map((cur) => `- ${cur}`),
5569
5323
  ];
5570
5324
  }
5571
- if (context.pattern !== defaults$l.pattern) {
5325
+ if (context.pattern !== defaults$k.pattern) {
5572
5326
  return [
5573
5327
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5574
5328
  "",
@@ -6112,7 +5866,7 @@ class EmptyTitle extends Rule {
6112
5866
  }
6113
5867
  }
6114
5868
 
6115
- const defaults$k = {
5869
+ const defaults$j = {
6116
5870
  allowArrayBrackets: true,
6117
5871
  shared: ["radio", "button", "reset", "submit"],
6118
5872
  };
@@ -6145,7 +5899,7 @@ function getDocumentation(context) {
6145
5899
  }
6146
5900
  class FormDupName extends Rule {
6147
5901
  constructor(options) {
6148
- super({ ...defaults$k, ...options });
5902
+ super({ ...defaults$j, ...options });
6149
5903
  }
6150
5904
  static schema() {
6151
5905
  return {
@@ -6305,7 +6059,7 @@ class FormDupName extends Rule {
6305
6059
  }
6306
6060
  }
6307
6061
 
6308
- const defaults$j = {
6062
+ const defaults$i = {
6309
6063
  allowMultipleH1: false,
6310
6064
  minInitialRank: "h1",
6311
6065
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
@@ -6336,7 +6090,7 @@ function parseMaxInitial(value) {
6336
6090
  }
6337
6091
  class HeadingLevel extends Rule {
6338
6092
  constructor(options) {
6339
- super({ ...defaults$j, ...options });
6093
+ super({ ...defaults$i, ...options });
6340
6094
  this.stack = [];
6341
6095
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6342
6096
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -6494,12 +6248,12 @@ class HeadingLevel extends Rule {
6494
6248
  }
6495
6249
  }
6496
6250
 
6497
- const defaults$i = {
6251
+ const defaults$h = {
6498
6252
  pattern: "kebabcase",
6499
6253
  };
6500
6254
  class IdPattern extends Rule {
6501
6255
  constructor(options) {
6502
- super({ ...defaults$i, ...options });
6256
+ super({ ...defaults$h, ...options });
6503
6257
  this.pattern = parsePattern(this.options.pattern);
6504
6258
  }
6505
6259
  static schema() {
@@ -6781,12 +6535,12 @@ function findLabelByParent(el) {
6781
6535
  return [];
6782
6536
  }
6783
6537
 
6784
- const defaults$h = {
6538
+ const defaults$g = {
6785
6539
  maxlength: 70,
6786
6540
  };
6787
6541
  class LongTitle extends Rule {
6788
6542
  constructor(options) {
6789
- super({ ...defaults$h, ...options });
6543
+ super({ ...defaults$g, ...options });
6790
6544
  this.maxlength = this.options.maxlength;
6791
6545
  }
6792
6546
  static schema() {
@@ -7012,13 +6766,13 @@ class MultipleLabeledControls extends Rule {
7012
6766
  }
7013
6767
  }
7014
6768
 
7015
- const defaults$g = {
6769
+ const defaults$f = {
7016
6770
  include: null,
7017
6771
  exclude: null,
7018
6772
  };
7019
6773
  class NoAutoplay extends Rule {
7020
6774
  constructor(options) {
7021
- super({ ...defaults$g, ...options });
6775
+ super({ ...defaults$f, ...options });
7022
6776
  }
7023
6777
  documentation(context) {
7024
6778
  const tagName = context ? ` on <${context.tagName}>` : "";
@@ -7259,14 +7013,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
7259
7013
  }
7260
7014
  }
7261
7015
 
7262
- const defaults$f = {
7016
+ const defaults$e = {
7263
7017
  include: null,
7264
7018
  exclude: null,
7265
7019
  allowedProperties: ["display"],
7266
7020
  };
7267
7021
  class NoInlineStyle extends Rule {
7268
7022
  constructor(options) {
7269
- super({ ...defaults$f, ...options });
7023
+ super({ ...defaults$e, ...options });
7270
7024
  }
7271
7025
  static schema() {
7272
7026
  return {
@@ -7468,7 +7222,7 @@ class NoMultipleMain extends Rule {
7468
7222
  }
7469
7223
  }
7470
7224
 
7471
- const defaults$e = {
7225
+ const defaults$d = {
7472
7226
  relaxed: false,
7473
7227
  };
7474
7228
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -7485,7 +7239,7 @@ const replacementTable = {
7485
7239
  };
7486
7240
  class NoRawCharacters extends Rule {
7487
7241
  constructor(options) {
7488
- super({ ...defaults$e, ...options });
7242
+ super({ ...defaults$d, ...options });
7489
7243
  this.relaxed = this.options.relaxed;
7490
7244
  }
7491
7245
  static schema() {
@@ -7663,13 +7417,13 @@ class NoRedundantRole extends Rule {
7663
7417
  }
7664
7418
 
7665
7419
  const xmlns = /^(.+):.+$/;
7666
- const defaults$d = {
7420
+ const defaults$c = {
7667
7421
  ignoreForeign: true,
7668
7422
  ignoreXML: true,
7669
7423
  };
7670
7424
  class NoSelfClosing extends Rule {
7671
7425
  constructor(options) {
7672
- super({ ...defaults$d, ...options });
7426
+ super({ ...defaults$c, ...options });
7673
7427
  }
7674
7428
  static schema() {
7675
7429
  return {
@@ -7758,13 +7512,13 @@ class NoTrailingWhitespace extends Rule {
7758
7512
  }
7759
7513
  }
7760
7514
 
7761
- const defaults$c = {
7515
+ const defaults$b = {
7762
7516
  include: null,
7763
7517
  exclude: null,
7764
7518
  };
7765
7519
  class NoUnknownElements extends Rule {
7766
7520
  constructor(options) {
7767
- super({ ...defaults$c, ...options });
7521
+ super({ ...defaults$b, ...options });
7768
7522
  }
7769
7523
  static schema() {
7770
7524
  return {
@@ -7876,13 +7630,13 @@ const replacement = {
7876
7630
  reset: '<button type="reset">',
7877
7631
  image: '<button type="button">',
7878
7632
  };
7879
- const defaults$b = {
7633
+ const defaults$a = {
7880
7634
  include: null,
7881
7635
  exclude: null,
7882
7636
  };
7883
7637
  class PreferButton extends Rule {
7884
7638
  constructor(options) {
7885
- super({ ...defaults$b, ...options });
7639
+ super({ ...defaults$a, ...options });
7886
7640
  }
7887
7641
  static schema() {
7888
7642
  return {
@@ -7957,7 +7711,7 @@ class PreferButton extends Rule {
7957
7711
  }
7958
7712
  }
7959
7713
 
7960
- const defaults$a = {
7714
+ const defaults$9 = {
7961
7715
  mapping: {
7962
7716
  article: "article",
7963
7717
  banner: "header",
@@ -7987,7 +7741,7 @@ const defaults$a = {
7987
7741
  };
7988
7742
  class PreferNativeElement extends Rule {
7989
7743
  constructor(options) {
7990
- super({ ...defaults$a, ...options });
7744
+ super({ ...defaults$9, ...options });
7991
7745
  }
7992
7746
  static schema() {
7993
7747
  return {
@@ -8107,12 +7861,12 @@ class PreferTbody extends Rule {
8107
7861
  }
8108
7862
  }
8109
7863
 
8110
- const defaults$9 = {
7864
+ const defaults$8 = {
8111
7865
  tags: ["script", "style"],
8112
7866
  };
8113
7867
  class RequireCSPNonce extends Rule {
8114
7868
  constructor(options) {
8115
- super({ ...defaults$9, ...options });
7869
+ super({ ...defaults$8, ...options });
8116
7870
  }
8117
7871
  static schema() {
8118
7872
  return {
@@ -8163,7 +7917,7 @@ class RequireCSPNonce extends Rule {
8163
7917
  }
8164
7918
  }
8165
7919
 
8166
- const defaults$8 = {
7920
+ const defaults$7 = {
8167
7921
  target: "all",
8168
7922
  include: null,
8169
7923
  exclude: null,
@@ -8175,7 +7929,7 @@ const supportSri = {
8175
7929
  };
8176
7930
  class RequireSri extends Rule {
8177
7931
  constructor(options) {
8178
- super({ ...defaults$8, ...options });
7932
+ super({ ...defaults$7, ...options });
8179
7933
  this.target = this.options.target;
8180
7934
  }
8181
7935
  static schema() {
@@ -8337,7 +8091,7 @@ class SvgFocusable extends Rule {
8337
8091
  }
8338
8092
  }
8339
8093
 
8340
- const defaults$7 = {
8094
+ const defaults$6 = {
8341
8095
  characters: [
8342
8096
  { pattern: " ", replacement: "&nbsp;", description: "non-breaking space" },
8343
8097
  { pattern: "-", replacement: "&#8209;", description: "non-breaking hyphen" },
@@ -8376,7 +8130,7 @@ function matchAll(text, regexp) {
8376
8130
  }
8377
8131
  class TelNonBreaking extends Rule {
8378
8132
  constructor(options) {
8379
- super({ ...defaults$7, ...options });
8133
+ super({ ...defaults$6, ...options });
8380
8134
  this.regex = constructRegex(this.options.characters);
8381
8135
  }
8382
8136
  static schema() {
@@ -8664,7 +8418,7 @@ class TextContent extends Rule {
8664
8418
  }
8665
8419
  }
8666
8420
 
8667
- const defaults$6 = {
8421
+ const defaults$5 = {
8668
8422
  ignoreCase: false,
8669
8423
  requireSemicolon: true,
8670
8424
  };
@@ -8706,7 +8460,7 @@ function getDescription(context, options) {
8706
8460
  }
8707
8461
  class UnknownCharReference extends Rule {
8708
8462
  constructor(options) {
8709
- super({ ...defaults$6, ...options });
8463
+ super({ ...defaults$5, ...options });
8710
8464
  }
8711
8465
  static schema() {
8712
8466
  return {
@@ -8823,12 +8577,12 @@ var RuleContext;
8823
8577
  RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
8824
8578
  RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
8825
8579
  })(RuleContext || (RuleContext = {}));
8826
- const defaults$5 = {
8580
+ const defaults$4 = {
8827
8581
  relaxed: false,
8828
8582
  };
8829
8583
  class ValidID extends Rule {
8830
8584
  constructor(options) {
8831
- super({ ...defaults$5, ...options });
8585
+ super({ ...defaults$4, ...options });
8832
8586
  }
8833
8587
  static schema() {
8834
8588
  return {
@@ -8905,130 +8659,50 @@ class ValidID extends Rule {
8905
8659
  }
8906
8660
  }
8907
8661
 
8908
- var Style$1;
8662
+ class VoidContent extends Rule {
8663
+ documentation(tagName) {
8664
+ const doc = {
8665
+ description: "HTML void elements cannot have any content and must not have content or end tag.",
8666
+ url: "https://html-validate.org/rules/void-content.html",
8667
+ };
8668
+ if (tagName) {
8669
+ doc.description = `<${tagName}> is a void element and must not have content or end tag.`;
8670
+ }
8671
+ return doc;
8672
+ }
8673
+ setup() {
8674
+ this.on("tag:end", (event) => {
8675
+ const node = event.target; // The current element being closed.
8676
+ if (!node) {
8677
+ return;
8678
+ }
8679
+ if (!node.voidElement) {
8680
+ return;
8681
+ }
8682
+ if (node.closed === exports.NodeClosed.EndTag) {
8683
+ this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location, node.tagName);
8684
+ }
8685
+ });
8686
+ }
8687
+ }
8688
+
8689
+ var Style;
8909
8690
  (function (Style) {
8910
- Style[Style["Any"] = 0] = "Any";
8911
8691
  Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
8912
8692
  Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
8913
- })(Style$1 || (Style$1 = {}));
8914
- const defaults$4 = {
8693
+ })(Style || (Style = {}));
8694
+ const defaults$3 = {
8915
8695
  style: "omit",
8916
8696
  };
8917
- class Void extends Rule {
8918
- get deprecated() {
8919
- return true;
8697
+ class VoidStyle extends Rule {
8698
+ constructor(options) {
8699
+ super({ ...defaults$3, ...options });
8700
+ this.style = parseStyle(this.options.style);
8920
8701
  }
8921
8702
  static schema() {
8922
8703
  return {
8923
8704
  style: {
8924
- enum: ["any", "omit", "selfclose", "selfclosing"],
8925
- type: "string",
8926
- },
8927
- };
8928
- }
8929
- documentation() {
8930
- return {
8931
- description: "HTML void elements cannot have any content and must not have an end tag.",
8932
- url: "https://html-validate.org/rules/void.html",
8933
- };
8934
- }
8935
- constructor(options) {
8936
- super({ ...defaults$4, ...options });
8937
- this.style = parseStyle$1(this.options.style);
8938
- }
8939
- setup() {
8940
- this.on("tag:end", (event) => {
8941
- const current = event.target; // The current element being closed
8942
- const active = event.previous; // The current active element (that is, the current element on the stack)
8943
- if (current && current.meta) {
8944
- this.validateCurrent(current);
8945
- }
8946
- if (active && active.meta) {
8947
- this.validateActive(active, active.meta);
8948
- }
8949
- });
8950
- }
8951
- validateCurrent(node) {
8952
- if (node.voidElement && node.closed === exports.NodeClosed.EndTag) {
8953
- this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location);
8954
- }
8955
- }
8956
- validateActive(node, meta) {
8957
- /* ignore foreign elements, they may or may not be self-closed and both are
8958
- * valid */
8959
- if (meta.foreign) {
8960
- return;
8961
- }
8962
- const selfOrOmitted = node.closed === exports.NodeClosed.VoidOmitted || node.closed === exports.NodeClosed.VoidSelfClosed;
8963
- if (node.voidElement) {
8964
- if (this.style === Style$1.AlwaysOmit && node.closed === exports.NodeClosed.VoidSelfClosed) {
8965
- this.report(node, `Expected omitted end tag <${node.tagName}> instead of self-closing element <${node.tagName}/>`);
8966
- }
8967
- if (this.style === Style$1.AlwaysSelfclose && node.closed === exports.NodeClosed.VoidOmitted) {
8968
- this.report(node, `Expected self-closing element <${node.tagName}/> instead of omitted end-tag <${node.tagName}>`);
8969
- }
8970
- }
8971
- if (selfOrOmitted && node.voidElement === false) {
8972
- this.report(node, `End tag for <${node.tagName}> must not be omitted`);
8973
- }
8974
- }
8975
- }
8976
- function parseStyle$1(name) {
8977
- switch (name) {
8978
- case "any":
8979
- return Style$1.Any;
8980
- case "omit":
8981
- return Style$1.AlwaysOmit;
8982
- case "selfclose":
8983
- case "selfclosing":
8984
- return Style$1.AlwaysSelfclose;
8985
- }
8986
- }
8987
-
8988
- class VoidContent extends Rule {
8989
- documentation(tagName) {
8990
- const doc = {
8991
- description: "HTML void elements cannot have any content and must not have content or end tag.",
8992
- url: "https://html-validate.org/rules/void-content.html",
8993
- };
8994
- if (tagName) {
8995
- doc.description = `<${tagName}> is a void element and must not have content or end tag.`;
8996
- }
8997
- return doc;
8998
- }
8999
- setup() {
9000
- this.on("tag:end", (event) => {
9001
- const node = event.target; // The current element being closed.
9002
- if (!node) {
9003
- return;
9004
- }
9005
- if (!node.voidElement) {
9006
- return;
9007
- }
9008
- if (node.closed === exports.NodeClosed.EndTag) {
9009
- this.report(null, `End tag for <${node.tagName}> must be omitted`, node.location, node.tagName);
9010
- }
9011
- });
9012
- }
9013
- }
9014
-
9015
- var Style;
9016
- (function (Style) {
9017
- Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
9018
- Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
9019
- })(Style || (Style = {}));
9020
- const defaults$3 = {
9021
- style: "omit",
9022
- };
9023
- class VoidStyle extends Rule {
9024
- constructor(options) {
9025
- super({ ...defaults$3, ...options });
9026
- this.style = parseStyle(this.options.style);
9027
- }
9028
- static schema() {
9029
- return {
9030
- style: {
9031
- enum: ["omit", "selfclose", "selfclosing"],
8705
+ enum: ["omit", "selfclose", "selfclosing"],
9032
8706
  type: "string",
9033
8707
  },
9034
8708
  };
@@ -9486,7 +9160,6 @@ const bundledRules = {
9486
9160
  "text-content": TextContent,
9487
9161
  "unrecognized-char-ref": UnknownCharReference,
9488
9162
  "valid-id": ValidID,
9489
- void: Void,
9490
9163
  "void-content": VoidContent,
9491
9164
  "void-style": VoidStyle,
9492
9165
  ...WCAG,
@@ -9779,7 +9452,112 @@ class ResolvedConfig {
9779
9452
  }
9780
9453
  }
9781
9454
 
9782
- let rootDirCache = null;
9455
+ function haveResolver(key, value) {
9456
+ return key in value;
9457
+ }
9458
+ function haveConfigResolver(value) {
9459
+ return haveResolver("resolveConfig", value);
9460
+ }
9461
+ function haveElementsResolver(value) {
9462
+ return haveResolver("resolveElements", value);
9463
+ }
9464
+ function havePluginResolver(value) {
9465
+ return haveResolver("resolvePlugin", value);
9466
+ }
9467
+ function haveTransformerResolver(value) {
9468
+ return haveResolver("resolveTransformer", value);
9469
+ }
9470
+ /**
9471
+ * @internal
9472
+ */
9473
+ function resolveConfig(resolvers, id, options) {
9474
+ for (const resolver of resolvers.filter(haveConfigResolver)) {
9475
+ const config = resolver.resolveConfig(id, options);
9476
+ if (config) {
9477
+ return config;
9478
+ }
9479
+ }
9480
+ throw new UserError(`Failed to load configuration from "${id}"`);
9481
+ }
9482
+ /**
9483
+ * @internal
9484
+ */
9485
+ function resolveElements(resolvers, id, options) {
9486
+ for (const resolver of resolvers.filter(haveElementsResolver)) {
9487
+ const elements = resolver.resolveElements(id, options);
9488
+ if (elements) {
9489
+ return elements;
9490
+ }
9491
+ }
9492
+ throw new UserError(`Failed to load elements from "${id}"`);
9493
+ }
9494
+ /**
9495
+ * @internal
9496
+ */
9497
+ function resolvePlugin(resolvers, id, options) {
9498
+ for (const resolver of resolvers.filter(havePluginResolver)) {
9499
+ const plugin = resolver.resolvePlugin(id, options);
9500
+ if (plugin) {
9501
+ return plugin;
9502
+ }
9503
+ }
9504
+ throw new UserError(`Failed to load plugin from "${id}"`);
9505
+ }
9506
+ /**
9507
+ * @internal
9508
+ */
9509
+ function resolveTransformer(resolvers, id, options) {
9510
+ for (const resolver of resolvers.filter(haveTransformerResolver)) {
9511
+ const transformer = resolver.resolveTransformer(id, options);
9512
+ if (transformer) {
9513
+ return transformer;
9514
+ }
9515
+ }
9516
+ throw new UserError(`Failed to load transformer from "${id}"`);
9517
+ }
9518
+
9519
+ /**
9520
+ * Create a new resolver for static content, i.e. plugins or transformers known
9521
+ * at compile time.
9522
+ *
9523
+ * @public
9524
+ * @since 8.0.0
9525
+ */
9526
+ function staticResolver(map = {}) {
9527
+ const { elements = {}, configs = {}, plugins = {}, transformers = {} } = map;
9528
+ return {
9529
+ name: "static-qresolver",
9530
+ addElements(id, value) {
9531
+ elements[id] = value;
9532
+ },
9533
+ addConfig(id, value) {
9534
+ configs[id] = value;
9535
+ },
9536
+ addPlugin(id, value) {
9537
+ plugins[id] = value;
9538
+ },
9539
+ addTransformer(id, value) {
9540
+ transformers[id] = value;
9541
+ },
9542
+ resolveElements(id) {
9543
+ var _a;
9544
+ return (_a = elements[id]) !== null && _a !== void 0 ? _a : null;
9545
+ },
9546
+ resolveConfig(id) {
9547
+ var _a;
9548
+ return (_a = configs[id]) !== null && _a !== void 0 ? _a : null;
9549
+ },
9550
+ resolvePlugin(id) {
9551
+ var _a;
9552
+ return (_a = plugins[id]) !== null && _a !== void 0 ? _a : null;
9553
+ },
9554
+ resolveTransformer(id) {
9555
+ var _a;
9556
+ return (_a = transformers[id]) !== null && _a !== void 0 ? _a : null;
9557
+ },
9558
+ };
9559
+ }
9560
+
9783
9561
  const ajv = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
9784
9562
  ajv.addMetaSchema(ajvSchemaDraft);
9785
9563
  const validator = ajv.compile(configurationSchema);
@@ -9802,30 +9580,13 @@ function mergeInternal(base, rhs) {
9802
9580
  }
9803
9581
  return dst;
9804
9582
  }
9805
- /**
9806
- * @internal
9807
- */
9808
- function configDataFromFile(filename) {
9809
- let json;
9810
- try {
9811
- /* load using require as it can process both js and json */
9812
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, should be refactored into something more typesafe */
9813
- json = requireUncached(legacyRequire, filename);
9814
- }
9815
- catch (err) {
9816
- throw new ConfigError(`Failed to read configuration from "${filename}"`, ensureError(err));
9817
- }
9818
- /* expand any relative paths */
9819
- for (const key of ["extends", "elements", "plugins"]) {
9820
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, should be refactored into something more typesafe */
9821
- const value = json[key];
9822
- if (!value)
9823
- continue;
9824
- json[key] = value.map((ref) => {
9825
- return Config.expandRelative(ref, path__default.default.dirname(filename));
9826
- });
9583
+ function toArray(value) {
9584
+ if (Array.isArray(value)) {
9585
+ return value;
9586
+ }
9587
+ else {
9588
+ return [value];
9827
9589
  }
9828
- return json;
9829
9590
  }
9830
9591
  /**
9831
9592
  * Configuration holder.
@@ -9839,7 +9600,7 @@ class Config {
9839
9600
  * Create a new blank configuration. See also `Config.defaultConfig()`.
9840
9601
  */
9841
9602
  static empty() {
9842
- return new Config({
9603
+ return new Config([], {
9843
9604
  extends: [],
9844
9605
  rules: {},
9845
9606
  plugins: [],
@@ -9849,9 +9610,9 @@ class Config {
9849
9610
  /**
9850
9611
  * Create configuration from object.
9851
9612
  */
9852
- static fromObject(options, filename = null) {
9613
+ static fromObject(resolvers, options, filename = null) {
9853
9614
  Config.validate(options, filename);
9854
- return new Config(options);
9615
+ return new Config(resolvers, options);
9855
9616
  }
9856
9617
  /**
9857
9618
  * Read configuration from filename.
@@ -9862,9 +9623,9 @@ class Config {
9862
9623
  * @internal
9863
9624
  * @param filename - The file to read from
9864
9625
  */
9865
- static fromFile(filename) {
9866
- const configdata = configDataFromFile(filename);
9867
- return Config.fromObject(configdata, filename);
9626
+ static fromFile(resolvers, filename) {
9627
+ const configData = resolveConfig(toArray(resolvers), filename, { cache: false });
9628
+ return Config.fromObject(resolvers, configData, filename);
9868
9629
  }
9869
9630
  /**
9870
9631
  * Validate configuration data.
@@ -9894,12 +9655,12 @@ class Config {
9894
9655
  * Load a default configuration object.
9895
9656
  */
9896
9657
  static defaultConfig() {
9897
- return new Config(defaultConfig);
9658
+ return new Config([], defaultConfig);
9898
9659
  }
9899
9660
  /**
9900
9661
  * @internal
9901
9662
  */
9902
- constructor(options) {
9663
+ constructor(resolvers, options) {
9903
9664
  var _a;
9904
9665
  this.transformers = [];
9905
9666
  const initial = {
@@ -9908,10 +9669,10 @@ class Config {
9908
9669
  rules: {},
9909
9670
  transform: {},
9910
9671
  };
9911
- this.config = mergeInternal(initial, options || {});
9672
+ this.config = mergeInternal(initial, options);
9912
9673
  this.metaTable = null;
9913
- this.rootDir = this.findRootDir();
9914
9674
  this.initialized = false;
9675
+ this.resolvers = toArray(resolvers);
9915
9676
  /* load plugins */
9916
9677
  this.plugins = this.loadPlugins(this.config.plugins || []);
9917
9678
  this.configurations = this.loadConfigurations(this.plugins);
@@ -9957,8 +9718,8 @@ class Config {
9957
9718
  * @public
9958
9719
  * @param rhs - Configuration to merge with this one.
9959
9720
  */
9960
- merge(rhs) {
9961
- return new Config(mergeInternal(this.config, rhs.config));
9721
+ merge(resolvers, rhs) {
9722
+ return new Config(resolvers, mergeInternal(this.config, rhs.config));
9962
9723
  }
9963
9724
  extendConfig(entries) {
9964
9725
  if (entries.length === 0) {
@@ -9972,7 +9733,7 @@ class Config {
9972
9733
  extended = this.configurations.get(entry);
9973
9734
  }
9974
9735
  else {
9975
- extended = Config.fromFile(entry).config;
9736
+ extended = Config.fromFile(this.resolvers, entry).config;
9976
9737
  }
9977
9738
  base = mergeInternal(base, extended);
9978
9739
  }
@@ -10009,30 +9770,20 @@ class Config {
10009
9770
  metaTable.loadFromObject(bundled);
10010
9771
  continue;
10011
9772
  }
10012
- /* assume it is loadable with require() */
10013
- const id = entry.replace("<rootDir>", this.rootDir);
9773
+ /* load with resolver */
10014
9774
  try {
10015
- const data = legacyRequire(id);
10016
- metaTable.loadFromObject(data, id);
9775
+ const data = resolveElements(this.resolvers, entry, { cache: false });
9776
+ metaTable.loadFromObject(data, entry);
10017
9777
  }
10018
9778
  catch (err) {
10019
9779
  /* istanbul ignore next: only used as a fallback */
10020
9780
  const message = err instanceof Error ? err.message : String(err);
10021
- throw new ConfigError(`Failed to load elements from "${id}": ${message}`, ensureError(err));
9781
+ throw new ConfigError(`Failed to load elements from "${entry}": ${message}`, ensureError(err));
10022
9782
  }
10023
9783
  }
10024
9784
  metaTable.init();
10025
9785
  return (this.metaTable = metaTable);
10026
9786
  }
10027
- /**
10028
- * @internal exposed for testing only
10029
- */
10030
- static expandRelative(src, currentPath) {
10031
- if (src[0] === ".") {
10032
- return path__default.default.normalize(`${currentPath}/${src}`);
10033
- }
10034
- return src;
10035
- }
10036
9787
  /**
10037
9788
  * Get a copy of internal configuration data.
10038
9789
  *
@@ -10084,7 +9835,7 @@ class Config {
10084
9835
  return plugin;
10085
9836
  }
10086
9837
  try {
10087
- const plugin = legacyRequire(moduleName.replace("<rootDir>", this.rootDir));
9838
+ const plugin = resolvePlugin(this.resolvers, moduleName, { cache: true });
10088
9839
  plugin.name = plugin.name || moduleName;
10089
9840
  plugin.originalName = moduleName;
10090
9841
  return plugin;
@@ -10257,57 +10008,7 @@ class Config {
10257
10008
  return plugin.transformer;
10258
10009
  }
10259
10010
  getTransformerFromModule(name) {
10260
- /* expand <rootDir> */
10261
- const moduleName = name.replace("<rootDir>", this.rootDir);
10262
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- technical debt, the code kinda does the right thing but it should be reflected in the typing too */
10263
- const fn = legacyRequire(moduleName);
10264
- /* sanity check */
10265
- if (typeof fn !== "function") {
10266
- /* this is not a proper transformer, is it a plugin exposing a transformer? */
10267
- if (fn.transformer) {
10268
- throw new ConfigError(`Module is not a valid transformer. This looks like a plugin, did you forget to load the plugin first?`);
10269
- }
10270
- throw new ConfigError(`Module is not a valid transformer.`);
10271
- }
10272
- return fn;
10273
- }
10274
- /**
10275
- * @internal
10276
- */
10277
- get rootDirCache() {
10278
- /* return global instance */
10279
- return rootDirCache;
10280
- }
10281
- set rootDirCache(value) {
10282
- /* set global instance */
10283
- rootDirCache = value;
10284
- }
10285
- /**
10286
- * @internal
10287
- */
10288
- findRootDir() {
10289
- const cache = this.rootDirCache;
10290
- if (cache !== null) {
10291
- return cache;
10292
- }
10293
- /* try to locate package.json */
10294
- let current = process.cwd();
10295
- // eslint-disable-next-line no-constant-condition -- break outs when filesystem is traversed
10296
- while (true) {
10297
- const search = path__default.default.join(current, "package.json");
10298
- if (fs__default.default.existsSync(search)) {
10299
- return (this.rootDirCache = current);
10300
- }
10301
- /* get the parent directory */
10302
- const child = current;
10303
- current = path__default.default.dirname(current);
10304
- /* stop if this is the root directory */
10305
- if (current === child) {
10306
- break;
10307
- }
10308
- }
10309
- /* default to working directory if no package.json is found */
10310
- return (this.rootDirCache = process.cwd());
10011
+ return resolveTransformer(this.resolvers, name, { cache: true });
10311
10012
  }
10312
10013
  }
10313
10014
 
@@ -10320,19 +10021,25 @@ class Config {
10320
10021
  * @public
10321
10022
  */
10322
10023
  class ConfigLoader {
10323
- constructor(config, configFactory = Config) {
10324
- const defaults = configFactory.empty();
10325
- this.configFactory = configFactory;
10326
- this.globalConfig = defaults.merge(config ? this.loadFromObject(config) : this.defaultConfig());
10024
+ constructor(resolvers, config) {
10025
+ const defaults = Config.empty();
10026
+ this.resolvers = resolvers;
10027
+ this.globalConfig = defaults.merge(this.resolvers, config ? this.loadFromObject(config) : this.defaultConfig());
10028
+ }
10029
+ /**
10030
+ * @internal For testing only
10031
+ */
10032
+ _getGlobalConfig() {
10033
+ return this.globalConfig.get();
10327
10034
  }
10328
10035
  empty() {
10329
- return this.configFactory.empty();
10036
+ return Config.empty();
10330
10037
  }
10331
10038
  loadFromObject(options, filename) {
10332
- return this.configFactory.fromObject(options, filename);
10039
+ return Config.fromObject(this.resolvers, options, filename);
10333
10040
  }
10334
10041
  loadFromFile(filename) {
10335
- return this.configFactory.fromFile(filename);
10042
+ return Config.fromFile(this.resolvers, filename);
10336
10043
  }
10337
10044
  }
10338
10045
 
@@ -11320,7 +11027,7 @@ class Engine {
11320
11027
  /**
11321
11028
  * Get rule documentation.
11322
11029
  */
11323
- getRuleDocumentation(ruleId, context) {
11030
+ getRuleDocumentation({ ruleId, context, }) {
11324
11031
  const rules = this.config.getRules();
11325
11032
  const ruleData = rules.get(ruleId);
11326
11033
  if (ruleData) {
@@ -11557,6 +11264,10 @@ class Engine {
11557
11264
  }
11558
11265
  }
11559
11266
 
11267
+ const defaultResolvers = [];
11268
+ function hasResolver(value) {
11269
+ return Array.isArray(value[0]);
11270
+ }
11560
11271
  /**
11561
11272
  * The static configuration loader does not do any per-handle lookup. Only the
11562
11273
  * global or per-call configuration is used.
@@ -11567,13 +11278,23 @@ class Engine {
11567
11278
  * @public
11568
11279
  */
11569
11280
  class StaticConfigLoader extends ConfigLoader {
11281
+ constructor(...args) {
11282
+ if (hasResolver(args)) {
11283
+ const [resolvers, config] = args;
11284
+ super(resolvers, config);
11285
+ }
11286
+ else {
11287
+ const [config] = args;
11288
+ super(defaultResolvers, config);
11289
+ }
11290
+ }
11570
11291
  getConfigFor(_handle, configOverride) {
11571
11292
  const override = this.loadFromObject(configOverride || {});
11572
11293
  if (override.isRootFound()) {
11573
11294
  override.init();
11574
11295
  return override.resolve();
11575
11296
  }
11576
- const merged = this.globalConfig.merge(override);
11297
+ const merged = this.globalConfig.merge(this.resolvers, override);
11577
11298
  merged.init();
11578
11299
  return merged.resolve();
11579
11300
  }
@@ -11626,6 +11347,33 @@ class HtmlValidate {
11626
11347
  };
11627
11348
  return this.validateSource(source, options);
11628
11349
  }
11350
+ validateStringSync(str, arg1, arg2, arg3) {
11351
+ const filename = typeof arg1 === "string" ? arg1 : "inline";
11352
+ const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
11353
+ const hooks = isSourceHooks(arg1) ? arg1 : isSourceHooks(arg2) ? arg2 : arg3;
11354
+ const source = {
11355
+ data: str,
11356
+ filename,
11357
+ line: 1,
11358
+ column: 1,
11359
+ offset: 0,
11360
+ hooks,
11361
+ };
11362
+ return this.validateSourceSync(source, options);
11363
+ }
11364
+ /**
11365
+ * Parse and validate HTML from [[Source]].
11366
+ *
11367
+ * @public
11368
+ * @param input - Source to parse.
11369
+ * @returns Report output.
11370
+ */
11371
+ async validateSource(input, configOverride) {
11372
+ const config = await this.getConfigFor(input.filename, configOverride);
11373
+ const source = config.transformSource(input);
11374
+ const engine = new Engine(config, Parser);
11375
+ return engine.lint(source);
11376
+ }
11629
11377
  /**
11630
11378
  * Parse and validate HTML from [[Source]].
11631
11379
  *
@@ -11633,8 +11381,8 @@ class HtmlValidate {
11633
11381
  * @param input - Source to parse.
11634
11382
  * @returns Report output.
11635
11383
  */
11636
- validateSource(input, configOverride) {
11637
- const config = this.getConfigFor(input.filename, configOverride);
11384
+ validateSourceSync(input, configOverride) {
11385
+ const config = this.getConfigForSync(input.filename, configOverride);
11638
11386
  const source = config.transformSource(input);
11639
11387
  const engine = new Engine(config, Parser);
11640
11388
  return engine.lint(source);
@@ -11646,8 +11394,21 @@ class HtmlValidate {
11646
11394
  * @param filename - Filename to read and parse.
11647
11395
  * @returns Report output.
11648
11396
  */
11649
- validateFile(filename) {
11650
- const config = this.getConfigFor(filename);
11397
+ async validateFile(filename) {
11398
+ const config = await this.getConfigFor(filename);
11399
+ const source = config.transformFilename(filename);
11400
+ const engine = new Engine(config, Parser);
11401
+ return Promise.resolve(engine.lint(source));
11402
+ }
11403
+ /**
11404
+ * Parse and validate HTML from file.
11405
+ *
11406
+ * @public
11407
+ * @param filename - Filename to read and parse.
11408
+ * @returns Report output.
11409
+ */
11410
+ validateFileSync(filename) {
11411
+ const config = this.getConfigForSync(filename);
11651
11412
  const source = config.transformFilename(filename);
11652
11413
  const engine = new Engine(config, Parser);
11653
11414
  return engine.lint(source);
@@ -11659,8 +11420,19 @@ class HtmlValidate {
11659
11420
  * @param filenames - Filenames to read and parse.
11660
11421
  * @returns Report output.
11661
11422
  */
11662
- validateMultipleFiles(filenames) {
11663
- return Reporter.merge(filenames.map((filename) => this.validateFile(filename)));
11423
+ async validateMultipleFiles(filenames) {
11424
+ const report = Reporter.merge(filenames.map((filename) => this.validateFileSync(filename)));
11425
+ return Promise.resolve(report);
11426
+ }
11427
+ /**
11428
+ * Parse and validate HTML from multiple files. Result is merged together to a
11429
+ * single report.
11430
+ *
11431
+ * @param filenames - Filenames to read and parse.
11432
+ * @returns Report output.
11433
+ */
11434
+ validateMultipleFilesSync(filenames) {
11435
+ return Reporter.merge(filenames.map((filename) => this.validateFileSync(filename)));
11664
11436
  }
11665
11437
  /**
11666
11438
  * Returns true if the given filename can be validated.
@@ -11671,14 +11443,33 @@ class HtmlValidate {
11671
11443
  * This is mostly useful for tooling to determine whenever to validate the
11672
11444
  * file or not. CLI tools will run on all the given files anyway.
11673
11445
  */
11674
- canValidate(filename) {
11446
+ async canValidate(filename) {
11675
11447
  /* .html is always supported */
11676
11448
  const extension = path__default.default.extname(filename).toLowerCase();
11677
11449
  if (extension === ".html") {
11678
11450
  return true;
11679
11451
  }
11680
11452
  /* test if there is a matching transformer */
11681
- const config = this.getConfigFor(filename);
11453
+ const config = await this.getConfigFor(filename);
11454
+ return config.canTransform(filename);
11455
+ }
11456
+ /**
11457
+ * Returns true if the given filename can be validated.
11458
+ *
11459
+ * A file is considered to be validatable if the extension is `.html` or if a
11460
+ * transformer matches the filename.
11461
+ *
11462
+ * This is mostly useful for tooling to determine whenever to validate the
11463
+ * file or not. CLI tools will run on all the given files anyway.
11464
+ */
11465
+ canValidateSync(filename) {
11466
+ /* .html is always supported */
11467
+ const extension = path__default.default.extname(filename).toLowerCase();
11468
+ if (extension === ".html") {
11469
+ return true;
11470
+ }
11471
+ /* test if there is a matching transformer */
11472
+ const config = this.getConfigForSync(filename);
11682
11473
  return config.canTransform(filename);
11683
11474
  }
11684
11475
  /**
@@ -11691,7 +11482,7 @@ class HtmlValidate {
11691
11482
  * @param filename - Filename to tokenize.
11692
11483
  */
11693
11484
  dumpTokens(filename) {
11694
- const config = this.getConfigFor(filename);
11485
+ const config = this.getConfigForSync(filename);
11695
11486
  const source = config.transformFilename(filename);
11696
11487
  const engine = new Engine(config, Parser);
11697
11488
  return engine.dumpTokens(source);
@@ -11706,7 +11497,7 @@ class HtmlValidate {
11706
11497
  * @param filename - Filename to dump events from.
11707
11498
  */
11708
11499
  dumpEvents(filename) {
11709
- const config = this.getConfigFor(filename);
11500
+ const config = this.getConfigForSync(filename);
11710
11501
  const source = config.transformFilename(filename);
11711
11502
  const engine = new Engine(config, Parser);
11712
11503
  return engine.dumpEvents(source);
@@ -11721,7 +11512,7 @@ class HtmlValidate {
11721
11512
  * @param filename - Filename to dump DOM tree from.
11722
11513
  */
11723
11514
  dumpTree(filename) {
11724
- const config = this.getConfigFor(filename);
11515
+ const config = this.getConfigForSync(filename);
11725
11516
  const source = config.transformFilename(filename);
11726
11517
  const engine = new Engine(config, Parser);
11727
11518
  return engine.dumpTree(source);
@@ -11736,7 +11527,7 @@ class HtmlValidate {
11736
11527
  * @param filename - Filename to dump source from.
11737
11528
  */
11738
11529
  dumpSource(filename) {
11739
- const config = this.getConfigFor(filename);
11530
+ const config = this.getConfigForSync(filename);
11740
11531
  const sources = config.transformFilename(filename);
11741
11532
  return sources.reduce((result, source) => {
11742
11533
  result.push(`Source ${source.filename}@${source.line}:${source.column} (offset: ${source.offset})`);
@@ -11772,37 +11563,95 @@ class HtmlValidate {
11772
11563
  * handled by html-validate but the path will be used when resolving
11773
11564
  * configuration. As a rule-of-thumb, set it to the elements json file.
11774
11565
  */
11775
- getElementsSchema(filename) {
11776
- const config = this.getConfigFor(filename !== null && filename !== void 0 ? filename : "inline");
11566
+ async getElementsSchema(filename) {
11567
+ const config = await this.getConfigFor(filename !== null && filename !== void 0 ? filename : "inline");
11777
11568
  const metaTable = config.getMetaTable();
11778
11569
  return metaTable.getJSONSchema();
11779
11570
  }
11571
+ /**
11572
+ * Get effective metadata element schema.
11573
+ *
11574
+ * If a filename is given the configured plugins can extend the
11575
+ * schema. Filename must not be an existing file or a filetype normally
11576
+ * handled by html-validate but the path will be used when resolving
11577
+ * configuration. As a rule-of-thumb, set it to the elements json file.
11578
+ */
11579
+ getElementsSchemaSync(filename) {
11580
+ const config = this.getConfigForSync(filename !== null && filename !== void 0 ? filename : "inline");
11581
+ const metaTable = config.getMetaTable();
11582
+ return metaTable.getJSONSchema();
11583
+ }
11584
+ async getContextualDocumentation(message, filenameOrConfig = "inline") {
11585
+ const config = typeof filenameOrConfig === "string"
11586
+ ? await this.getConfigFor(filenameOrConfig)
11587
+ : await filenameOrConfig;
11588
+ const engine = new Engine(config, Parser);
11589
+ return engine.getRuleDocumentation(message);
11590
+ }
11591
+ getContextualDocumentationSync(message, filenameOrConfig = "inline") {
11592
+ const config = typeof filenameOrConfig === "string"
11593
+ ? this.getConfigForSync(filenameOrConfig)
11594
+ : filenameOrConfig;
11595
+ const engine = new Engine(config, Parser);
11596
+ return engine.getRuleDocumentation(message);
11597
+ }
11780
11598
  /**
11781
11599
  * Get contextual documentation for the given rule.
11782
11600
  *
11783
11601
  * Typical usage:
11784
11602
  *
11785
11603
  * ```js
11786
- * const report = htmlvalidate.validateFile("my-file.html");
11604
+ * const report = await htmlvalidate.validateFile("my-file.html");
11787
11605
  * for (const result of report.results){
11788
- * const config = htmlvalidate.getConfigFor(result.filePath);
11606
+ * const config = await htmlvalidate.getConfigFor(result.filePath);
11789
11607
  * for (const message of result.messages){
11790
- * const documentation = htmlvalidate.getRuleDocumentation(message.ruleId, config, message.context);
11608
+ * const documentation = await htmlvalidate.getRuleDocumentation(message.ruleId, config, message.context);
11791
11609
  * // do something with documentation
11792
11610
  * }
11793
11611
  * }
11794
11612
  * ```
11795
11613
  *
11614
+ * @public
11615
+ * @deprecated Deprecated since 8.0.0, use [[getContextualDocumentation]] instead.
11796
11616
  * @param ruleId - Rule to get documentation for.
11797
11617
  * @param config - If set it provides more accurate description by using the
11798
11618
  * correct configuration for the file.
11799
11619
  * @param context - If set to `Message.context` some rules can provide
11800
11620
  * contextual details and suggestions.
11801
11621
  */
11802
- getRuleDocumentation(ruleId, config = null, context = null) {
11622
+ async getRuleDocumentation(ruleId, config = null, context = null) {
11803
11623
  const c = config || this.getConfigFor("inline");
11624
+ const engine = new Engine(await c, Parser);
11625
+ return engine.getRuleDocumentation({ ruleId, context });
11626
+ }
11627
+ /**
11628
+ * Get contextual documentation for the given rule.
11629
+ *
11630
+ * Typical usage:
11631
+ *
11632
+ * ```js
11633
+ * const report = htmlvalidate.validateFileSync("my-file.html");
11634
+ * for (const result of report.results){
11635
+ * const config = htmlvalidate.getConfigForSync(result.filePath);
11636
+ * for (const message of result.messages){
11637
+ * const documentation = htmlvalidate.getRuleDocumentationSync(message.ruleId, config, message.context);
11638
+ * // do something with documentation
11639
+ * }
11640
+ * }
11641
+ * ```
11642
+ *
11643
+ * @public
11644
+ * @deprecated Deprecated since 8.0.0, use [[getContextualDocumentationSync]] instead.
11645
+ * @param ruleId - Rule to get documentation for.
11646
+ * @param config - If set it provides more accurate description by using the
11647
+ * correct configuration for the file.
11648
+ * @param context - If set to `Message.context` some rules can provide
11649
+ * contextual details and suggestions.
11650
+ */
11651
+ getRuleDocumentationSync(ruleId, config = null, context = null) {
11652
+ const c = config || this.getConfigForSync("inline");
11804
11653
  const engine = new Engine(c, Parser);
11805
- return engine.getRuleDocumentation(ruleId, context);
11654
+ return engine.getRuleDocumentation({ ruleId, context });
11806
11655
  }
11807
11656
  /**
11808
11657
  * Create a parser configured for given filename.
@@ -11810,8 +11659,8 @@ class HtmlValidate {
11810
11659
  * @internal
11811
11660
  * @param source - Source to use.
11812
11661
  */
11813
- getParserFor(source) {
11814
- const config = this.getConfigFor(source.filename);
11662
+ async getParserFor(source) {
11663
+ const config = await this.getConfigFor(source.filename);
11815
11664
  return new Parser(config);
11816
11665
  }
11817
11666
  /**
@@ -11825,11 +11674,19 @@ class HtmlValidate {
11825
11674
  */
11826
11675
  getConfigFor(filename, configOverride) {
11827
11676
  const config = this.configLoader.getConfigFor(filename, configOverride);
11828
- /* for backwards compatibility only */
11829
- if (config instanceof Config) {
11830
- return config.resolve();
11831
- }
11832
- return config;
11677
+ return Promise.resolve(config);
11678
+ }
11679
+ /**
11680
+ * Get configuration for given filename.
11681
+ *
11682
+ * See [[FileSystemConfigLoader]] for details.
11683
+ *
11684
+ * @public
11685
+ * @param filename - Filename to get configuration for.
11686
+ * @param configOverride - Configuration to apply last.
11687
+ */
11688
+ getConfigForSync(filename, configOverride) {
11689
+ return this.configLoader.getConfigFor(filename, configOverride);
11833
11690
  }
11834
11691
  /**
11835
11692
  * Flush configuration cache. Clears full cache unless a filename is given.
@@ -11848,7 +11705,7 @@ class HtmlValidate {
11848
11705
  /** @public */
11849
11706
  const name = "html-validate";
11850
11707
  /** @public */
11851
- const version = "7.18.1";
11708
+ const version = "8.0.1";
11852
11709
  /** @public */
11853
11710
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11854
11711
 
@@ -11874,6 +11731,7 @@ const defaults$1 = {
11874
11731
  * option is used a warning is displayed on the console.
11875
11732
  *
11876
11733
  * @public
11734
+ * @since v5.0.0
11877
11735
  * @param name - Name of plugin
11878
11736
  * @param declared - What library versions the plugin support (e.g. declared peerDependencies)
11879
11737
  * @returns - `true` if version is compatible
@@ -11910,139 +11768,6 @@ function ruleExists(ruleId) {
11910
11768
  return ruleIds.has(ruleId);
11911
11769
  }
11912
11770
 
11913
- /**
11914
- * @internal
11915
- */
11916
- function findConfigurationFiles(directory) {
11917
- return ["json", "cjs", "js"]
11918
- .map((extension) => path__default.default.join(directory, `.htmlvalidate.${extension}`))
11919
- .filter((filePath) => fs__default.default.existsSync(filePath));
11920
- }
11921
- /**
11922
- * Loads configuration by traversing filesystem.
11923
- *
11924
- * Configuration is read from three sources and in the following order:
11925
- *
11926
- * 1. Global configuration passed to constructor.
11927
- * 2. Configuration files found when traversing the directory structure.
11928
- * 3. Override passed to this function.
11929
- *
11930
- * The following configuration filenames are searched:
11931
- *
11932
- * - `.htmlvalidate.json`
11933
- * - `.htmlvalidate.js`
11934
- * - `.htmlvalidate.cjs`
11935
- *
11936
- * Global configuration is used when no configuration file is found. The
11937
- * result is always merged with override if present.
11938
- *
11939
- * The `root` property set to `true` affects the configuration as following:
11940
- *
11941
- * 1. If set in override the override is returned as-is.
11942
- * 2. If set in the global config the override is merged into global and
11943
- * returned. No configuration files are searched.
11944
- * 3. Setting `root` in configuration file only stops directory traversal.
11945
- *
11946
- * @public
11947
- */
11948
- class FileSystemConfigLoader extends ConfigLoader {
11949
- /**
11950
- * @param config - Global configuration
11951
- * @param configFactory - Optional configuration factory
11952
- */
11953
- constructor(config, configFactory = Config) {
11954
- super(config, configFactory);
11955
- this.cache = new Map();
11956
- }
11957
- /**
11958
- * Get configuration for given filename.
11959
- *
11960
- * @param filename - Filename to get configuration for.
11961
- * @param configOverride - Configuration to merge final result with.
11962
- */
11963
- getConfigFor(filename, configOverride) {
11964
- /* special case when the overridden configuration is marked as root, should
11965
- * not try to load any more configuration files */
11966
- const override = this.loadFromObject(configOverride || {});
11967
- if (override.isRootFound()) {
11968
- override.init();
11969
- return override.resolve();
11970
- }
11971
- /* special case when the global configuration is marked as root, should not
11972
- * try to load and more configuration files */
11973
- if (this.globalConfig.isRootFound()) {
11974
- const merged = this.globalConfig.merge(override);
11975
- merged.init();
11976
- return merged.resolve();
11977
- }
11978
- const config = this.fromFilename(filename);
11979
- const merged = config ? config.merge(override) : this.globalConfig.merge(override);
11980
- merged.init();
11981
- return merged.resolve();
11982
- }
11983
- /**
11984
- * Flush configuration cache.
11985
- *
11986
- * @param filename - If given only the cache for that file is flushed.
11987
- */
11988
- flushCache(filename) {
11989
- if (filename) {
11990
- this.cache.delete(filename);
11991
- }
11992
- else {
11993
- this.cache.clear();
11994
- }
11995
- }
11996
- /**
11997
- * Load raw configuration from directory traversal.
11998
- *
11999
- * This configuration is not merged with global configuration and may return
12000
- * `null` if no configuration files are found.
12001
- */
12002
- fromFilename(filename) {
12003
- if (filename === "inline") {
12004
- return null;
12005
- }
12006
- const cache = this.cache.get(filename);
12007
- if (cache) {
12008
- return cache;
12009
- }
12010
- let found = false;
12011
- let current = path__default.default.resolve(path__default.default.dirname(filename));
12012
- let config = this.empty();
12013
- // eslint-disable-next-line no-constant-condition -- it will break out when filesystem is traversed
12014
- while (true) {
12015
- /* search configuration files in current directory */
12016
- for (const configFile of findConfigurationFiles(current)) {
12017
- const local = this.loadFromFile(configFile);
12018
- found = true;
12019
- config = local.merge(config);
12020
- }
12021
- /* stop if a configuration with "root" is set to true */
12022
- if (config.isRootFound()) {
12023
- break;
12024
- }
12025
- /* get the parent directory */
12026
- const child = current;
12027
- current = path__default.default.dirname(current);
12028
- /* stop if this is the root directory */
12029
- if (current === child) {
12030
- break;
12031
- }
12032
- }
12033
- /* no config was found by loader, return null and let caller decide what to do */
12034
- if (!found) {
12035
- this.cache.set(filename, null);
12036
- return null;
12037
- }
12038
- this.cache.set(filename, config);
12039
- return config;
12040
- }
12041
- defaultConfig() {
12042
- return this.configFactory.defaultConfig();
12043
- }
12044
- }
12045
-
12046
11771
  const entities = {
12047
11772
  ">": "&gt;",
12048
11773
  "<": "&lt;",
@@ -12303,7 +12028,6 @@ exports.DOMTokenList = DOMTokenList;
12303
12028
  exports.DOMTree = DOMTree;
12304
12029
  exports.DynamicValue = DynamicValue;
12305
12030
  exports.EventHandler = EventHandler;
12306
- exports.FileSystemConfigLoader = FileSystemConfigLoader;
12307
12031
  exports.HtmlElement = HtmlElement;
12308
12032
  exports.HtmlValidate = HtmlValidate;
12309
12033
  exports.MetaCopyableProperty = MetaCopyableProperty;
@@ -12316,7 +12040,6 @@ exports.ResolvedConfig = ResolvedConfig;
12316
12040
  exports.Rule = Rule;
12317
12041
  exports.SchemaValidationError = SchemaValidationError;
12318
12042
  exports.StaticConfigLoader = StaticConfigLoader;
12319
- exports.TemplateExtractor = TemplateExtractor;
12320
12043
  exports.TextNode = TextNode;
12321
12044
  exports.UserError = UserError;
12322
12045
  exports.Validator = Validator;
@@ -12324,16 +12047,15 @@ exports.WrappedError = WrappedError;
12324
12047
  exports.bugs = bugs;
12325
12048
  exports.codeframe = codeframe;
12326
12049
  exports.compatibilityCheck = compatibilityCheck;
12327
- exports.configDataFromFile = configDataFromFile;
12328
12050
  exports.definePlugin = definePlugin;
12329
12051
  exports.ensureError = ensureError;
12330
12052
  exports.generateIdSelector = generateIdSelector;
12331
12053
  exports.getFormatter = getFormatter;
12332
12054
  exports.isElementNode = isElementNode;
12333
12055
  exports.isTextNode = isTextNode;
12334
- exports.legacyRequire = legacyRequire;
12335
12056
  exports.name = name;
12336
12057
  exports.ruleExists = ruleExists;
12337
12058
  exports.sliceLocation = sliceLocation;
12059
+ exports.staticResolver = staticResolver;
12338
12060
  exports.version = version;
12339
12061
  //# sourceMappingURL=core.js.map