@alexlit/lint-kit 190.0.1 → 191.0.0

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.
Files changed (171) hide show
  1. package/package.json +1 -1
  2. package/packages/config-eslint/package.json +3 -3
  3. package/packages/config-markdownlint/package.json +2 -2
  4. package/packages/config-markdownlint/node_modules/ansi-regex/index.d.ts +0 -33
  5. package/packages/config-markdownlint/node_modules/ansi-regex/index.js +0 -14
  6. package/packages/config-markdownlint/node_modules/ansi-regex/license +0 -9
  7. package/packages/config-markdownlint/node_modules/ansi-regex/package.json +0 -61
  8. package/packages/config-markdownlint/node_modules/ansi-regex/readme.md +0 -66
  9. package/packages/config-markdownlint/node_modules/markdownlint/CHANGELOG.md +0 -529
  10. package/packages/config-markdownlint/node_modules/markdownlint/CONTRIBUTING.md +0 -92
  11. package/packages/config-markdownlint/node_modules/markdownlint/LICENSE +0 -21
  12. package/packages/config-markdownlint/node_modules/markdownlint/README.md +0 -1112
  13. package/packages/config-markdownlint/node_modules/markdownlint/doc/CustomRules.md +0 -194
  14. package/packages/config-markdownlint/node_modules/markdownlint/doc/Prettier.md +0 -27
  15. package/packages/config-markdownlint/node_modules/markdownlint/doc/ReleaseProcess.md +0 -20
  16. package/packages/config-markdownlint/node_modules/markdownlint/doc/Rules.md +0 -2858
  17. package/packages/config-markdownlint/node_modules/markdownlint/doc/md001.md +0 -51
  18. package/packages/config-markdownlint/node_modules/markdownlint/doc/md003.md +0 -59
  19. package/packages/config-markdownlint/node_modules/markdownlint/doc/md004.md +0 -50
  20. package/packages/config-markdownlint/node_modules/markdownlint/doc/md005.md +0 -53
  21. package/packages/config-markdownlint/node_modules/markdownlint/doc/md007.md +0 -52
  22. package/packages/config-markdownlint/node_modules/markdownlint/doc/md009.md +0 -50
  23. package/packages/config-markdownlint/node_modules/markdownlint/doc/md010.md +0 -62
  24. package/packages/config-markdownlint/node_modules/markdownlint/doc/md011.md +0 -30
  25. package/packages/config-markdownlint/node_modules/markdownlint/doc/md012.md +0 -38
  26. package/packages/config-markdownlint/node_modules/markdownlint/doc/md013.md +0 -58
  27. package/packages/config-markdownlint/node_modules/markdownlint/doc/md014.md +0 -54
  28. package/packages/config-markdownlint/node_modules/markdownlint/doc/md018.md +0 -27
  29. package/packages/config-markdownlint/node_modules/markdownlint/doc/md019.md +0 -28
  30. package/packages/config-markdownlint/node_modules/markdownlint/doc/md020.md +0 -29
  31. package/packages/config-markdownlint/node_modules/markdownlint/doc/md021.md +0 -31
  32. package/packages/config-markdownlint/node_modules/markdownlint/doc/md022.md +0 -67
  33. package/packages/config-markdownlint/node_modules/markdownlint/doc/md023.md +0 -33
  34. package/packages/config-markdownlint/node_modules/markdownlint/doc/md024.md +0 -44
  35. package/packages/config-markdownlint/node_modules/markdownlint/doc/md025.md +0 -49
  36. package/packages/config-markdownlint/node_modules/markdownlint/doc/md026.md +0 -40
  37. package/packages/config-markdownlint/node_modules/markdownlint/doc/md027.md +0 -32
  38. package/packages/config-markdownlint/node_modules/markdownlint/doc/md028.md +0 -44
  39. package/packages/config-markdownlint/node_modules/markdownlint/doc/md029.md +0 -100
  40. package/packages/config-markdownlint/node_modules/markdownlint/doc/md030.md +0 -82
  41. package/packages/config-markdownlint/node_modules/markdownlint/doc/md031.md +0 -50
  42. package/packages/config-markdownlint/node_modules/markdownlint/doc/md032.md +0 -55
  43. package/packages/config-markdownlint/node_modules/markdownlint/doc/md033.md +0 -33
  44. package/packages/config-markdownlint/node_modules/markdownlint/doc/md034.md +0 -55
  45. package/packages/config-markdownlint/node_modules/markdownlint/doc/md035.md +0 -44
  46. package/packages/config-markdownlint/node_modules/markdownlint/doc/md036.md +0 -45
  47. package/packages/config-markdownlint/node_modules/markdownlint/doc/md037.md +0 -37
  48. package/packages/config-markdownlint/node_modules/markdownlint/doc/md038.md +0 -52
  49. package/packages/config-markdownlint/node_modules/markdownlint/doc/md039.md +0 -21
  50. package/packages/config-markdownlint/node_modules/markdownlint/doc/md040.md +0 -52
  51. package/packages/config-markdownlint/node_modules/markdownlint/doc/md041.md +0 -64
  52. package/packages/config-markdownlint/node_modules/markdownlint/doc/md042.md +0 -38
  53. package/packages/config-markdownlint/node_modules/markdownlint/doc/md043.md +0 -87
  54. package/packages/config-markdownlint/node_modules/markdownlint/doc/md044.md +0 -45
  55. package/packages/config-markdownlint/node_modules/markdownlint/doc/md045.md +0 -48
  56. package/packages/config-markdownlint/node_modules/markdownlint/doc/md046.md +0 -40
  57. package/packages/config-markdownlint/node_modules/markdownlint/doc/md047.md +0 -34
  58. package/packages/config-markdownlint/node_modules/markdownlint/doc/md048.md +0 -42
  59. package/packages/config-markdownlint/node_modules/markdownlint/doc/md049.md +0 -36
  60. package/packages/config-markdownlint/node_modules/markdownlint/doc/md050.md +0 -35
  61. package/packages/config-markdownlint/node_modules/markdownlint/doc/md051.md +0 -117
  62. package/packages/config-markdownlint/node_modules/markdownlint/doc/md052.md +0 -52
  63. package/packages/config-markdownlint/node_modules/markdownlint/doc/md053.md +0 -38
  64. package/packages/config-markdownlint/node_modules/markdownlint/doc/md054.md +0 -100
  65. package/packages/config-markdownlint/node_modules/markdownlint/doc/md055.md +0 -55
  66. package/packages/config-markdownlint/node_modules/markdownlint/doc/md056.md +0 -37
  67. package/packages/config-markdownlint/node_modules/markdownlint/doc/md058.md +0 -48
  68. package/packages/config-markdownlint/node_modules/markdownlint/doc/md059.md +0 -33
  69. package/packages/config-markdownlint/node_modules/markdownlint/doc/md060.md +0 -130
  70. package/packages/config-markdownlint/node_modules/markdownlint/helpers/LICENSE +0 -21
  71. package/packages/config-markdownlint/node_modules/markdownlint/helpers/README.md +0 -29
  72. package/packages/config-markdownlint/node_modules/markdownlint/helpers/helpers.cjs +0 -695
  73. package/packages/config-markdownlint/node_modules/markdownlint/helpers/micromark-helpers.cjs +0 -332
  74. package/packages/config-markdownlint/node_modules/markdownlint/helpers/package.json +0 -26
  75. package/packages/config-markdownlint/node_modules/markdownlint/helpers/shared.cjs +0 -16
  76. package/packages/config-markdownlint/node_modules/markdownlint/lib/cache.mjs +0 -80
  77. package/packages/config-markdownlint/node_modules/markdownlint/lib/configuration-strict.d.ts +0 -2417
  78. package/packages/config-markdownlint/node_modules/markdownlint/lib/configuration.d.ts +0 -8
  79. package/packages/config-markdownlint/node_modules/markdownlint/lib/constants.mjs +0 -14
  80. package/packages/config-markdownlint/node_modules/markdownlint/lib/defer-require.cjs +0 -18
  81. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-async.d.mts +0 -1
  82. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-async.mjs +0 -3
  83. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-promise.d.mts +0 -1
  84. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-promise.mjs +0 -3
  85. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-sync.d.mts +0 -1
  86. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports-sync.mjs +0 -3
  87. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports.d.mts +0 -30
  88. package/packages/config-markdownlint/node_modules/markdownlint/lib/exports.mjs +0 -33
  89. package/packages/config-markdownlint/node_modules/markdownlint/lib/markdownit.cjs +0 -171
  90. package/packages/config-markdownlint/node_modules/markdownlint/lib/markdownlint.d.mts +0 -615
  91. package/packages/config-markdownlint/node_modules/markdownlint/lib/markdownlint.mjs +0 -1592
  92. package/packages/config-markdownlint/node_modules/markdownlint/lib/md001.mjs +0 -32
  93. package/packages/config-markdownlint/node_modules/markdownlint/lib/md003.mjs +0 -47
  94. package/packages/config-markdownlint/node_modules/markdownlint/lib/md004.mjs +0 -72
  95. package/packages/config-markdownlint/node_modules/markdownlint/lib/md005.mjs +0 -69
  96. package/packages/config-markdownlint/node_modules/markdownlint/lib/md007.mjs +0 -84
  97. package/packages/config-markdownlint/node_modules/markdownlint/lib/md009.mjs +0 -96
  98. package/packages/config-markdownlint/node_modules/markdownlint/lib/md010.mjs +0 -78
  99. package/packages/config-markdownlint/node_modules/markdownlint/lib/md011.mjs +0 -56
  100. package/packages/config-markdownlint/node_modules/markdownlint/lib/md012.mjs +0 -40
  101. package/packages/config-markdownlint/node_modules/markdownlint/lib/md013.mjs +0 -91
  102. package/packages/config-markdownlint/node_modules/markdownlint/lib/md014.mjs +0 -47
  103. package/packages/config-markdownlint/node_modules/markdownlint/lib/md018.mjs +0 -43
  104. package/packages/config-markdownlint/node_modules/markdownlint/lib/md019-md021.mjs +0 -77
  105. package/packages/config-markdownlint/node_modules/markdownlint/lib/md020.mjs +0 -68
  106. package/packages/config-markdownlint/node_modules/markdownlint/lib/md022.mjs +0 -103
  107. package/packages/config-markdownlint/node_modules/markdownlint/lib/md023.mjs +0 -37
  108. package/packages/config-markdownlint/node_modules/markdownlint/lib/md024.mjs +0 -45
  109. package/packages/config-markdownlint/node_modules/markdownlint/lib/md025.mjs +0 -45
  110. package/packages/config-markdownlint/node_modules/markdownlint/lib/md026.mjs +0 -46
  111. package/packages/config-markdownlint/node_modules/markdownlint/lib/md027.mjs +0 -50
  112. package/packages/config-markdownlint/node_modules/markdownlint/lib/md028.mjs +0 -39
  113. package/packages/config-markdownlint/node_modules/markdownlint/lib/md029.mjs +0 -84
  114. package/packages/config-markdownlint/node_modules/markdownlint/lib/md030.mjs +0 -57
  115. package/packages/config-markdownlint/node_modules/markdownlint/lib/md031.mjs +0 -61
  116. package/packages/config-markdownlint/node_modules/markdownlint/lib/md032.mjs +0 -78
  117. package/packages/config-markdownlint/node_modules/markdownlint/lib/md033.mjs +0 -46
  118. package/packages/config-markdownlint/node_modules/markdownlint/lib/md034.mjs +0 -92
  119. package/packages/config-markdownlint/node_modules/markdownlint/lib/md035.mjs +0 -23
  120. package/packages/config-markdownlint/node_modules/markdownlint/lib/md036.mjs +0 -55
  121. package/packages/config-markdownlint/node_modules/markdownlint/lib/md037.mjs +0 -94
  122. package/packages/config-markdownlint/node_modules/markdownlint/lib/md038.mjs +0 -73
  123. package/packages/config-markdownlint/node_modules/markdownlint/lib/md039.mjs +0 -59
  124. package/packages/config-markdownlint/node_modules/markdownlint/lib/md040.mjs +0 -32
  125. package/packages/config-markdownlint/node_modules/markdownlint/lib/md041.mjs +0 -71
  126. package/packages/config-markdownlint/node_modules/markdownlint/lib/md042.mjs +0 -58
  127. package/packages/config-markdownlint/node_modules/markdownlint/lib/md043.mjs +0 -72
  128. package/packages/config-markdownlint/node_modules/markdownlint/lib/md044.mjs +0 -110
  129. package/packages/config-markdownlint/node_modules/markdownlint/lib/md045.mjs +0 -61
  130. package/packages/config-markdownlint/node_modules/markdownlint/lib/md046.mjs +0 -31
  131. package/packages/config-markdownlint/node_modules/markdownlint/lib/md047.mjs +0 -28
  132. package/packages/config-markdownlint/node_modules/markdownlint/lib/md048.mjs +0 -47
  133. package/packages/config-markdownlint/node_modules/markdownlint/lib/md049-md050.mjs +0 -115
  134. package/packages/config-markdownlint/node_modules/markdownlint/lib/md051.mjs +0 -173
  135. package/packages/config-markdownlint/node_modules/markdownlint/lib/md052.mjs +0 -40
  136. package/packages/config-markdownlint/node_modules/markdownlint/lib/md053.mjs +0 -60
  137. package/packages/config-markdownlint/node_modules/markdownlint/lib/md054.mjs +0 -122
  138. package/packages/config-markdownlint/node_modules/markdownlint/lib/md055.mjs +0 -72
  139. package/packages/config-markdownlint/node_modules/markdownlint/lib/md056.mjs +0 -50
  140. package/packages/config-markdownlint/node_modules/markdownlint/lib/md058.mjs +0 -57
  141. package/packages/config-markdownlint/node_modules/markdownlint/lib/md059.mjs +0 -71
  142. package/packages/config-markdownlint/node_modules/markdownlint/lib/md060.mjs +0 -209
  143. package/packages/config-markdownlint/node_modules/markdownlint/lib/micromark-parse.mjs +0 -337
  144. package/packages/config-markdownlint/node_modules/markdownlint/lib/micromark-types.d.mts +0 -11
  145. package/packages/config-markdownlint/node_modules/markdownlint/lib/node-imports-browser.mjs +0 -22
  146. package/packages/config-markdownlint/node_modules/markdownlint/lib/node-imports-node.mjs +0 -11
  147. package/packages/config-markdownlint/node_modules/markdownlint/lib/parse-configuration.mjs +0 -47
  148. package/packages/config-markdownlint/node_modules/markdownlint/lib/resolve-module.cjs +0 -52
  149. package/packages/config-markdownlint/node_modules/markdownlint/lib/resolve-module.d.cts +0 -34
  150. package/packages/config-markdownlint/node_modules/markdownlint/lib/rules.mjs +0 -122
  151. package/packages/config-markdownlint/node_modules/markdownlint/lib/types.d.mts +0 -13
  152. package/packages/config-markdownlint/node_modules/markdownlint/package.json +0 -120
  153. package/packages/config-markdownlint/node_modules/markdownlint/schema/.markdownlint.jsonc +0 -349
  154. package/packages/config-markdownlint/node_modules/markdownlint/schema/.markdownlint.yaml +0 -310
  155. package/packages/config-markdownlint/node_modules/markdownlint/schema/ValidatingConfiguration.md +0 -26
  156. package/packages/config-markdownlint/node_modules/markdownlint/schema/markdownlint-config-schema-strict.json +0 -5138
  157. package/packages/config-markdownlint/node_modules/markdownlint/schema/markdownlint-config-schema.json +0 -5143
  158. package/packages/config-markdownlint/node_modules/markdownlint/style/all.json +0 -5
  159. package/packages/config-markdownlint/node_modules/markdownlint/style/cirosantilli.json +0 -22
  160. package/packages/config-markdownlint/node_modules/markdownlint/style/prettier.json +0 -27
  161. package/packages/config-markdownlint/node_modules/markdownlint/style/relaxed.json +0 -12
  162. package/packages/config-markdownlint/node_modules/string-width/index.d.ts +0 -39
  163. package/packages/config-markdownlint/node_modules/string-width/index.js +0 -203
  164. package/packages/config-markdownlint/node_modules/string-width/license +0 -9
  165. package/packages/config-markdownlint/node_modules/string-width/package.json +0 -65
  166. package/packages/config-markdownlint/node_modules/string-width/readme.md +0 -66
  167. package/packages/config-markdownlint/node_modules/strip-ansi/index.d.ts +0 -15
  168. package/packages/config-markdownlint/node_modules/strip-ansi/index.js +0 -19
  169. package/packages/config-markdownlint/node_modules/strip-ansi/license +0 -9
  170. package/packages/config-markdownlint/node_modules/strip-ansi/package.json +0 -59
  171. package/packages/config-markdownlint/node_modules/strip-ansi/readme.md +0 -37
