@html-eslint/eslint-plugin 0.45.0 → 0.46.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.
@@ -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,6 +1,8 @@
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
 
@@ -16,27 +18,24 @@ const plugin = {
16
18
  name,
17
19
  version,
18
20
  },
19
- configs: {
20
- recommended,
21
-
22
- "flat/recommended": {
23
- plugins: {
24
- /** @type {ESLint.Plugin} */
25
- get "@html-eslint"() {
26
- return plugin;
27
- },
28
- },
29
-
30
- languageOptions: {
31
- parser,
32
- },
33
- rules: recommended.rules,
34
- },
35
- },
36
21
  languages: {
37
22
  html: new HTMLLanguage(),
38
23
  },
39
24
  rules,
25
+ configs: {
26
+ recommended: {
27
+ rules: recommendedRules,
28
+ plugins: {},
29
+ },
30
+ ["recommended-legacy"]: {
31
+ rules: recommendedLegacyRules,
32
+ },
33
+ },
40
34
  };
41
35
 
36
+ {
37
+ // @ts-ignore
38
+ plugin.configs.recommended.plugins.html = plugin;
39
+ }
40
+
42
41
  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.0",
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": "01f54b34922f987051762f4b2e5c816cbfeeab68"
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,70 +1,44 @@
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");
7
5
  export declare namespace meta {
8
6
  export { name };
9
7
  export { version };
10
8
  }
9
+ export declare namespace languages {
10
+ let html: HTMLLanguage;
11
+ }
12
+ export { rules };
11
13
  export declare let configs: {
12
14
  recommended: {
13
15
  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", {
16
+ "html/require-lang": "error";
17
+ "html/require-img-alt": "error";
18
+ "html/require-doctype": "error";
19
+ "html/require-title": "error";
20
+ "html/no-multiple-h1": "error";
21
+ "html/no-extra-spacing-attrs": "error";
22
+ "html/attrs-newline": "error";
23
+ "html/element-newline": ["error", {
22
24
  inline: string[];
23
25
  }];
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";
26
+ "html/no-duplicate-id": "error";
27
+ "html/indent": "error";
28
+ "html/require-li-container": "error";
29
+ "html/quotes": "error";
30
+ "html/no-obsolete-tags": "error";
31
+ "html/require-closing-tags": "error";
32
+ "html/no-duplicate-attrs": "error";
33
+ "html/use-baseline": "error";
34
+ "html/no-duplicate-in-head": "error";
33
35
  };
36
+ plugins: {};
34
37
  };
35
- "flat/recommended": {
36
- plugins: {
37
- /** @type {ESLint.Plugin} */
38
- readonly "@html-eslint": ESLint.Plugin;
39
- };
40
- languageOptions: {
41
- parser: typeof parser;
42
- };
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
- };
38
+ "recommended-legacy": {
39
+ rules: Record<string, "error" | ["error", {
40
+ inline: string[];
41
+ }]>;
64
42
  };
65
43
  };
66
- export declare namespace languages {
67
- let html: HTMLLanguage;
68
- }
69
- export { rules };
70
44
  //# 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":""}
@@ -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"}