@html-eslint/eslint-plugin 0.45.0 → 0.46.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.
@@ -1,29 +1,39 @@
1
- /** @satisfies {import('eslint').Linter.FlatConfig} */
2
- const recommended = {
3
- rules: {
4
- "@html-eslint/require-lang": "error",
5
- "@html-eslint/require-img-alt": "error",
6
- "@html-eslint/require-doctype": "error",
7
- "@html-eslint/require-title": "error",
8
- "@html-eslint/no-multiple-h1": "error",
9
- "@html-eslint/no-extra-spacing-attrs": "error",
10
- "@html-eslint/attrs-newline": "error",
11
- "@html-eslint/element-newline": [
12
- "error",
13
- {
14
- inline: [`$inline`],
15
- },
16
- ],
17
- "@html-eslint/no-duplicate-id": "error",
18
- "@html-eslint/indent": "error",
19
- "@html-eslint/require-li-container": "error",
20
- "@html-eslint/quotes": "error",
21
- "@html-eslint/no-obsolete-tags": "error",
22
- "@html-eslint/require-closing-tags": "error",
23
- "@html-eslint/no-duplicate-attrs": "error",
24
- "@html-eslint/use-baseline": "error",
25
- "@html-eslint/no-duplicate-in-head": "error",
26
- },
1
+ /** @satisfies {import('eslint').Linter.Config['rules']} */
2
+ const recommendedRules = {
3
+ "html/require-lang": "error",
4
+ "html/require-img-alt": "error",
5
+ "html/require-doctype": "error",
6
+ "html/require-title": "error",
7
+ "html/no-multiple-h1": "error",
8
+ "html/no-extra-spacing-attrs": "error",
9
+ "html/attrs-newline": "error",
10
+ "html/element-newline": [
11
+ "error",
12
+ {
13
+ inline: [`$inline`],
14
+ },
15
+ ],
16
+ "html/no-duplicate-id": "error",
17
+ "html/indent": "error",
18
+ "html/require-li-container": "error",
19
+ "html/quotes": "error",
20
+ "html/no-obsolete-tags": "error",
21
+ "html/require-closing-tags": "error",
22
+ "html/no-duplicate-attrs": "error",
23
+ "html/use-baseline": "error",
24
+ "html/no-duplicate-in-head": "error",
27
25
  };
28
26
 
29
- module.exports = recommended;
27
+ const recommendedLegacyRules = Object.entries(recommendedRules).reduce(
28
+ (acc, [key, value]) => {
29
+ acc[key.replace("html/", "@html-eslint/")] = value;
30
+ return acc;
31
+ },
32
+ /** @type {Record<string, typeof recommendedRules[keyof typeof recommendedRules]>} */
33
+ ({})
34
+ );
35
+
36
+ module.exports = {
37
+ recommendedRules,
38
+ recommendedLegacyRules,
39
+ };
package/lib/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  const rules = require("./rules");
2
- const recommended = require("./configs/recommended");
3
- const parser = require("@html-eslint/parser");
2
+ const {
3
+ recommendedRules,
4
+ recommendedLegacyRules,
5
+ } = require("./configs/recommended");
4
6
  const { HTMLLanguage } = require("./languages/html-language");
5
7
  const { name, version } = require("../package.json");
6
-
8
+ const parser = require("@html-eslint/parser");
7
9
  /**
8
10
  * @import { ESLint } from "eslint";
9
11
  */
@@ -16,9 +18,18 @@ const plugin = {
16
18
  name,
17
19
  version,
18
20
  },
21
+ languages: {
22
+ html: new HTMLLanguage(),
23
+ },
24
+ rules,
19
25
  configs: {
20
- recommended,
21
-
26
+ recommended: {
27
+ rules: recommendedRules,
28
+ plugins: {},
29
+ },
30
+ ["recommended-legacy"]: {
31
+ rules: recommendedLegacyRules,
32
+ },
22
33
  "flat/recommended": {
23
34
  plugins: {
24
35
  /** @type {ESLint.Plugin} */
@@ -26,17 +37,17 @@ const plugin = {
26
37
  return plugin;
27
38
  },
28
39
  },
29
-
30
40
  languageOptions: {
31
41
  parser,
32
42
  },
33
- rules: recommended.rules,
43
+ rules: recommendedLegacyRules,
34
44
  },
35
45
  },
36
- languages: {
37
- html: new HTMLLanguage(),
38
- },
39
- rules,
40
46
  };