@@ -1,1592 +0,0 @@
1
- // @ts-check
2
-
3
- // @ts-ignore
4
- import { fs as nodeFs, os, path } from "#node-imports";
5
- import { initialize as cacheInitialize } from "./cache.mjs";
6
- import { version } from "./constants.mjs";
7
- import { requireMarkdownItCjs } from "./defer-require.cjs";
8
- import { resolveModule } from "./resolve-module.cjs";
9
- import rules from "./rules.mjs";
10
- import { parse as micromarkParse } from "./micromark-parse.mjs";
11
- import parseConfiguration from "./parse-configuration.mjs";
12
- import * as helpers from "../helpers/helpers.cjs";
13
-
14
- /**
15
- * Validate the list of rules for structure and reuse.
16
- *
17
- * @param {Rule[]} ruleList List of rules.
18
- * @param {boolean} synchronous Whether to execute synchronously.
19
- * @returns {Error | null} Error message if validation fails.
20
- */
21
- function validateRuleList(ruleList, synchronous) {
22
- let result = null;
23
- if (ruleList.length === rules.length) {
24
- // No need to validate if only using built-in rules
25
- return result;
26
- }
27
- /** @type {Object.<string, boolean>} */
28
- const allIds = {};
29
- for (const [ index, rule ] of ruleList.entries()) {
30
- const customIndex = index - rules.length;
31
- // eslint-disable-next-line jsdoc/reject-any-type, jsdoc/require-jsdoc
32
- function newError(/** @type {string} */ property, /** @type {any} */ value) {
33
- return new Error(
34
- `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`);
35
- }
36
- for (const property of [ "names", "tags" ]) {
37
- // @ts-ignore
38
- const value = rule[property];
39
- if (!result &&
40
- (!value || !Array.isArray(value) || (value.length === 0) ||
41
- !value.every(helpers.isString) || value.some(helpers.isEmptyString))) {
42
- result = newError(property, value);
43
- }
44
- }
45
- for (const propertyInfo of [
46
- [ "description", "string" ],
47
- [ "function", "function" ]
48
- ]) {
49
- const property = propertyInfo[0];
50
- // @ts-ignore
51
- const value = rule[property];
52
- if (!result && (!value || (typeof value !== propertyInfo[1]))) {
53
- result = newError(property, value);
54
- }
55
- }
56
- if (
57
- !result &&
58
- (rule.parser !== undefined) &&
59
- (rule.parser !== "markdownit") &&
60
- (rule.parser !== "micromark") &&
61
- (rule.parser !== "none")
62
- ) {
63
- result = newError("parser", rule.parser);
64
- }
65
- if (
66
- !result &&
67
- rule.information &&
68
- !helpers.isUrl(rule.information)
69
- ) {
70
- result = newError("information", rule.information);
71
- }
72
- if (
73
- !result &&
74
- (rule.asynchronous !== undefined) &&
75
- (typeof rule.asynchronous !== "boolean")
76
- ) {
77
- result = newError("asynchronous", rule.asynchronous);
78
- }
79
- if (!result && rule.asynchronous && synchronous) {
80
- result = new Error(
81
- "Custom rule " + rule.names.join("/") + " at index " + customIndex +
82
- " is asynchronous and can not be used in a synchronous context."
83
- );
84
- }
85
- if (!result) {
86
- for (const name of rule.names) {
87
- const nameUpper = name.toUpperCase();
88
- if (!result && (allIds[nameUpper] !== undefined)) {
89
- result = new Error("Name '" + name + "' of custom rule at index " +
90
- customIndex + " is already used as a name or tag.");
91
- }
92
- allIds[nameUpper] = true;
93
- }
94
- for (const tag of rule.tags) {
95
- const tagUpper = tag.toUpperCase();
96
- if (!result && allIds[tagUpper]) {
97
- result = new Error("Tag '" + tag + "' of custom rule at index " +
98
- customIndex + " is already used as a name.");
99
- }
100
- allIds[tagUpper] = false;
101
- }
102
- }
103
- }
104
- return result;
105
- }
106
-
107
- /**
108
- * Result object for removeFrontMatter.
109
- *
110
- * @typedef {Object} RemoveFrontMatterResult
111
- * @property {string} content Markdown content.
112
- * @property {string[]} frontMatterLines Front matter lines.
113
- */
114
-
115
- /**
116
- * Remove front matter (if present at beginning of content).
117
- *
118
- * @param {string} content Markdown content.
119
- * @param {RegExp | null} frontMatter Regular expression to match front matter.
120
- * @returns {RemoveFrontMatterResult} Trimmed content and front matter lines.
121
- */
122
- function removeFrontMatter(content, frontMatter) {
123
- /** @type {string[]} */
124
- let frontMatterLines = [];
125
- if (frontMatter) {
126
- const frontMatterMatch = content.match(frontMatter);
127
- if (frontMatterMatch && !frontMatterMatch.index) {
128
- const contentMatched = frontMatterMatch[0];
129
- content = content.slice(contentMatched.length);
130
- frontMatterLines = contentMatched.split(helpers.newLineRe);
131
- if ((frontMatterLines.length > 0) &&
132
- (frontMatterLines[frontMatterLines.length - 1] === "")) {
133
- frontMatterLines.length--;
134
- }
135
- }
136
- }
137
- return {
138
- "content": content,
139
- "frontMatterLines": frontMatterLines
140
- };
141
- }
142
-
143
- /**
144
- * Map rule names/tags to canonical rule name.
145
- *
146
- * @param {Rule[]} ruleList List of rules.
147
- * @returns {Object.<string, string[]>} Map of alias to rule name.
148
- */
149
- function mapAliasToRuleNames(ruleList) {
150
- /** @type {Object.<string, string[]>} */
151
- const aliasToRuleNames = {};
152
- // const tagToRuleNames = {};
153
- for (const rule of ruleList) {
154
- const ruleName = rule.names[0].toUpperCase();
155
- // The following is useful for updating README.md:
156
- // console.log(
157
- // "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
158
- // ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description);
159
- for (const name of rule.names) {
160
- const nameUpper = name.toUpperCase();
161
- aliasToRuleNames[nameUpper] = [ ruleName ];
162
- }
163
- for (const tag of rule.tags) {
164
- const tagUpper = tag.toUpperCase();
165
- const ruleNames = aliasToRuleNames[tagUpper] || [];
166
- ruleNames.push(ruleName);
167
- aliasToRuleNames[tagUpper] = ruleNames;
168
- // tagToRuleNames[tag] = ruleName;
169
- }
170
- }
171
- // The following is useful for updating README.md:
172
- // Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
173
- // console.log("* **" + tag + "** - " +
174
- // aliasToRuleNames[tag.toUpperCase()].join(", "));
175
- // });
176
- // @ts-ignore
177
- return aliasToRuleNames;
178
- }
179
-
180
- /**
181
- * Result object for getEffectiveConfig.
182
- *
183
- * @typedef {Object} GetEffectiveConfigResult
184
- * @property {Configuration} effectiveConfig Effective configuration.
185
- * @property {Map<string, boolean>} rulesEnabled Rules enabled.
186
- * @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
187
- */
188
-
189
- /**
190
- * Apply (and normalize) configuration object.
191
- *
192
- * @param {Rule[]} ruleList List of rules.
193
- * @param {Configuration} config Configuration object.
194
- * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
195
- * @returns {GetEffectiveConfigResult} Effective configuration and rule severities.
196
- */
197
- function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
198
- let ruleDefaultEnable = true;
199
- /** @type {"error" | "warning"} */
200
- let ruleDefaultSeverity = "error";
201
- // eslint-disable-next-line unicorn/no-unused-array-method-return
202
- Object.entries(config).every(([ key, value ]) => {
203
- if (key.toUpperCase() === "DEFAULT") {
204
- ruleDefaultEnable = !!value;
205
- if (value === "warning") {
206
- ruleDefaultSeverity = "warning";
207
- }
208
- return false;
209
- }
210
- return true;
211
- });
212
- /** @type {Configuration} */
213
- const effectiveConfig = {};
214
- /** @type {Map<string, boolean>} */
215
- const rulesEnabled = new Map();
216
- /** @type {Map<string, "error" | "warning">} */
217
- const rulesSeverity = new Map();
218
- const emptyObject = Object.freeze({});
219
- for (const ruleName of ruleList.map((rule) => rule.names[0].toUpperCase())) {
220
- effectiveConfig[ruleName] = emptyObject;
221
- rulesEnabled.set(ruleName, ruleDefaultEnable);
222
- rulesSeverity.set(ruleName, ruleDefaultSeverity);
223
- }
224
- // for (const ruleName of deprecatedRuleNames) {
225
- // effectiveConfig[ruleName] = false;
226
- // }
227
- for (const [ key, value ] of Object.entries(config)) {
228
- const keyUpper = key.toUpperCase();
229
- /** @type {boolean} */
230
- let enabled = false;
231
- /** @type {"error" | "warning"} */
232
- let severity = "error";
233
- let effectiveValue = {};
234
- if (value) {
235
- if (value instanceof Object) {
236
- /** @type {{ enabled?: boolean, severity?: "error" | "warning" }} */
237
- const valueObject = value;
238
- enabled = (valueObject.enabled === undefined) ? true : !!valueObject.enabled;
239
- severity = (valueObject.severity === "warning") ? "warning" : "error";
240
- effectiveValue = Object.fromEntries(
241
- Object.entries(value).filter(
242
- ([ k ]) => (k !== "enabled") && (k !== "severity")
243
- )
244
- );
245
- } else {
246
- enabled = true;
247
- severity = (value === "warning") ? "warning" : "error";
248
- }
249
- }
250
- for (const ruleName of (aliasToRuleNames[keyUpper] || [])) {
251
- Object.freeze(effectiveValue);
252
- effectiveConfig[ruleName] = effectiveValue;
253
- rulesEnabled.set(ruleName, enabled);
254
- rulesSeverity.set(ruleName, severity);
255
- }
256
- }
257
- return {
258
- effectiveConfig,
259
- rulesEnabled,
260
- rulesSeverity
261
- };
262
- }
263
-
264
- /**
265
- * Result object for getEnabledRulesPerLineNumber.
266
- *
267
- * @typedef {Object} EnabledRulesPerLineNumberResult
268
- * @property {Configuration} effectiveConfig Effective configuration.
269
- * @property {Map<string, boolean>[]} enabledRulesPerLineNumber Enabled rules per line number.
270
- * @property {Rule[]} enabledRuleList Enabled rule list.
271
- * @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
272
- */
273
-
274
- /**
275
- * Create a mapping of enabled rules per line.
276
- *
277
- * @param {Rule[]} ruleList List of rules.
278
- * @param {string[]} lines List of content lines.
279
- * @param {string[]} frontMatterLines List of front matter lines.
280
- * @param {boolean} noInlineConfig Whether to allow inline configuration.
281
- * @param {Configuration} config Configuration object.
282
- * @param {ConfigurationParser[] | undefined} configParsers Configuration parsers.
283
- * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
284
- * @returns {EnabledRulesPerLineNumberResult} Effective configuration and enabled rules per line number.
285
- */
286
- function getEnabledRulesPerLineNumber(
287
- ruleList,
288
- lines,
289
- frontMatterLines,
290
- noInlineConfig,
291
- config,
292
- configParsers,
293
- aliasToRuleNames) {
294
- // Shared variables
295
- /** @type {Map<string, boolean>} */
296
- let enabledRules = new Map();
297
- /** @type {Map<string, boolean>} */
298
- let capturedRules = enabledRules;
299
- const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);
300
- // Helper functions
301
- // eslint-disable-next-line jsdoc/require-jsdoc
302
- function handleInlineConfig(/** @type {string[]} */ input, /** @type {(act: string, par: string, ind: number) => void} */ forEachMatch, /** @type {(() => void)|undefined} */ forEachLine = undefined) {
303
- for (const [ lineIndex, line ] of input.entries()) {
304
- if (!noInlineConfig) {
305
- let match = null;
306
- while ((match = helpers.inlineCommentStartRe.exec(line))) {
307
- const action = match[2].toUpperCase();
308
- const startIndex = match.index + match[1].length;
309
- const endIndex = line.indexOf("-->", startIndex);
310
- if (endIndex === -1) {
311
- break;
312
- }
313
- const parameter = line.slice(startIndex, endIndex);
314
- forEachMatch(action, parameter, lineIndex + 1);
315
- }
316
- }
317
- if (forEachLine) {
318
- forEachLine();
319
- }
320
- }
321
- }
322
- // eslint-disable-next-line jsdoc/require-jsdoc
323
- function configureFile(/** @type {string} */ action, /** @type {string} */ parameter) {
324
- if (action === "CONFIGURE-FILE") {
325
- const { "config": parsed } = parseConfiguration(
326
- "CONFIGURE-FILE", parameter, configParsers
327
- );
328
- if (parsed) {
329
- config = {
330
- ...config,
331
- ...parsed
332
- };
333
- }
334
- }
335
- }
336
- // eslint-disable-next-line jsdoc/require-jsdoc
337
- function applyEnableDisable(/** @type {string} */ action, /** @type {string} */ parameter, /** @type {Map<string, boolean>} */ state) {
338
- state = new Map(state);
339
- const enabled = (action.startsWith("ENABLE"));
340
- const trimmed = parameter && parameter.trim();
341
- // eslint-disable-next-line no-use-before-define
342
- const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames;
343
- for (const nameUpper of items) {
344
- for (const ruleName of (aliasToRuleNames[nameUpper] || [])) {
345
- state.set(ruleName, enabled);
346
- }
347
- }
348
- return state;
349
- }
350
- // eslint-disable-next-line jsdoc/require-jsdoc
351
- function enableDisableFile(/** @type {string} */ action, /** @type {string} */ parameter) {
352
- if ((action === "ENABLE-FILE") || (action === "DISABLE-FILE")) {
353
- enabledRules = applyEnableDisable(action, parameter, enabledRules);
354
- }
355
- }
356
- // eslint-disable-next-line jsdoc/require-jsdoc
357
- function captureRestoreEnableDisable(/** @type {string} */ action, /** @type {string} */ parameter) {
358
- if (action === "CAPTURE") {
359
- capturedRules = enabledRules;
360
- } else if (action === "RESTORE") {
361
- enabledRules = capturedRules;
362
- } else if ((action === "ENABLE") || (action === "DISABLE")) {
363
- enabledRules = applyEnableDisable(action, parameter, enabledRules);
364
- }
365
- }
366
- // eslint-disable-next-line jsdoc/require-jsdoc
367
- function updateLineState() {
368
- enabledRulesPerLineNumber.push(enabledRules);
369
- }
370
- // eslint-disable-next-line jsdoc/require-jsdoc
371
- function disableLineNextLine(/** @type {string} */ action, /** @type {string} */ parameter, /** @type {number} */ lineNumber) {
372
- const disableLine = (action === "DISABLE-LINE");
373
- const disableNextLine = (action === "DISABLE-NEXT-LINE");
374
- if (disableLine || disableNextLine) {
375
- const nextLineNumber =
376
- frontMatterLines.length + lineNumber + (disableNextLine ? 1 : 0);
377
- enabledRulesPerLineNumber[nextLineNumber] =
378
- applyEnableDisable(
379
- action,
380
- parameter,
381
- enabledRulesPerLineNumber[nextLineNumber]
382
- );
383
- }
384
- }
385
- // Handle inline comments
386
- handleInlineConfig([ lines.join("\n") ], configureFile);
387
- const { effectiveConfig, rulesEnabled, rulesSeverity } = getEffectiveConfig(ruleList, config, aliasToRuleNames);
388
- const allRuleNames = [ ...rulesEnabled.keys() ];
389
- enabledRules = new Map(rulesEnabled);
390
- capturedRules = enabledRules;
391
- handleInlineConfig(lines, enableDisableFile);
392
- handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState);
393
- handleInlineConfig(lines, disableLineNextLine);
394
- // Create the list of rules that are used at least once
395
- const enabledRuleList = ruleList.filter((rule) => {
396
- const ruleName = rule.names[0].toUpperCase();
397
- return enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine.get(ruleName));
398
- });
399
- // Return results
400
- return {
401
- effectiveConfig,
402
- enabledRulesPerLineNumber,
403
- enabledRuleList,
404
- rulesSeverity
405
- };
406
- }
407
-
408
- /**
409
- * Lints a string containing Markdown content.
410
- *
411
- * @param {Rule[]} ruleList List of rules.
412
- * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
413
- * @param {string} name Identifier for the content.
414
- * @param {string} content Markdown content.
415
- * @param {MarkdownItFactory} markdownItFactory Function to create a markdown-it parser.
416
- * @param {Configuration} config Configuration object.
417
- * @param {ConfigurationParser[] | undefined} configParsers Configuration parsers.
418
- * @param {RegExp | null} frontMatter Regular expression for front matter.
419
- * @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
420
- * @param {boolean} noInlineConfig Whether to allow inline configuration.
421
- * @param {boolean} synchronous Whether to execute synchronously.
422
- * @param {LintContentCallback} callback Callback (err, result) function.
423
- * @returns {void}
424
- */
425
- function lintContent(
426
- ruleList,
427
- aliasToRuleNames,
428
- name,
429
- content,
430
- markdownItFactory,
431
- config,
432
- configParsers,
433
- frontMatter,
434
- handleRuleFailures,
435
- noInlineConfig,
436
- synchronous,
437
- callback) {
438
- // Provide a consistent error-reporting callback
439
- // eslint-disable-next-line jsdoc/reject-any-type
440
- const callbackError = (/** @type {any} */ error) => callback(error instanceof Error ? error : new Error(error));
441
- // Remove UTF-8 byte order marker (if present)
442
- content = content.replace(/^\uFEFF/, "");
443
- // Remove front matter
444
- const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
445
- const { frontMatterLines } = removeFrontMatterResult;
446
- content = removeFrontMatterResult.content;
447
- // Get enabled rules per line (with HTML comments present)
448
- const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList, rulesSeverity } =
449
- getEnabledRulesPerLineNumber(
450
- ruleList,
451
- content.split(helpers.newLineRe),
452
- frontMatterLines,
453
- noInlineConfig,
454
- config,
455
- configParsers,
456
- aliasToRuleNames
457
- );
458
- const needMarkdownItTokens = enabledRuleList.some(
459
- (rule) => (rule.parser === "markdownit") || (rule.parser === undefined)
460
- );
461
- const needMicromarkTokens = enabledRuleList.some(
462
- (rule) => (rule.parser === "micromark")
463
- );
464
- const customRulesPresent = (ruleList.length !== rules.length);
465
- // Parse content into parser tokens
466
- const micromarkTokens = needMicromarkTokens ?
467
- micromarkParse(content, { "freezeTokens": customRulesPresent }) :
468
- [];
469
- // Hide the content of HTML comments from rules
470
- const preClearedContent = content;
471
- content = helpers.clearHtmlCommentText(content);
472
- // Parse content into lines and get markdown-it tokens
473
- const lines = content.split(helpers.newLineRe);
474
- // Function to run after fetching markdown-it tokens (when needed)
475
- const lintContentInternal = (/** @type {MarkdownItToken[]} */ markdownitTokens) => {
476
- // Create (frozen) parameters for rules
477
- /** @type {MarkdownParsers} */
478
- // @ts-ignore
479
- const parsersMarkdownIt = Object.freeze({
480
- "markdownit": Object.freeze({
481
- "tokens": markdownitTokens
482
- })
483
- });
484
- /** @type {MarkdownParsers} */
485
- // @ts-ignore
486
- const parsersMicromark = Object.freeze({
487
- "micromark": Object.freeze({
488
- "tokens": micromarkTokens
489
- })
490
- });
491
- /** @type {MarkdownParsers} */
492
- // @ts-ignore
493
- const parsersNone = Object.freeze({});
494
- const paramsBase = {
495
- name,
496
- version,
497
- "lines": Object.freeze(lines),
498
- "frontMatterLines": Object.freeze(frontMatterLines)
499
- };
500
- cacheInitialize({
501
- ...paramsBase,
502
- "parsers": parsersMicromark,
503
- "config": {}
504
- });
505
- // Function to run for each rule
506
- /** @type {LintError[]} */
507
- const results = [];
508
- /**
509
- * @param {Rule} rule Rule.
510
- * @returns {Promise<void> | null} Promise.
511
- */
512
- const forRule = (rule) => {
513
- // Configure rule
514
- const ruleName = rule.names[0].toUpperCase();
515
- const tokens = {};
516
- let parsers = parsersNone;
517
- if (rule.parser === undefined) {
518
- tokens.tokens = markdownitTokens;
519
- parsers = parsersMarkdownIt;
520
- } else if (rule.parser === "markdownit") {
521
- parsers = parsersMarkdownIt;
522
- } else if (rule.parser === "micromark") {
523
- parsers = parsersMicromark;
524
- }
525
- const params = Object.freeze({
526
- ...paramsBase,
527
- ...tokens,
528
- parsers,
529
- /** @type {RuleConfiguration} */
530
- // @ts-ignore
531
- "config": effectiveConfig[ruleName]
532
- });
533
- // eslint-disable-next-line jsdoc/require-jsdoc
534
- function throwError(/** @type {string} */ property) {
535
- throw new Error(
536
- `Value of '${property}' passed to onError by '${ruleName}' is incorrect for '${name}'.`);
537
- }
538
- // eslint-disable-next-line jsdoc/require-jsdoc
539
- function onError(/** @type {RuleOnErrorInfo} */ errorInfo) {
540
- if (!errorInfo ||
541
- !helpers.isNumber(errorInfo.lineNumber) ||
542
- (errorInfo.lineNumber < 1) ||
543
- (errorInfo.lineNumber > lines.length)) {
544
- throwError("lineNumber");
545
- }
546
- const lineNumber = errorInfo.lineNumber + frontMatterLines.length;
547
- if (!enabledRulesPerLineNumber[lineNumber].get(ruleName)) {
548
- return;
549
- }
550
- if (errorInfo.detail &&
551
- !helpers.isString(errorInfo.detail)) {
552
- throwError("detail");
553
- }
554
- if (errorInfo.context &&
555
- !helpers.isString(errorInfo.context)) {
556
- throwError("context");
557
- }
558
- if (errorInfo.information &&
559
- !helpers.isUrl(errorInfo.information)) {
560
- throwError("information");
561
- }
562
- if (errorInfo.range &&
563
- (!Array.isArray(errorInfo.range) ||
564
- (errorInfo.range.length !== 2) ||
565
- !helpers.isNumber(errorInfo.range[0]) ||
566
- (errorInfo.range[0] < 1) ||
567
- !helpers.isNumber(errorInfo.range[1]) ||
568
- (errorInfo.range[1] < 1) ||
569
- ((errorInfo.range[0] + errorInfo.range[1] - 1) >
570
- lines[errorInfo.lineNumber - 1].length))) {
571
- throwError("range");
572
- }
573
- const fixInfo = errorInfo.fixInfo;
574
- const cleanFixInfo = {};
575
- if (fixInfo) {
576
- if (!helpers.isObject(fixInfo)) {
577
- throwError("fixInfo");
578
- }
579
- if (fixInfo.lineNumber !== undefined) {
580
- if ((!helpers.isNumber(fixInfo.lineNumber) ||
581
- (fixInfo.lineNumber < 1) ||
582
- (fixInfo.lineNumber > lines.length))) {
583
- throwError("fixInfo.lineNumber");
584
- }
585
- cleanFixInfo.lineNumber =
586
- fixInfo.lineNumber + frontMatterLines.length;
587
- }
588
- const effectiveLineNumber = fixInfo.lineNumber || errorInfo.lineNumber;
589
- if (fixInfo.editColumn !== undefined) {
590
- if ((!helpers.isNumber(fixInfo.editColumn) ||
591
- (fixInfo.editColumn < 1) ||
592
- (fixInfo.editColumn >
593
- lines[effectiveLineNumber - 1].length + 1))) {
594
- throwError("fixInfo.editColumn");
595
- }
596
- cleanFixInfo.editColumn = fixInfo.editColumn;
597
- }
598
- if (fixInfo.deleteCount !== undefined) {
599
- if ((!helpers.isNumber(fixInfo.deleteCount) ||
600
- (fixInfo.deleteCount < -1) ||
601
- (fixInfo.deleteCount >
602
- lines[effectiveLineNumber - 1].length))) {
603
- throwError("fixInfo.deleteCount");
604
- }
605
- cleanFixInfo.deleteCount = fixInfo.deleteCount;
606
- }
607
- if (fixInfo.insertText !== undefined) {
608
- if (!helpers.isString(fixInfo.insertText)) {
609
- throwError("fixInfo.insertText");
610
- }
611
- cleanFixInfo.insertText = fixInfo.insertText;
612
- }
613
- }
614
- const information = errorInfo.information || rule.information;
615
- results.push({
616
- lineNumber,
617
- "ruleNames": rule.names,
618
- "ruleDescription": rule.description,
619
- "ruleInformation": information ? information.href : null,
620
- "errorDetail": errorInfo.detail?.replace(helpers.newLineRe, " ") || null,
621
- "errorContext": errorInfo.context?.replace(helpers.newLineRe, " ") || null,
622
- "errorRange": errorInfo.range ? [ ...errorInfo.range ] : null,
623
- "fixInfo": fixInfo ? cleanFixInfo : null,
624
- // @ts-ignore
625
- "severity": rulesSeverity.get(ruleName)
626
- });
627
- }
628
- // Call (possibly external) rule function to report errors
629
- // @ts-ignore
630
- const catchCallsOnError = (error) => onError({
631
- "lineNumber": 1,
632
- "detail": `This rule threw an exception: ${error.message || error}`
633
- });
634
- const invokeRuleFunction = () => rule.function(params, onError);
635
- if (rule.asynchronous) {
636
- // Asynchronous rule, ensure it returns a Promise
637
- const ruleFunctionPromise =
638
- Promise.resolve().then(invokeRuleFunction);
639
- return handleRuleFailures ?
640
- ruleFunctionPromise.catch(catchCallsOnError) :
641
- ruleFunctionPromise;
642
- }
643
- // Synchronous rule
644
- try {
645
- invokeRuleFunction();
646
- } catch(error) {
647
- if (handleRuleFailures) {
648
- catchCallsOnError(error);
649
- } else {
650
- throw error;
651
- }
652
- }
653
- return null;
654
- };
655
- const formatResults = () => {
656
- // Sort results by rule name by line number
657
- results.sort((a, b) => (
658
- a.ruleNames[0].localeCompare(b.ruleNames[0]) ||
659
- a.lineNumber - b.lineNumber
660
- ));
661
- return results;
662
- };
663
- // Run all rules
664
- const ruleListAsync = enabledRuleList.filter((rule) => rule.asynchronous);
665
- const ruleListSync = enabledRuleList.filter((rule) => !rule.asynchronous);
666
- const ruleListAsyncFirst = [
667
- ...ruleListAsync,
668
- ...ruleListSync
669
- ];
670
- const callbackSuccess = () => callback(null, formatResults());
671
- try {
672
- const ruleResults = ruleListAsyncFirst.map(forRule);
673
- if (ruleListAsync.length > 0) {
674
- Promise.all(ruleResults.slice(0, ruleListAsync.length))
675
- .then(callbackSuccess)
676
- .catch(callbackError);
677
- } else {
678
- callbackSuccess();
679
- }
680
- } catch(error) {
681
- callbackError(error);
682
- } finally {
683
- cacheInitialize();
684
- }
685
- };
686
- if (!needMarkdownItTokens || synchronous) {
687
- // Need/able to call into markdown-it and lintContentInternal synchronously
688
- const markdownItTokens = needMarkdownItTokens ?
689
- requireMarkdownItCjs().getMarkdownItTokens(markdownItFactory(), preClearedContent, lines) :
690
- [];
691
- lintContentInternal(markdownItTokens);
692
- } else {
693
- // Need to call into markdown-it and lintContentInternal asynchronously
694
- Promise.all([
695
- // eslint-disable-next-line no-inline-comments
696
- import(/* webpackMode: "eager" */ "./markdownit.cjs"),
697
- // eslint-disable-next-line no-promise-executor-return
698
- new Promise((resolve) => resolve(markdownItFactory()))
699
- ]).then(([ markdownitCjs, markdownIt ]) => {
700
- const markdownItTokens = markdownitCjs.getMarkdownItTokens(markdownIt, preClearedContent, lines);
701
- lintContentInternal(markdownItTokens);
702
- }).catch(callbackError);
703
- }
704
- }
705
-
706
- /**
707
- * Lints a file containing Markdown content.
708
- *
709
- * @param {Rule[]} ruleList List of rules.
710
- * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
711
- * @param {string} file Path of file to lint.
712
- * @param {MarkdownItFactory} markdownItFactory Function to create a markdown-it parser.
713
- * @param {Configuration} config Configuration object.
714
- * @param {ConfigurationParser[] | undefined} configParsers Configuration parsers.
715
- * @param {RegExp | null} frontMatter Regular expression for front matter.
716
- * @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
717
- * @param {boolean} noInlineConfig Whether to allow inline configuration.
718
- * @param {FsLike} fs File system implementation.
719
- * @param {boolean} synchronous Whether to execute synchronously.
720
- * @param {LintContentCallback} callback Callback (err, result) function.
721
- * @returns {void}
722
- */
723
- function lintFile(
724
- ruleList,
725
- aliasToRuleNames,
726
- file,
727
- markdownItFactory,
728
- config,
729
- configParsers,
730
- frontMatter,
731
- handleRuleFailures,
732
- noInlineConfig,
733
- fs,
734
- synchronous,
735
- callback) {
736
- // eslint-disable-next-line jsdoc/require-jsdoc
737
- function lintContentWrapper(/** @type {Error | null} */ err, /** @type {string} */ content) {
738
- if (err) {
739
- return callback(err);
740
- }
741
- return lintContent(
742
- ruleList,
743
- aliasToRuleNames,
744
- file,
745
- content,
746
- markdownItFactory,
747
- config,
748
- configParsers,
749
- frontMatter,
750
- handleRuleFailures,
751
- noInlineConfig,
752
- synchronous,
753
- callback
754
- );
755
- }
756
- // Make a/synchronous call to read file
757
- if (synchronous) {
758
- lintContentWrapper(null, fs.readFileSync(file, "utf8"));
759
- } else {
760
- fs.readFile(file, "utf8", lintContentWrapper);
761
- }
762
- }
763
-
764
- /**
765
- * Lint files and strings specified in the Options object.
766
- *
767
- * @param {Options | null} options Options object.
768
- * @param {boolean} synchronous Whether to execute synchronously.
769
- * @param {LintCallback} callback Callback (err, result) function.
770
- * @returns {void}
771
- */
772
- function lintInput(options, synchronous, callback) {
773
- // Normalize inputs
774
- options = options || {};
775
- callback = callback || function noop() {};
776
- /** @type {Rule[]} */
777
- // @ts-ignore
778
- const customRuleList =
779
- [ options.customRules || [] ]
780
- .flat()
781
- .map((rule) => ({
782
- "names": helpers.cloneIfArray(rule.names),
783
- "description": rule.description,
784
- "information": helpers.cloneIfUrl(rule.information),
785
- "tags": helpers.cloneIfArray(rule.tags),
786
- "parser": rule.parser,
787
- "asynchronous": rule.asynchronous,
788
- "function": rule.function
789
- }));
790
- // eslint-disable-next-line unicorn/prefer-spread
791
- const ruleList = rules.concat(customRuleList);
792
- const ruleErr = validateRuleList(ruleList, synchronous);
793
- if (ruleErr) {
794
- callback(ruleErr);
795
- return;
796
- }
797
- /** @type {string[]} */
798
- let files = [];
799
- if (Array.isArray(options.files)) {
800
- files = [ ...options.files ];
801
- } else if (options.files) {
802
- files = [ String(options.files) ];
803
- }
804
- const strings = options.strings || {};
805
- const stringsKeys = Object.keys(strings);
806
- const config = options.config || { "default": true };
807
- const configParsers = options.configParsers || undefined;
808
- const frontMatter = (options.frontMatter === undefined) ?
809
- helpers.frontMatterRe :
810
- options.frontMatter;
811
- const handleRuleFailures = !!options.handleRuleFailures;
812
- const noInlineConfig = !!options.noInlineConfig;
813
- const markdownItFactory =
814
- options.markdownItFactory ||
815
- (() => { throw new Error("The option 'markdownItFactory' was required (due to the option 'customRules' including a rule requiring the 'markdown-it' parser), but 'markdownItFactory' was not set."); });
816
- /** @type {FsLike} */
817
- // @ts-ignore
818
- const fs = options.fs || nodeFs;
819
- const aliasToRuleNames = mapAliasToRuleNames(ruleList);
820
- const results = {};
821
- let done = false;
822
- let concurrency = 0;
823
- // eslint-disable-next-line jsdoc/require-jsdoc
824
- function lintWorker() {
825
- /** @type {string | undefined} */
826
- let currentItem = undefined;
827
- // eslint-disable-next-line jsdoc/require-jsdoc
828
- function lintWorkerCallback(/** @type {Error | null} */ err, /** @type {LintError[] | undefined} */ result) {
829
- concurrency--;
830
- if (err) {
831
- done = true;
832
- return callback(err);
833
- }
834
- // @ts-ignore
835
- results[currentItem] = result;
836
- if (!synchronous) {
837
- lintWorker();
838
- }
839
- return null;
840
- }
841
- if (done) {
842
- // Abort for error or nothing left to do
843
- } else if ((currentItem = files.shift())) {
844
- // Lint next file
845
- concurrency++;
846
- lintFile(
847
- ruleList,
848
- aliasToRuleNames,
849
- currentItem,
850
- markdownItFactory,
851
- config,
852
- configParsers,
853
- frontMatter,
854
- handleRuleFailures,
855
- noInlineConfig,
856
- fs,
857
- synchronous,
858
- lintWorkerCallback
859
- );
860
- } else if ((currentItem = stringsKeys.shift())) {
861
- // Lint next string
862
- concurrency++;
863
- lintContent(
864
- ruleList,
865
- aliasToRuleNames,
866
- currentItem,
867
- strings[currentItem] || "",
868
- markdownItFactory,
869
- config,
870
- configParsers,
871
- frontMatter,
872
- handleRuleFailures,
873
- noInlineConfig,
874
- synchronous,
875
- lintWorkerCallback
876
- );
877
- } else if (concurrency === 0) {
878
- // Finished, sort keys for consistency
879
- done = true;
880
- const sortedEntries = Object.entries(results);
881
- sortedEntries.sort(([ a ], [ b ]) => a.localeCompare(b));
882
- const sortedResults = Object.fromEntries(sortedEntries);
883
- return callback(null, sortedResults);
884
- }
885
- return null;
886
- }
887
- if (synchronous) {
888
- while (!done) {
889
- lintWorker();
890
- }
891
- } else {
892
- // Testing on a Raspberry Pi 4 Model B with an artificial 5ms file access
893
- // delay suggests that a concurrency factor of 8 can eliminate the impact
894
- // of that delay (i.e., total time is the same as with no delay).
895
- lintWorker();
896
- lintWorker();
897
- lintWorker();
898
- lintWorker();
899
- lintWorker();
900
- lintWorker();
901
- lintWorker();
902
- lintWorker();
903
- }
904
- }
905
-
906
- /**
907
- * Lint specified Markdown files.
908
- *
909
- * @param {Options | null} options Configuration options.
910
- * @param {LintCallback} callback Callback (err, result) function.
911
- * @returns {void}
912
- */
913
- export function lintAsync(options, callback) {
914
- return lintInput(options, false, callback);
915
- }
916
-
917
- /**
918
- * Lint specified Markdown files.
919
- *
920
- * @param {Options | null} options Configuration options.
921
- * @returns {Promise<LintResults>} Results object.
922
- */
923
- export function lintPromise(options) {
924
- return new Promise((resolve, reject) => {
925
- lintAsync(options, (error, results) => {
926
- if (error || !results) {
927
- reject(error);
928
- } else {
929
- resolve(results);
930
- }
931
- });
932
- });
933
- }
934
-
935
- /**
936
- * Lint specified Markdown files.
937
- *
938
- * @param {Options | null} options Configuration options.
939
- * @returns {LintResults} Results object.
940
- */
941
- export function lintSync(options) {
942
- let results = null;
943
- lintInput(options, true, function callback(error, res) {
944
- if (error) {
945
- throw error;
946
- }
947
- results = res;
948
- });
949
- // @ts-ignore
950
- return results;
951
- }
952
-
953
- /**
954
- * Node fs instance (or compatible object).
955
- *
956
- * @typedef FsLike
957
- * @property {(path: string, callback: (err: Error) => void) => void} access access method.
958
- * @property {(path: string) => void} accessSync accessSync method.
959
- * @property {(path: string, encoding: string, callback: (err: Error, data: string) => void) => void} readFile readFile method.
960
- * @property {(path: string, encoding: string) => string} readFileSync readFileSync method.
961
- */
962
-
963
- /**
964
- * Resolve referenced "extends" path in a configuration file
965
- * using path.resolve() with require.resolve() as a fallback.
966
- *
967
- * @param {string} configFile Configuration file name.
968
- * @param {string} referenceId Referenced identifier to resolve.
969
- * @param {FsLike} fs File system implementation.
970
- * @param {ResolveConfigExtendsCallback} callback Callback (err, result) function.
971
- * @returns {void}
972
- */
973
- function resolveConfigExtends(configFile, referenceId, fs, callback) {
974
- const configFileDirname = path.dirname(configFile);
975
- const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
976
- fs.access(resolvedExtendsFile, (err) => {
977
- if (err) {
978
- // Not a file, try require.resolve
979
- try {
980
- return callback(
981
- null,
982
- resolveModule(referenceId, [ configFileDirname ])
983
- );
984
- } catch {
985
- // Unable to resolve, use resolvedExtendsFile
986
- }
987
- }
988
- return callback(null, resolvedExtendsFile);
989
- });
990
- }
991
-
992
- /**
993
- * Resolve referenced "extends" path in a configuration file
994
- * using path.resolve() with require.resolve() as a fallback.
995
- *
996
- * @param {string} configFile Configuration file name.
997
- * @param {string} referenceId Referenced identifier to resolve.
998
- * @param {FsLike} fs File system implementation.
999
- * @returns {string} Resolved path to file.
1000
- */
1001
- function resolveConfigExtendsSync(configFile, referenceId, fs) {
1002
- const configFileDirname = path.dirname(configFile);
1003
- const resolvedExtendsFile = path.resolve(configFileDirname, referenceId);
1004
- try {
1005
- fs.accessSync(resolvedExtendsFile);
1006
- return resolvedExtendsFile;
1007
- } catch {
1008
- // Not a file, try require.resolve
1009
- }
1010
- try {
1011
- return resolveModule(referenceId, [ configFileDirname ]);
1012
- } catch {
1013
- // Unable to resolve, return resolvedExtendsFile
1014
- }
1015
- return resolvedExtendsFile;
1016
- }
1017
-
1018
- /**
1019
- * Extend specified configuration object.
1020
- *
1021
- * @param {Configuration} config Configuration object.
1022
- * @param {string} file Configuration file name.
1023
- * @param {ConfigurationParser[] | undefined} parsers Parsing function(s).
1024
- * @param {FsLike} fs File system implementation.
1025
- * @param {ReadConfigCallback} callback Callback (err, result) function.
1026
- * @returns {void}
1027
- */
1028
- function extendConfig(config, file, parsers, fs, callback) {
1029
- const configExtends = config.extends;
1030
- if (configExtends) {
1031
- return resolveConfigExtends(
1032
- file,
1033
- helpers.expandTildePath(configExtends, os),
1034
- fs,
1035
- // eslint-disable-next-line no-use-before-define
1036
- (_, resolvedExtends) => readConfigAsync(
1037
- // @ts-ignore
1038
- resolvedExtends,
1039
- parsers,
1040
- fs,
1041
- (err, extendsConfig) => {
1042
- if (err) {
1043
- return callback(err);
1044
- }
1045
- const result = {
1046
- ...extendsConfig,
1047
- ...config
1048
- };
1049
- delete result.extends;
1050
- return callback(null, result);
1051
- }
1052
- )
1053
- );
1054
- }
1055
- return callback(null, config);
1056
- }
1057
-
1058
- /**
1059
- * Extend specified configuration object.
1060
- *
1061
- * @param {Configuration} config Configuration object.
1062
- * @param {string} file Configuration file name.
1063
- * @param {ConfigurationParser[] | undefined} parsers Parsing function(s).
1064
- * @param {FsLike} fs File system implementation.
1065
- * @returns {Promise<Configuration>} Configuration object.
1066
- */
1067
- export function extendConfigPromise(config, file, parsers, fs) {
1068
- return new Promise((resolve, reject) => {
1069
- extendConfig(config, file, parsers, fs, (error, results) => {
1070
- if (error || !results) {
1071
- reject(error);
1072
- } else {
1073
- resolve(results);
1074
- }
1075
- });
1076
- });
1077
- }
1078
-
1079
- /**
1080
- * Read specified configuration file.
1081
- *
1082
- * @param {string} file Configuration file name.
1083
- * @param {ConfigurationParser[] | ReadConfigCallback} [parsers] Parsing function(s).
1084
- * @param {FsLike | ReadConfigCallback} [fs] File system implementation.
1085
- * @param {ReadConfigCallback} [callback] Callback (err, result) function.
1086
- * @returns {void}
1087
- */
1088
- export function readConfigAsync(file, parsers, fs, callback) {
1089
- if (!callback) {
1090
- if (fs) {
1091
- // @ts-ignore
1092
- callback = fs;
1093
- // @ts-ignore
1094
- fs = null;
1095
- } else {
1096
- // @ts-ignore
1097
- callback = parsers;
1098
- // @ts-ignore
1099
- parsers = null;
1100
- }
1101
- }
1102
- /** @type {FsLike} */
1103
- // @ts-ignore
1104
- const fsLike = fs || nodeFs;
1105
- // Read file
1106
- file = helpers.expandTildePath(file, os);
1107
- fsLike.readFile(file, "utf8", (err, content) => {
1108
- if (err) {
1109
- // @ts-ignore
1110
- return callback(err);
1111
- }
1112
- // Try to parse file
1113
- // @ts-ignore
1114
- const { config, message } = parseConfiguration(file, content, parsers);
1115
- if (!config) {
1116
- // @ts-ignore
1117
- return callback(new Error(message));
1118
- }
1119
- // Extend configuration
1120
- // @ts-ignore
1121
- return extendConfig(config, file, parsers, fsLike, callback);
1122
- });
1123
- }
1124
-
1125
- /**
1126
- * Read specified configuration file.
1127
- *
1128
- * @param {string} file Configuration file name.
1129
- * @param {ConfigurationParser[]} [parsers] Parsing function(s).
1130
- * @param {FsLike} [fs] File system implementation.
1131
- * @returns {Promise<Configuration>} Configuration object.
1132
- */
1133
- export function readConfigPromise(file, parsers, fs) {
1134
- return new Promise((resolve, reject) => {
1135
- readConfigAsync(file, parsers, fs, (error, results) => {
1136
- if (error || !results) {
1137
- reject(error);
1138
- } else {
1139
- resolve(results);
1140
- }
1141
- });
1142
- });
1143
- }
1144
-
1145
- /**
1146
- * Read specified configuration file.
1147
- *
1148
- * @param {string} file Configuration file name.
1149
- * @param {ConfigurationParser[]} [parsers] Parsing function(s).
1150
- * @param {FsLike} [fs] File system implementation.
1151
- * @returns {Configuration} Configuration object.
1152
- */
1153
- export function readConfigSync(file, parsers, fs) {
1154
- /** @type {FsLike} */
1155
- // @ts-ignore
1156
- const fsLike = fs || nodeFs;
1157
- // Read file
1158
- file = helpers.expandTildePath(file, os);
1159
- const content = fsLike.readFileSync(file, "utf8");
1160
- // Try to parse file
1161
- const { config, message } = parseConfiguration(file, content, parsers);
1162
- if (!config) {
1163
- // @ts-ignore
1164
- throw new Error(message);
1165
- }
1166
- // Extend configuration
1167
- const configExtends = config.extends;
1168
- if (configExtends) {
1169
- delete config.extends;
1170
- const resolvedExtends = resolveConfigExtendsSync(
1171
- file,
1172
- helpers.expandTildePath(configExtends, os),
1173
- fsLike
1174
- );
1175
- return {
1176
- ...readConfigSync(resolvedExtends, parsers, fs),
1177
- ...config
1178
- };
1179
- }
1180
- return config;
1181
- }
1182
-
1183
- /**
1184
- * Normalizes the fields of a RuleOnErrorFixInfo instance.
1185
- *
1186
- * @param {FixInfo} fixInfo RuleOnErrorFixInfo instance.
1187
- * @param {number} [lineNumber] Line number.
1188
- * @returns {FixInfoNormalized} Normalized RuleOnErrorFixInfo instance.
1189
- */
1190
- function normalizeFixInfo(fixInfo, lineNumber = 0) {
1191
- return {
1192
- "lineNumber": fixInfo.lineNumber || lineNumber,
1193
- "editColumn": fixInfo.editColumn || 1,
1194
- "deleteCount": fixInfo.deleteCount || 0,
1195
- "insertText": fixInfo.insertText || ""
1196
- };
1197
- }
1198
-
1199
- /**
1200
- * Applies the specified fix to a Markdown content line.
1201
- *
1202
- * @param {string} line Line of Markdown content.
1203
- * @param {FixInfo} fixInfo FixInfo instance.
1204
- * @param {string} [lineEnding] Line ending to use.
1205
- * @returns {string | null} Fixed content or null if deleted.
1206
- */
1207
- export function applyFix(line, fixInfo, lineEnding = "\n") {
1208
- const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo);
1209
- const editIndex = editColumn - 1;
1210
- return (deleteCount === -1) ?
1211
- null :
1212
- line.slice(0, editIndex) + insertText.replace(/\n/g, lineEnding) + line.slice(editIndex + deleteCount);
1213
- }
1214
-
1215
- /**
1216
- * Applies as many of the specified fixes as possible to Markdown content.
1217
- *
1218
- * @param {string} input Lines of Markdown content.
1219
- * @param {LintError[]} errors LintError instances.
1220
- * @returns {string} Fixed content.
1221
- */
1222
- export function applyFixes(input, errors) {
1223
- const lineEnding = helpers.getPreferredLineEnding(input, os);
1224
- const lines = input.split(helpers.newLineRe);
1225
- // Normalize fixInfo objects
1226
- let fixInfos = errors
1227
- .filter((error) => error.fixInfo)
1228
- // @ts-ignore
1229
- .map((error) => normalizeFixInfo(error.fixInfo, error.lineNumber));
1230
- // Sort bottom-to-top, line-deletes last, right-to-left, long-to-short
1231
- fixInfos.sort((a, b) => {
1232
- const aDeletingLine = (a.deleteCount === -1);
1233
- const bDeletingLine = (b.deleteCount === -1);
1234
- return (
1235
- (b.lineNumber - a.lineNumber) ||
1236
- (aDeletingLine ? 1 : (bDeletingLine ? -1 : 0)) ||
1237
- (b.editColumn - a.editColumn) ||
1238
- (b.insertText.length - a.insertText.length)
1239
- );
1240
- });
1241
- // Remove duplicate entries (needed for following collapse step)
1242
- /** @type {RuleOnErrorFixInfo} */
1243
- let lastFixInfo = {};
1244
- fixInfos = fixInfos.filter((fixInfo) => {
1245
- const unique = (
1246
- (fixInfo.lineNumber !== lastFixInfo.lineNumber) ||
1247
- (fixInfo.editColumn !== lastFixInfo.editColumn) ||
1248
- (fixInfo.deleteCount !== lastFixInfo.deleteCount) ||
1249
- (fixInfo.insertText !== lastFixInfo.insertText)
1250
- );
1251
- lastFixInfo = fixInfo;
1252
- return unique;
1253
- });
1254
- // Collapse insert/no-delete and no-insert/delete for same line/column
1255
- lastFixInfo = {
1256
- "lineNumber": -1
1257
- };
1258
- for (const fixInfo of fixInfos) {
1259
- if (
1260
- (fixInfo.lineNumber === lastFixInfo.lineNumber) &&
1261
- (fixInfo.editColumn === lastFixInfo.editColumn) &&
1262
- !fixInfo.insertText &&
1263
- (fixInfo.deleteCount > 0) &&
1264
- lastFixInfo.insertText &&
1265
- !lastFixInfo.deleteCount) {
1266
- fixInfo.insertText = lastFixInfo.insertText;
1267
- lastFixInfo.lineNumber = 0;
1268
- }
1269
- lastFixInfo = fixInfo;
1270
- }
1271
- fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber);
1272
- // Apply all (remaining/updated) fixes
1273
- let lastLineIndex = -1;
1274
- let lastEditIndex = -1;
1275
- for (const fixInfo of fixInfos) {
1276
- const { lineNumber, editColumn, deleteCount } = fixInfo;
1277
- const lineIndex = lineNumber - 1;
1278
- const editIndex = editColumn - 1;
1279
- if (
1280
- (lineIndex !== lastLineIndex) ||
1281
- (deleteCount === -1) ||
1282
- ((editIndex + deleteCount) <=
1283
- (lastEditIndex - ((deleteCount > 0) ? 0 : 1)))
1284
- ) {
1285
- // @ts-ignore
1286
- lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding);
1287
- }
1288
- lastLineIndex = lineIndex;
1289
- lastEditIndex = editIndex;
1290
- }
1291
- // Return corrected input
1292
- return lines.filter((line) => line !== null).join(lineEnding);
1293
- }
1294
-
1295
- /**
1296
- * Gets the (semantic) version of the library.
1297
- *
1298
- * @returns {string} SemVer string.
1299
- */
1300
- export function getVersion() {
1301
- return version;
1302
- }
1303
-
1304
- // Type declarations
1305
-
1306
- /**
1307
- * Function to implement rule logic.
1308
- *
1309
- * @callback RuleFunction
1310
- * @param {RuleParams} params Rule parameters.
1311
- * @param {RuleOnError} onError Error-reporting callback.
1312
- * @returns {void}
1313
- */
1314
-
1315
- /**
1316
- * Rule parameters.
1317
- *
1318
- * @typedef {Object} RuleParams
1319
- * @property {string} name File/string name.
1320
- * @property {MarkdownParsers} parsers Markdown parser data.
1321
- * @property {readonly string[]} lines File/string lines.
1322
- * @property {readonly string[]} frontMatterLines Front matter lines.
1323
- * @property {RuleConfiguration} config Rule configuration.
1324
- * @property {string} version Version of the markdownlint library.
1325
- */
1326
-
1327
- /**
1328
- * Markdown parser data.
1329
- *
1330
- * @typedef {Object} MarkdownParsers
1331
- * @property {ParserMarkdownIt} markdownit Markdown parser data from markdown-it (only present when Rule.parser is "markdownit").
1332
- * @property {ParserMicromark} micromark Markdown parser data from micromark (only present when Rule.parser is "micromark").
1333
- */
1334
-
1335
- /**
1336
- * Markdown parser data from markdown-it.
1337
- *
1338
- * @typedef {Object} ParserMarkdownIt
1339
- * @property {MarkdownItToken[]} tokens Token objects from markdown-it.
1340
- */
1341
-
1342
- /**
1343
- * Markdown parser data from micromark.
1344
- *
1345
- * @typedef {Object} ParserMicromark
1346
- * @property {MicromarkToken[]} tokens Token objects from micromark.
1347
- */
1348
-
1349
- /**
1350
- * markdown-it base token.
1351
- *
1352
- * @typedef {Object} MarkdownItBaseToken
1353
- * @property {string[][] | null} attrs HTML attributes.
1354
- * @property {boolean} block Block-level token.
1355
- * @property {MarkdownItBaseToken[] | null} children Child nodes.
1356
- * @property {string} content Tag contents.
1357
- * @property {boolean} hidden Ignore element.
1358
- * @property {string} info Fence info.
1359
- * @property {number} level Nesting level.
1360
- * @property {number[] | null} map Beginning/ending line numbers.
1361
- * @property {string} markup Markup text.
1362
- * @property {Object} meta Arbitrary data.
1363
- * @property {number} nesting Level change.
1364
- * @property {string} tag HTML tag name.
1365
- * @property {string} type Token type.
1366
- */
1367
-
1368
- /**
1369
- * markdown-it extended token.
1370
- *
1371
- * @typedef {Object} MarkdownItExtendedToken
1372
- * @property {MarkdownItExtendedToken[] | null} children Child nodes.
1373
- * @property {number} lineNumber Line number (1-based).
1374
- * @property {string} line Line content.
1375
- */
1376
-
1377
- /**
1378
- * markdown-it token.
1379
- *
1380
- * @typedef {MarkdownItBaseToken & MarkdownItExtendedToken} MarkdownItToken
1381
- */
1382
-
1383
- /** @typedef {import("micromark-util-types").TokenType} MicromarkTokenType */
1384
-
1385
- /**
1386
- * micromark token.
1387
- *
1388
- * @typedef {Object} MicromarkToken
1389
- * @property {MicromarkTokenType} type Token type.
1390
- * @property {number} startLine Start line (1-based).
1391
- * @property {number} startColumn Start column (1-based).
1392
- * @property {number} endLine End line (1-based).
1393
- * @property {number} endColumn End column (1-based).
1394
- * @property {string} text Token text.
1395
- * @property {MicromarkToken[]} children Child tokens.
1396
- * @property {MicromarkToken | null} parent Parent token.
1397
- */
1398
-
1399
- /**
1400
- * Error-reporting callback.
1401
- *
1402
- * @callback RuleOnError
1403
- * @param {RuleOnErrorInfo} onErrorInfo Error information.
1404
- * @returns {void}
1405
- */
1406
-
1407
- /**
1408
- * Fix information for RuleOnError callback.
1409
- *
1410
- * @typedef {Object} RuleOnErrorInfo
1411
- * @property {number} lineNumber Line number (1-based).
1412
- * @property {string} [detail] Detail about the error.
1413
- * @property {string} [context] Context for the error.
1414
- * @property {URL} [information] Link to more information.
1415
- * @property {number[]} [range] Column number (1-based) and length.
1416
- * @property {RuleOnErrorFixInfo} [fixInfo] Fix information.
1417
- */
1418
-
1419
- /**
1420
- * Fix information for RuleOnErrorInfo.
1421
- *
1422
- * @typedef {Object} RuleOnErrorFixInfo
1423
- * @property {number} [lineNumber] Line number (1-based).
1424
- * @property {number} [editColumn] Column of the fix (1-based).
1425
- * @property {number} [deleteCount] Count of characters to delete.
1426
- * @property {string} [insertText] Text to insert (after deleting).
1427
- */
1428
-
1429
- /**
1430
- * Rule definition.
1431
- *
1432
- * @typedef {Object} Rule
1433
- * @property {string[]} names Rule name(s).
1434
- * @property {string} description Rule description.
1435
- * @property {URL} [information] Link to more information.
1436
- * @property {string[]} tags Rule tag(s).
1437
- * @property {"markdownit" | "micromark" | "none"} parser Parser used.
1438
- * @property {boolean} [asynchronous] True if asynchronous.
1439
- * @property {RuleFunction} function Rule implementation.
1440
- */
1441
-
1442
- /**
1443
- * Method used by the markdown-it parser to parse input.
1444
- *
1445
- * @callback MarkdownItParse
1446
- * @param {string} src Source string.
1447
- * @param {Object} env Environment sandbox.
1448
- * @returns {MarkdownItBaseToken[]} Tokens.
1449
- */
1450
-
1451
- /**
1452
- * Instance of the markdown-it parser.
1453
- *
1454
- * @typedef MarkdownIt
1455
- * @property {MarkdownItParse} parse Method to parse input.
1456
- */
1457
-
1458
- /**
1459
- * Gets an instance of the markdown-it parser. Any plugins should already have been loaded.
1460
- *
1461
- * @callback MarkdownItFactory
1462
- * @returns {MarkdownIt|Promise<MarkdownIt>} Instance of the markdown-it parser.
1463
- */
1464
-
1465
- /**
1466
- * Configuration options.
1467
- *
1468
- * @typedef {Object} Options
1469
- * @property {Configuration} [config] Configuration object.
1470
- * @property {ConfigurationParser[]} [configParsers] Configuration parsers.
1471
- * @property {Rule[] | Rule} [customRules] Custom rules.
1472
- * @property {string[] | string} [files] Files to lint.
1473
- * @property {RegExp | null} [frontMatter] Front matter pattern.
1474
- * @property {FsLike} [fs] File system implementation.
1475
- * @property {boolean} [handleRuleFailures] True to catch exceptions.
1476
- * @property {MarkdownItFactory} [markdownItFactory] Function to create a markdown-it parser.
1477
- * @property {boolean} [noInlineConfig] True to ignore HTML directives.
1478
- * @property {Object.<string, string>} [strings] Strings to lint.
1479
- */
1480
-
1481
- /**
1482
- * A markdown-it plugin.
1483
- *
1484
- * @typedef {Object[]} Plugin
1485
- */
1486
-
1487
- /**
1488
- * Lint results.
1489
- *
1490
- * @typedef {Object.<string, LintError[]>} LintResults
1491
- */
1492
-
1493
- /**
1494
- * Lint error.
1495
- *
1496
- * @typedef {Object} LintError
1497
- * @property {number} lineNumber Line number (1-based).
1498
- * @property {string[]} ruleNames Rule name(s).
1499
- * @property {string} ruleDescription Rule description.
1500
- * @property {string | null} ruleInformation Link to more information.
1501
- * @property {string | null} errorDetail Detail about the error.
1502
- * @property {string | null} errorContext Context for the error.
1503
- * @property {number[] | null} errorRange Column number (1-based) and length.
1504
- * @property {FixInfo | null} fixInfo Fix information.
1505
- * @property {"error" | "warning"} severity Severity of the error.
1506
- */
1507
-
1508
- /**
1509
- * Fix information.
1510
- *
1511
- * @typedef {Object} FixInfo
1512
- * @property {number} [lineNumber] Line number (1-based).
1513
- * @property {number} [editColumn] Column of the fix (1-based).
1514
- * @property {number} [deleteCount] Count of characters to delete.
1515
- * @property {string} [insertText] Text to insert (after deleting).
1516
- */
1517
-
1518
- /**
1519
- * FixInfo with all optional properties present.
1520
- *
1521
- * @typedef {Object} FixInfoNormalized
1522
- * @property {number} lineNumber Line number (1-based).
1523
- * @property {number} editColumn Column of the fix (1-based).
1524
- * @property {number} deleteCount Count of characters to delete.
1525
- * @property {string} insertText Text to insert (after deleting).
1526
- */
1527
-
1528
- /**
1529
- * Called with the result of linting a string or document.
1530
- *
1531
- * @callback LintContentCallback
1532
- * @param {Error | null} error Error iff failed.
1533
- * @param {LintError[]} [result] Result iff successful.
1534
- * @returns {void}
1535
- */
1536
-
1537
- /**
1538
- * Called with the result of the lint function.
1539
- *
1540
- * @callback LintCallback
1541
- * @param {Error | null} error Error object iff failed.
1542
- * @param {LintResults} [results] Lint results iff succeeded.
1543
- * @returns {void}
1544
- */
1545
-
1546
- /**
1547
- * Configuration object for linting rules. For the JSON schema, see
1548
- * {@link ../schema/markdownlint-config-schema.json}.
1549
- *
1550
- * @typedef {import("./configuration.d.ts").Configuration} Configuration
1551
- */
1552
-
1553
- /**
1554
- * Configuration object for linting rules strictly. For the JSON schema, see
1555
- * {@link ../schema/markdownlint-config-schema-strict.json}.
1556
- *
1557
- * @typedef {import("./configuration-strict.d.ts").ConfigurationStrict} ConfigurationStrict
1558
- */
1559
-
1560
- /**
1561
- * Parses a configuration string and returns a configuration object.
1562
- *
1563
- * @callback ConfigurationParser
1564
- * @param {string} text Configuration string.
1565
- * @returns {Configuration}
1566
- */
1567
-
1568
- /**
1569
- * Called with the result of the readConfig function.
1570
- *
1571
- * @callback ReadConfigCallback
1572
- * @param {Error | null} err Error object or null.
1573
- * @param {Configuration} [config] Configuration object.
1574
- * @returns {void}
1575
- */
1576
-
1577
- /**
1578
- * Called with the result of the resolveConfigExtends function.
1579
- *
1580
- * @callback ResolveConfigExtendsCallback
1581
- * @param {Error | null} err Error object or null.
1582
- * @param {string} [path] Resolved path to file.
1583
- * @returns {void}
1584
- */
1585
-
1586
- /* eslint-disable jsdoc/reject-any-type */
1587
-
1588
- /**
1589
- * Rule configuration object.
1590
- *
1591
- * @typedef {boolean | any} RuleConfiguration Rule configuration.
1592
- */