@html-eslint/eslint-plugin 0.40.1 → 0.40.3-alpha.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.
package/lib/index.js CHANGED
@@ -6,10 +6,13 @@ const { name, version } = require("../package.json");
6
6
  /**
7
7
  * @typedef {import("./rules")} AllRules
8
8
  * @typedef {import("./configs/recommended")} RecommendedConfig
9
+ * @typedef {{name: string, version: string}} PluginMeta
10
+ * @typedef {{recommended: RecommendedConfig, "flat/recommended": import("eslint").Linter.FlatConfig }} HtmlESLintConfigs
11
+ * @typedef {{html: HTMLLanguage}} Languages
9
12
  */
10
13
 
11
14
  /**
12
- * @type {{meta: { name: string, version: string }, rules: AllRules, configs: {recommended: RecommendedConfig, "flat/recommended": import("eslint").Linter.FlatConfig }}}
15
+ * @type {{meta: PluginMeta, rules: AllRules, configs: HtmlESLintConfigs, languages: Languages}}
13
16
  */
14
17
  const plugin = {
15
18
  meta: {
@@ -65,16 +65,24 @@ class HTMLLanguage {
65
65
  * @param {File} file
66
66
  * @param {Object} [context]
67
67
  * @param {LanguageOptions} context.languageOptions
68
+ * @returns {{ok: true; ast: any; comments: any[]} | {ok: false, errors: unknown[]}}
68
69
  */
69
70
  parse(file, context) {
70
71
  const code = /** @type {string} */ (file.body);
71
72
  const languageOptions = (context && context.languageOptions) || {};
72
- const result = parseForESLint(code, languageOptions);
73
- return {
74
- ok: true,
75
- ast: result.ast,
76
- comments: result.ast.comments,
77
- };
73
+ try {
74
+ const result = parseForESLint(code, languageOptions);
75
+ return {
76
+ ok: true,
77
+ ast: result.ast,
78
+ comments: result.ast.comments,
79
+ };
80
+ } catch (e) {
81
+ return {
82
+ ok: false,
83
+ errors: [e],
84
+ };
85
+ }
78
86
  }
79
87
 
80
88
  /**
@@ -5,6 +5,7 @@
5
5
  * @typedef {import("@eslint/core").TraversalStep} TraversalStep
6
6
  * @typedef {import("@html-eslint/types").CommentContent} CommentContent
7
7
  * @typedef {import("@html-eslint/types").AnyHTMLNode} AnyHTMLNode
8
+ * @typedef {import("@eslint/core").Position} Position
8
9
  * @typedef {import("../types").BaseNode} BaseNode
9
10
  */
10
11
  const {
@@ -12,10 +13,15 @@ const {
12
13
  ConfigCommentParser,
13
14
  Directive,
14
15
  } = require("@eslint/plugin-kit");
15
- const { SourceCode } = require("eslint");
16
16
  const { HTMLTraversalStep, STEP_PHASE } = require("./html-traversal-step");
17
17
  const { visitorKeys } = require("@html-eslint/parser");
18
18
 
19
+ const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u;
20
+
21
+ function createGlobalLinebreakMatcher() {
22
+ return new RegExp(lineBreakPattern.source, "gu");
23
+ }
24
+
19
25
  const INLINE_CONFIG =
20
26
  /^\s*(?:eslint(?:-enable|-disable(?:(?:-next)?-line)?)?)(?:\s|$)/u;
21
27
 
@@ -27,10 +33,7 @@ class HTMLSourceCode extends TextSourceCodeBase {
27
33
  */
28
34
  constructor({ ast, text, comments }) {
29
35
  super({ ast, text });
30
- /**
31
- * @property
32
- */
33
- this.eslintSourceCode = new SourceCode(text, ast);
36
+
34
37
  /**
35
38
  * @property
36
39
  */
@@ -40,6 +43,14 @@ class HTMLSourceCode extends TextSourceCodeBase {
40
43
  */
41
44
  this.comments = comments;
42
45
  this.parentsMap = new Map();
46
+
47
+ this.lineStartIndices = [0];
48
+
49
+ const lineEndingPattern = createGlobalLinebreakMatcher();
50
+ let match;
51
+ while ((match = lineEndingPattern.exec(this.text))) {
52
+ this.lineStartIndices.push(match.index + match[0].length);
53
+ }
43
54
  }
44
55
 
45
56
  /**
@@ -62,20 +73,88 @@ class HTMLSourceCode extends TextSourceCodeBase {
62
73
  return this.lines;
63
74
  }
64
75
 
76
+ // Copied from eslint source code
65
77
  /**
66
- * @param {import("@eslint/core").Position} loc
67
- * @returns
78
+ * @see https://github.com/eslint/eslint/blob/f60f2764971a33e252be13e560dccf21f554dbf1/lib/languages/js/source-code/source-code.js#L745
79
+ * @param {Position} loc
80
+ * @returns {number}
68
81
  */
69
82
  getIndexFromLoc(loc) {
70
- return this.eslintSourceCode.getIndexFromLoc(loc);
83
+ if (
84
+ typeof loc !== "object" ||
85
+ typeof loc.line !== "number" ||
86
+ typeof loc.column !== "number"
87
+ ) {
88
+ throw new TypeError(
89
+ "Expected `loc` to be an object with numeric `line` and `column` properties."
90
+ );
91
+ }
92
+
93
+ if (loc.line <= 0) {
94
+ throw new RangeError(
95
+ `Line number out of range (line ${loc.line} requested). Line numbers should be 1-based.`
96
+ );
97
+ }
98
+
99
+ if (loc.line > this.lineStartIndices.length) {
100
+ throw new RangeError(
101
+ `Line number out of range (line ${loc.line} requested, but only ${this.lineStartIndices.length} lines present).`
102
+ );
103
+ }
104
+
105
+ const lineStartIndex = this.lineStartIndices[loc.line - 1];
106
+ const lineEndIndex =
107
+ loc.line === this.lineStartIndices.length
108
+ ? this.text.length
109
+ : this.lineStartIndices[loc.line];
110
+ const positionIndex = lineStartIndex + loc.column;
111
+ if (
112
+ (loc.line === this.lineStartIndices.length &&
113
+ positionIndex > lineEndIndex) ||
114
+ (loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex)
115
+ ) {
116
+ throw new RangeError(
117
+ `Column number out of range (column ${loc.column} requested, but the length of line ${loc.line} is ${lineEndIndex - lineStartIndex}).`
118
+ );
119
+ }
120
+
121
+ return positionIndex;
71
122
  }
72
123
 
124
+ // Copied from eslint source code
73
125
  /**
126
+ * @see https://github.com/eslint/eslint/blob/f60f2764971a33e252be13e560dccf21f554dbf1/lib/languages/js/source-code/source-code.js#L694
74
127
  * @param {number} index
75
- * @returns {import("@eslint/core").Position}
128
+ * @returns {Position}
76
129
  */
77
130
  getLocFromIndex(index) {
78
- return this.eslintSourceCode.getLocFromIndex(index);
131
+ if (typeof index !== "number") {
132
+ throw new TypeError("Expected `index` to be a number.");
133
+ }
134
+
135
+ if (index < 0 || index > this.text.length) {
136
+ throw new RangeError(
137
+ `Index out of range (requested index ${index}, but source text has length ${this.text.length}).`
138
+ );
139
+ }
140
+ if (index === this.text.length) {
141
+ return {
142
+ line: this.lines.length,
143
+ // @ts-ignore
144
+ column: this.lines.at(-1).length,
145
+ };
146
+ }
147
+
148
+ const lineNumber =
149
+ // @ts-ignore
150
+ index >= this.lineStartIndices.at(-1)
151
+ ? this.lineStartIndices.length
152
+ : this.lineStartIndices.findIndex((el) => index < el);
153
+
154
+ return {
155
+ line: lineNumber,
156
+ column: index - this.lineStartIndices[lineNumber - 1],
157
+ };
79
158
  }
80
159
 
81
160
  getInlineConfigNodes() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@html-eslint/eslint-plugin",
3
- "version": "0.40.1",
3
+ "version": "0.40.3-alpha.0",
4
4
  "description": "ESLint plugin for html",
5
5
  "author": "yeonjuan",
6
6
  "homepage": "https://github.com/yeonjuan/html-eslint#readme",
@@ -39,12 +39,12 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "@eslint/plugin-kit": "0.2.8",
42
+ "@html-eslint/parser": "^0.40.0",
42
43
  "@html-eslint/template-parser": "^0.40.0",
43
44
  "@html-eslint/template-syntax-parser": "^0.40.0"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@eslint/core": "0.13.0",
47
- "@html-eslint/parser": "^0.40.0",
48
48
  "@html-eslint/types": "^0.40.0",
49
49
  "@types/eslint": "^9.6.1",
50
50
  "@types/estree": "^0.0.47",
@@ -53,5 +53,5 @@
53
53
  "espree": "^10.3.0",
54
54
  "typescript": "^5.7.2"
55
55
  },
56
- "gitHead": "595b1231bd0876792b229170edaecd4a7239d7fb"
56
+ "gitHead": "873a490bff042b8ad9b8451210f08688c683f510"
57
57
  }
package/types/index.d.ts CHANGED
@@ -2,23 +2,21 @@ export = plugin;
2
2
  /**
3
3
  * @typedef {import("./rules")} AllRules
4
4
  * @typedef {import("./configs/recommended")} RecommendedConfig
5
+ * @typedef {{name: string, version: string}} PluginMeta
6
+ * @typedef {{recommended: RecommendedConfig, "flat/recommended": import("eslint").Linter.FlatConfig }} HtmlESLintConfigs
7
+ * @typedef {{html: HTMLLanguage}} Languages
5
8
  */
6
9
  /**
7
- * @type {{meta: { name: string, version: string }, rules: AllRules, configs: {recommended: RecommendedConfig, "flat/recommended": import("eslint").Linter.FlatConfig }}}
10
+ * @type {{meta: PluginMeta, rules: AllRules, configs: HtmlESLintConfigs, languages: Languages}}
8
11
  */
9
12
  declare const plugin: {
10
- meta: {
11
- name: string;
12
- version: string;
13
- };
13
+ meta: PluginMeta;
14
14
  rules: AllRules;
15
- configs: {
16
- recommended: RecommendedConfig;
17
- "flat/recommended": import("eslint").Linter.FlatConfig;
18
- };
15
+ configs: HtmlESLintConfigs;
16
+ languages: Languages;
19
17
  };
20
18
  declare namespace plugin {
21
- export { AllRules, RecommendedConfig };
19
+ export { AllRules, RecommendedConfig, PluginMeta, HtmlESLintConfigs, Languages };
22
20
  }
23
21
  type AllRules = {
24
22
  "require-lang": import("./types").RuleModule<[]>;
@@ -93,4 +91,16 @@ type RecommendedConfig = {
93
91
  "@html-eslint/use-baseline": string;
94
92
  };
95
93
  };
94
+ type PluginMeta = {
95
+ name: string;
96
+ version: string;
97
+ };
98
+ type HtmlESLintConfigs = {
99
+ recommended: RecommendedConfig;
100
+ "flat/recommended": import("eslint").Linter.FlatConfig;
101
+ };
102
+ type Languages = {
103
+ html: HTMLLanguage;
104
+ };
105
+ import { HTMLLanguage } from "./languages/html-language";
96
106
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";AAKA;;;GAGG;AAEH;;GAEG;AACH,sBAFU;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE;QAAC,WAAW,EAAE,iBAAiB,CAAC;QAAC,kBAAkB,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAA;KAAE,CAAA;CAAC,CAetK"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.js"],"names":[],"mappings":";AAKA;;;;;;GAMG;AAEH;;GAEG;AACH,sBAFU;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAC,CAe7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBArBW;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC;yBAC/B;IAAC,WAAW,EAAE,iBAAiB,CAAC;IAAC,kBAAkB,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE;iBACzF;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC"}
@@ -37,13 +37,17 @@ export class HTMLLanguage {
37
37
  * @param {File} file
38
38
  * @param {Object} [context]
39
39
  * @param {LanguageOptions} context.languageOptions
40
+ * @returns {{ok: true; ast: any; comments: any[]} | {ok: false, errors: unknown[]}}
40
41
  */
41
42
  parse(file: File, context?: {
42
43
  languageOptions: LanguageOptions;
43
44
  }): {
44
- ok: boolean;
45
+ ok: true;
45
46
  ast: any;
46
- comments: any;
47
+ comments: any[];
48
+ } | {
49
+ ok: false;
50
+ errors: unknown[];
47
51
  };
48
52
  /**
49
53
  * @param {File} file
@@ -1 +1 @@
1
- {"version":3,"file":"html-language.d.ts","sourceRoot":"","sources":["../../lib/languages/html-language.js"],"names":[],"mappings":"mBAIa,OAAO,cAAc,EAAE,IAAI;8BAC3B,OAAO,qBAAqB,EAAE,aAAa;AAFxD;;;GAGG;AACH;IAEI;;;OAGG;IACH,UAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,CAAC,GAAC,CAAC,CAEK;IAElB;;;OAGG;IACH,aAFU,CAAC,GAAC,CAAC,CAEO;IAEpB;;OAEG;IACH,aAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,aAFU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEJ;IAGhC;;OAEG;IACH,yCAFW,eAAe,QAqBzB;IAED;;;;OAIG;IACH,YAJW,IAAI,YAEZ;QAAiC,eAAe,EAAxC,eAAe;KACzB;;;;MAUA;IAED;;;OAGG;IACH,uBAHW,IAAI,eACJ,GAAG,kBAQb;CACF"}
1
+ {"version":3,"file":"html-language.d.ts","sourceRoot":"","sources":["../../lib/languages/html-language.js"],"names":[],"mappings":"mBAIa,OAAO,cAAc,EAAE,IAAI;8BAC3B,OAAO,qBAAqB,EAAE,aAAa;AAFxD;;;GAGG;AACH;IAEI;;;OAGG;IACH,UAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,WAFU,CAAC,GAAC,CAAC,CAEK;IAElB;;;OAGG;IACH,aAFU,CAAC,GAAC,CAAC,CAEO;IAEpB;;OAEG;IACH,aAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,aAFU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEJ;IAGhC;;OAEG;IACH,yCAFW,eAAe,QAqBzB;IAED;;;;;OAKG;IACH,YALW,IAAI,YAEZ;QAAiC,eAAe,EAAxC,eAAe;KACvB,GAAU;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,EAAE,CAAA;KAAC,GAAG;QAAC,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAC,CAkBlF;IAED;;;OAGG;IACH,uBAHW,IAAI,eACJ,GAAG,kBAQb;CACF"}
@@ -4,6 +4,7 @@ export type DirectiveType = import("@eslint/plugin-kit").DirectiveType;
4
4
  export type TraversalStep = import("@eslint/core").TraversalStep;
5
5
  export type CommentContent = import("@html-eslint/types").CommentContent;
6
6
  export type AnyHTMLNode = import("@html-eslint/types").AnyHTMLNode;
7
+ export type Position = import("@eslint/core").Position;
7
8
  export type BaseNode = import("../types").BaseNode;
8
9
  export class HTMLSourceCode extends TextSourceCodeBase {
9
10
  /**
@@ -14,10 +15,6 @@ export class HTMLSourceCode extends TextSourceCodeBase {
14
15
  text: string;
15
16
  comments: CommentContent[];
16
17
  });
17
- /**
18
- * @property
19
- */
20
- eslintSourceCode: SourceCode;
21
18
  /**
22
19
  * @property
23
20
  */
@@ -27,6 +24,7 @@ export class HTMLSourceCode extends TextSourceCodeBase {
27
24
  */
28
25
  comments: import("@html-eslint/types").CommentContent[];
29
26
  parentsMap: Map<any, any>;
27
+ lineStartIndices: number[];
30
28
  /**
31
29
  * @param {BaseNode} node
32
30
  * @returns {[number, number]}
@@ -39,15 +37,17 @@ export class HTMLSourceCode extends TextSourceCodeBase {
39
37
  getLoc(node: BaseNode): import("@eslint/plugin-kit").SourceLocation;
40
38
  getLines(): string[];
41
39
  /**
42
- * @param {import("@eslint/core").Position} loc
43
- * @returns
40
+ * @see https://github.com/eslint/eslint/blob/f60f2764971a33e252be13e560dccf21f554dbf1/lib/languages/js/source-code/source-code.js#L745
41
+ * @param {Position} loc
42
+ * @returns {number}
44
43
  */
45
- getIndexFromLoc(loc: import("@eslint/core").Position): number;
44
+ getIndexFromLoc(loc: Position): number;
46
45
  /**
46
+ * @see https://github.com/eslint/eslint/blob/f60f2764971a33e252be13e560dccf21f554dbf1/lib/languages/js/source-code/source-code.js#L694
47
47
  * @param {number} index
48
- * @returns {import("@eslint/core").Position}
48
+ * @returns {Position}
49
49
  */
50
- getLocFromIndex(index: number): import("@eslint/core").Position;
50
+ getLocFromIndex(index: number): Position;
51
51
  getInlineConfigNodes(): import("@html-eslint/types").CommentContent[];
52
52
  getDisableDirectives(): {
53
53
  problems: {
@@ -65,6 +65,5 @@ export class HTMLSourceCode extends TextSourceCodeBase {
65
65
  getParent(node: AnyHTMLNode): any;
66
66
  }
67
67
  import { TextSourceCodeBase } from "@eslint/plugin-kit";
68
- import { SourceCode } from "eslint";
69
68
  import { Directive } from "@eslint/plugin-kit";
70
69
  //# sourceMappingURL=html-source-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-source-code.d.ts","sourceRoot":"","sources":["../../lib/languages/html-source-code.js"],"names":[],"mappings":"sBACc,OAAO,QAAQ,EAAE,GAAG,CAAC,OAAO;6BAC5B,OAAO,oBAAoB,EAAE,cAAc;4BAC3C,OAAO,oBAAoB,EAAE,aAAa;4BAC1C,OAAO,cAAc,EAAE,aAAa;6BACpC,OAAO,oBAAoB,EAAE,cAAc;0BAC3C,OAAO,oBAAoB,EAAE,WAAW;uBACxC,OAAO,UAAU,EAAE,QAAQ;AAgBzC;IACE;;OAEG;IACH,qCAFW;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAC,EAiBlE;IAbC;;OAEG;IACH,6BAAiD;IACjD;;OAEG;IACH,kCAAc;IACd;;OAEG;IACH,wDAAwB;IACxB,0BAA2B;IAG7B;;;OAGG;IACH,eAHW,QAAQ,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5B;IAED;;;OAGG;IACH,aAHW,QAAQ,GACN,OAAO,oBAAoB,EAAE,cAAc,CAIvD;IAED,qBAEC;IAED;;;OAGG;IACH,qBAHW,OAAO,cAAc,EAAE,QAAQ,UAKzC;IAED;;;OAGG;IACH,uBAHW,MAAM,GACJ,OAAO,cAAc,EAAE,QAAQ,CAI3C;IAED,sEAEC;IAED;;oBAEqB,IAAI,GAAG,MAAM;qBAAW,MAAM;iBAAO,cAAc;;;MA8CvE;IAED,mDAgDC;IAED;;;OAGG;IACH,gBAHW,WAAW,OAKrB;CACF"}
1
+ {"version":3,"file":"html-source-code.d.ts","sourceRoot":"","sources":["../../lib/languages/html-source-code.js"],"names":[],"mappings":"sBACc,OAAO,QAAQ,EAAE,GAAG,CAAC,OAAO;6BAC5B,OAAO,oBAAoB,EAAE,cAAc;4BAC3C,OAAO,oBAAoB,EAAE,aAAa;4BAC1C,OAAO,cAAc,EAAE,aAAa;6BACpC,OAAO,oBAAoB,EAAE,cAAc;0BAC3C,OAAO,oBAAoB,EAAE,WAAW;uBACxC,OAAO,cAAc,EAAE,QAAQ;uBAC/B,OAAO,UAAU,EAAE,QAAQ;AAqBzC;IACE;;OAEG;IACH,qCAFW;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAC,EAsBlE;IAjBC;;OAEG;IACH,kCAAc;IACd;;OAEG;IACH,wDAAwB;IACxB,0BAA2B;IAE3B,2BAA2B;IAS7B;;;OAGG;IACH,eAHW,QAAQ,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5B;IAED;;;OAGG;IACH,aAHW,QAAQ,GACN,OAAO,oBAAoB,EAAE,cAAc,CAIvD;IAED,qBAEC;IAGD;;;;OAIG;IACH,qBAHW,QAAQ,GACN,MAAM,CA0ClB;IAGD;;;;OAIG;IACH,uBAHW,MAAM,GACJ,QAAQ,CA8BpB;IAED,sEAEC;IAED;;oBAEqB,IAAI,GAAG,MAAM;qBAAW,MAAM;iBAAO,cAAc;;;MA8CvE;IAED,mDAgDC;IAED;;;OAGG;IACH,gBAHW,WAAW,OAKrB;CACF"}