41
47
 
48
+ {
49
+ // @ts-ignore
50
+ plugin.configs.recommended.plugins.html = plugin;
51
+ }
52
+
42
53
  module.exports = plugin;
@@ -1,5 +1,10 @@
1
1
  /**
2
- * @import {Tag, StyleTag, ScriptTag} from "@html-eslint/types";
2
+ * @import {
3
+ * Tag,
4
+ * StyleTag,
5
+ * ScriptTag,
6
+ * Doctype,
7
+ * } from "@html-eslint/types";
3
8
  * @import {RuleModule} from "../types";
4
9
  */
5
10
 
@@ -128,6 +133,48 @@ module.exports = {
128
133
  }
129
134
  }
130
135
 
136
+ /**
137
+ * @param {Doctype} doctype
138
+ */
139
+ function checkDoctype(doctype) {
140
+ if (doctype.open.value !== doctype.open.value.toLowerCase()) {
141
+ context.report({
142
+ node: doctype.open,
143
+ messageId: MESSAGE_IDS.UNEXPECTED,
144
+ data: {
145
+ name: doctype.open.value.slice(1),
146
+ },
147
+ fix(fixer) {
148
+ return fixer.replaceTextRange(doctype.open.range, "<!doctype");
149
+ },
150
+ });
151
+ }
152
+ if (doctype.attributes && doctype.attributes.length) {
153
+ doctype.attributes.forEach((attribute) => {
154
+ if (
155
+ attribute.value &&
156
+ attribute.value.value !== attribute.value.value.toLowerCase()
157
+ ) {
158
+ context.report({
159
+ node: attribute.value,
160
+ messageId: MESSAGE_IDS.UNEXPECTED,
161
+ data: {
162
+ name: attribute.value.value,
163
+ },
164
+ fix(fixer) {
165
+ return fixer.replaceText(
166
+ // @ts-ignore
167
+ attribute.value,
168
+ // @ts-ignore
169
+ attribute.value.value.toLowerCase()
170
+ );
171
+ },
172
+ });
173
+ }
174
+ });
175
+ }
176
+ }
177
+
131
178
  return createVisitors(context, {
132
179
  Tag(node) {
133
180
  if (node.name.toLocaleLowerCase() === "svg") {
@@ -142,6 +189,7 @@ module.exports = {
142
189
  },
143
190
  StyleTag: check,
144
191
  ScriptTag: check,
192
+ Doctype: checkDoctype,
145
193
  });
146
194
  },
147
195
  };
@@ -24,7 +24,7 @@ module.exports = {
24
24
  type: "code",
25
25
 
26
26
  docs: {
27
- description: "Enforce attributes alphabetical sorting",
27
+ description: "Enforce priority and alphabetical sorting of attributes",
28
28
  category: RULE_CATEGORY.STYLE,
29
29
  recommended: false,
30
30
  url: getRuleUrl("sort-attrs"),
@@ -60,7 +60,8 @@ module.exports = {
60
60
  },
61
61
  ],
62
62
  messages: {
63
- [MESSAGE_IDS.UNSORTED]: "Attributes should be sorted alphabetically",
63
+ [MESSAGE_IDS.UNSORTED]:
64
+ "Attributes should be sorted by priority and alphabetically",
64
65
  },
65
66
  },
66
67
  create(context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.45.0",
3
+ "version": "0.46.1",
4
4
  "type": "commonjs",
5
5
  "description": "ESLint plugin for HTML",
6
6
  "author": "yeonjuan",
@@ -40,16 +40,16 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "@eslint/plugin-kit": "^0.3.1",
43
- "@html-eslint/parser": "^0.45.0",
44
- "@html-eslint/template-parser": "^0.45.0",
45
- "@html-eslint/template-syntax-parser": "^0.45.0"
43
+ "@html-eslint/parser": "^0.46.0",
44
+ "@html-eslint/template-parser": "^0.46.0",
45
+ "@html-eslint/template-syntax-parser": "^0.46.0"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "eslint": "^8.0.0 || ^9.0.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@eslint/core": "^0.14.0",
52
- "@html-eslint/types": "^0.45.0",
52
+ "@html-eslint/types": "^0.46.0",
53
53
  "@types/estree": "^0.0.47",
54
54
  "es-html-parser": "0.3.0",
55
55
  "eslint": "^9.27.0",
@@ -59,5 +59,5 @@
59
59
  "engines": {
60
60
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
61
61
  },
62
- "gitHead": "39d3cc1773a4d999ba348ded5903d753a3f7d12c"
62
+ "gitHead": "30d2b2e4c8b4b69fade92dbe37cb2a178500207c"
63
63
  }
@@ -1,22 +1,26 @@
1
- export let rules: {
2
- "@html-eslint/require-lang": "error";
3
- "@html-eslint/require-img-alt": "error";
4
- "@html-eslint/require-doctype": "error";
5
- "@html-eslint/require-title": "error";
6
- "@html-eslint/no-multiple-h1": "error";
7
- "@html-eslint/no-extra-spacing-attrs": "error";
8
- "@html-eslint/attrs-newline": "error";
9
- "@html-eslint/element-newline": ["error", {
1
+ /** @satisfies {import('eslint').Linter.Config['rules']} */
2
+ export const recommendedRules: {
3
+ "html/require-lang": "error";
4
+ "html/require-img-alt": "error";
5
+ "html/require-doctype": "error";
6
+ "html/require-title": "error";
7
+ "html/no-multiple-h1": "error";
8
+ "html/no-extra-spacing-attrs": "error";
9
+ "html/attrs-newline": "error";
10
+ "html/element-newline": ["error", {
10
11
  inline: string[];
11
12
  }];
12
- "@html-eslint/no-duplicate-id": "error";
13
- "@html-eslint/indent": "error";
14
- "@html-eslint/require-li-container": "error";
15
- "@html-eslint/quotes": "error";
16
- "@html-eslint/no-obsolete-tags": "error";
17
- "@html-eslint/require-closing-tags": "error";
18
- "@html-eslint/no-duplicate-attrs": "error";
19
- "@html-eslint/use-baseline": "error";
20
- "@html-eslint/no-duplicate-in-head": "error";
13
+ "html/no-duplicate-id": "error";
14
+ "html/indent": "error";
15
+ "html/require-li-container": "error";
16
+ "html/quotes": "error";
17
+ "html/no-obsolete-tags": "error";
18
+ "html/require-closing-tags": "error";
19
+ "html/no-duplicate-attrs": "error";
20
+ "html/use-baseline": "error";
21
+ "html/no-duplicate-in-head": "error";
21
22
  };
23
+ export const recommendedLegacyRules: Record<string, "error" | ["error", {
24
+ inline: string[];
25
+ }]>;
22
26
  //# sourceMappingURL=recommended.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../lib/configs/recommended.js"],"names":[],"mappings":""}
1
+ {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../lib/configs/recommended.js"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D;;;;;;;;;;;;;;;;;;;;EAuBE;AAEF;;IAOE"}
package/types/index.d.ts CHANGED
@@ -1,36 +1,46 @@
1
1
  import { name } from "../package.json";
2
2
  import { version } from "../package.json";
3
- import type { ESLint } from "eslint";
4
- import parser = require("@html-eslint/parser");
5
3
  import { HTMLLanguage } from "./languages/html-language";
6
4
  import rules = require("./rules");
5
+ import type { ESLint } from "eslint";
6
+ import parser = require("@html-eslint/parser");
7
7
  export declare namespace meta {
8
8
  export { name };
9
9
  export { version };
10
10
  }
11
+ export declare namespace languages {
12
+ let html: HTMLLanguage;
13
+ }
14
+ export { rules };
11
15
  export declare let configs: {
12
16
  recommended: {
13
17
  rules: {
14
- "@html-eslint/require-lang": "error";
15
- "@html-eslint/require-img-alt": "error";
16
- "@html-eslint/require-doctype": "error";
17
- "@html-eslint/require-title": "error";
18
- "@html-eslint/no-multiple-h1": "error";
19
- "@html-eslint/no-extra-spacing-attrs": "error";
20
- "@html-eslint/attrs-newline": "error";
21
- "@html-eslint/element-newline": ["error", {
18
+ "html/require-lang": "error";
19
+ "html/require-img-alt": "error";
20
+ "html/require-doctype": "error";
21
+ "html/require-title": "error";
22
+ "html/no-multiple-h1": "error";
23
+ "html/no-extra-spacing-attrs": "error";
24
+ "html/attrs-newline": "error";
25
+ "html/element-newline": ["error", {
22
26
  inline: string[];
23
27
  }];
24
- "@html-eslint/no-duplicate-id": "error";
25
- "@html-eslint/indent": "error";
26
- "@html-eslint/require-li-container": "error";
27
- "@html-eslint/quotes": "error";
28
- "@html-eslint/no-obsolete-tags": "error";
29
- "@html-eslint/require-closing-tags": "error";
30
- "@html-eslint/no-duplicate-attrs": "error";
31
- "@html-eslint/use-baseline": "error";
32
- "@html-eslint/no-duplicate-in-head": "error";
28
+ "html/no-duplicate-id": "error";
29
+ "html/indent": "error";
30
+ "html/require-li-container": "error";
31
+ "html/quotes": "error";
32
+ "html/no-obsolete-tags": "error";
33
+ "html/require-closing-tags": "error";
34
+ "html/no-duplicate-attrs": "error";
35
+ "html/use-baseline": "error";
36
+ "html/no-duplicate-in-head": "error";
33
37
  };
38
+ plugins: {};
39
+ };
40
+ "recommended-legacy": {
41
+ rules: Record<string, "error" | ["error", {
42
+ inline: string[];
43
+ }]>;
34
44
  };
35
45
  "flat/recommended": {
36
46
  plugins: {
@@ -40,31 +50,9 @@ export declare let configs: {
40
50
  languageOptions: {
41
51
  parser: typeof parser;
42
52
  };
43
- rules: {
44
- "@html-eslint/require-lang": "error";
45
- "@html-eslint/require-img-alt": "error";
46
- "@html-eslint/require-doctype": "error";
47
- "@html-eslint/require-title": "error";
48
- "@html-eslint/no-multiple-h1": "error";
49
- "@html-eslint/no-extra-spacing-attrs": "error";
50
- "@html-eslint/attrs-newline": "error";
51
- "@html-eslint/element-newline": ["error", {
52
- inline: string[];
53
- }];
54
- "@html-eslint/no-duplicate-id": "error";
55
- "@html-eslint/indent": "error";
56
- "@html-eslint/require-li-container": "error";
57
- "@html-eslint/quotes": "error";
58
- "@html-eslint/no-obsolete-tags": "error";
59
- "@html-eslint/require-closing-tags": "error";
60
- "@html-eslint/no-duplicate-attrs": "error";
61
- "@html-eslint/use-baseline": "error";
62
- "@html-eslint/no-duplicate-in-head": "error";
63
- };
53
+ rules: Record<string, "error" | ["error", {
54
+ inline: string[];
55
+ }]>;
64
56
  };
65
57
  };
66
- export declare namespace languages {
67
- let html: HTMLLanguage;
68
- }
69
- export { rules };
70
58
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";;4BAO2B,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgB3B,4BAA4B;qCAAjB,aAAa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";;;;4BAS2B,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAyB3B,4BAA4B;qCAAjB,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"lowercase.d.ts","sourceRoot":"","sources":["../../lib/rules/lowercase.js"],"names":[],"mappings":"wBAgBU,WAAW,EAAE,CAAC;;gCAdK,UAAU"}
1
+ {"version":3,"file":"lowercase.d.ts","sourceRoot":"","sources":["../../lib/rules/lowercase.js"],"names":[],"mappings":"wBAqBU,WAAW,EAAE,CAAC;;gCAdK,UAAU"}