@herb-tools/linter 0.4.3 → 0.5.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 (181) hide show
  1. package/README.md +216 -19
  2. package/dist/herb-lint.js +420 -205
  3. package/dist/herb-lint.js.map +1 -1
  4. package/dist/index.cjs +61 -43
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.js +61 -43
  7. package/dist/index.js.map +1 -1
  8. package/dist/package.json +4 -4
  9. package/dist/src/cli/argument-parser.js +28 -18
  10. package/dist/src/cli/argument-parser.js.map +1 -1
  11. package/dist/src/cli/file-processor.js +19 -13
  12. package/dist/src/cli/file-processor.js.map +1 -1
  13. package/dist/src/cli/formatters/detailed-formatter.js +9 -9
  14. package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
  15. package/dist/src/cli/formatters/github-actions-formatter.js +50 -0
  16. package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -0
  17. package/dist/src/cli/formatters/index.js +2 -0
  18. package/dist/src/cli/formatters/index.js.map +1 -1
  19. package/dist/src/cli/formatters/json-formatter.js +58 -0
  20. package/dist/src/cli/formatters/json-formatter.js.map +1 -0
  21. package/dist/src/cli/formatters/simple-formatter.js +15 -15
  22. package/dist/src/cli/formatters/simple-formatter.js.map +1 -1
  23. package/dist/src/cli/output-manager.js +120 -0
  24. package/dist/src/cli/output-manager.js.map +1 -0
  25. package/dist/src/cli/summary-reporter.js +22 -22
  26. package/dist/src/cli/summary-reporter.js.map +1 -1
  27. package/dist/src/cli.js +41 -26
  28. package/dist/src/cli.js.map +1 -1
  29. package/dist/src/default-rules.js +2 -0
  30. package/dist/src/default-rules.js.map +1 -1
  31. package/dist/src/linter.js +1 -1
  32. package/dist/src/linter.js.map +1 -1
  33. package/dist/src/rules/erb-no-empty-tags.js +2 -2
  34. package/dist/src/rules/erb-no-empty-tags.js.map +1 -1
  35. package/dist/src/rules/erb-no-output-control-flow.js +2 -2
  36. package/dist/src/rules/erb-no-output-control-flow.js.map +1 -1
  37. package/dist/src/rules/erb-prefer-image-tag-helper.js +2 -2
  38. package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
  39. package/dist/src/rules/erb-require-whitespace-inside-tags.js +2 -2
  40. package/dist/src/rules/erb-require-whitespace-inside-tags.js.map +1 -1
  41. package/dist/src/rules/erb-requires-trailing-newline.js.map +1 -1
  42. package/dist/src/rules/html-anchor-require-href.js +2 -2
  43. package/dist/src/rules/html-anchor-require-href.js.map +1 -1
  44. package/dist/src/rules/html-aria-attribute-must-be-valid.js +2 -2
  45. package/dist/src/rules/html-aria-attribute-must-be-valid.js.map +1 -1
  46. package/dist/src/rules/html-aria-level-must-be-valid.js +2 -2
  47. package/dist/src/rules/html-aria-level-must-be-valid.js.map +1 -1
  48. package/dist/src/rules/html-aria-role-heading-requires-level.js +2 -2
  49. package/dist/src/rules/html-aria-role-heading-requires-level.js.map +1 -1
  50. package/dist/src/rules/html-aria-role-must-be-valid.js +2 -2
  51. package/dist/src/rules/html-aria-role-must-be-valid.js.map +1 -1
  52. package/dist/src/rules/html-attribute-double-quotes.js +2 -2
  53. package/dist/src/rules/html-attribute-double-quotes.js.map +1 -1
  54. package/dist/src/rules/html-attribute-values-require-quotes.js +2 -2
  55. package/dist/src/rules/html-attribute-values-require-quotes.js.map +1 -1
  56. package/dist/src/rules/html-boolean-attributes-no-value.js +2 -2
  57. package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
  58. package/dist/src/rules/html-img-require-alt.js +2 -2
  59. package/dist/src/rules/html-img-require-alt.js.map +1 -1
  60. package/dist/src/rules/html-no-block-inside-inline.js +4 -4
  61. package/dist/src/rules/html-no-block-inside-inline.js.map +1 -1
  62. package/dist/src/rules/html-no-duplicate-attributes.js +2 -2
  63. package/dist/src/rules/html-no-duplicate-attributes.js.map +1 -1
  64. package/dist/src/rules/html-no-duplicate-ids.js +2 -2
  65. package/dist/src/rules/html-no-duplicate-ids.js.map +1 -1
  66. package/dist/src/rules/html-no-empty-headings.js +2 -2
  67. package/dist/src/rules/html-no-empty-headings.js.map +1 -1
  68. package/dist/src/rules/html-no-nested-links.js +2 -2
  69. package/dist/src/rules/html-no-nested-links.js.map +1 -1
  70. package/dist/src/rules/html-tag-name-lowercase.js +2 -2
  71. package/dist/src/rules/html-tag-name-lowercase.js.map +1 -1
  72. package/dist/src/rules/parser-no-errors.js +18 -0
  73. package/dist/src/rules/parser-no-errors.js.map +1 -0
  74. package/dist/src/rules/svg-tag-name-capitalization.js +2 -2
  75. package/dist/src/rules/svg-tag-name-capitalization.js.map +1 -1
  76. package/dist/tsconfig.tsbuildinfo +1 -1
  77. package/dist/types/cli/argument-parser.d.ts +2 -1
  78. package/dist/types/cli/file-processor.d.ts +6 -5
  79. package/dist/types/cli/formatters/base-formatter.d.ts +2 -2
  80. package/dist/types/cli/formatters/detailed-formatter.d.ts +2 -2
  81. package/dist/types/cli/formatters/github-actions-formatter.d.ts +12 -0
  82. package/dist/types/cli/formatters/index.d.ts +2 -0
  83. package/dist/types/cli/formatters/json-formatter.d.ts +42 -0
  84. package/dist/types/cli/formatters/simple-formatter.d.ts +2 -2
  85. package/dist/types/cli/output-manager.d.ts +31 -0
  86. package/dist/types/cli/summary-reporter.d.ts +3 -3
  87. package/dist/types/cli.d.ts +3 -1
  88. package/dist/types/rules/erb-no-empty-tags.d.ts +2 -2
  89. package/dist/types/rules/erb-no-output-control-flow.d.ts +2 -2
  90. package/dist/types/rules/erb-prefer-image-tag-helper.d.ts +2 -2
  91. package/dist/types/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
  92. package/dist/types/rules/html-anchor-require-href.d.ts +2 -2
  93. package/dist/types/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
  94. package/dist/types/rules/html-aria-level-must-be-valid.d.ts +2 -2
  95. package/dist/types/rules/html-aria-role-heading-requires-level.d.ts +2 -2
  96. package/dist/types/rules/html-aria-role-must-be-valid.d.ts +2 -2
  97. package/dist/types/rules/html-attribute-double-quotes.d.ts +2 -2
  98. package/dist/types/rules/html-attribute-values-require-quotes.d.ts +2 -2
  99. package/dist/types/rules/html-boolean-attributes-no-value.d.ts +2 -2
  100. package/dist/types/rules/html-img-require-alt.d.ts +2 -2
  101. package/dist/types/rules/html-no-block-inside-inline.d.ts +2 -2
  102. package/dist/types/rules/html-no-duplicate-attributes.d.ts +2 -2
  103. package/dist/types/rules/html-no-duplicate-ids.d.ts +2 -2
  104. package/dist/types/rules/html-no-empty-headings.d.ts +2 -2
  105. package/dist/types/rules/html-no-nested-links.d.ts +2 -2
  106. package/dist/types/rules/html-tag-name-lowercase.d.ts +2 -2
  107. package/dist/types/rules/parser-no-errors.d.ts +8 -0
  108. package/dist/types/rules/svg-tag-name-capitalization.d.ts +2 -2
  109. package/dist/types/src/cli/argument-parser.d.ts +2 -1
  110. package/dist/types/src/cli/file-processor.d.ts +6 -5
  111. package/dist/types/src/cli/formatters/base-formatter.d.ts +2 -2
  112. package/dist/types/src/cli/formatters/detailed-formatter.d.ts +2 -2
  113. package/dist/types/src/cli/formatters/github-actions-formatter.d.ts +12 -0
  114. package/dist/types/src/cli/formatters/index.d.ts +2 -0
  115. package/dist/types/src/cli/formatters/json-formatter.d.ts +42 -0
  116. package/dist/types/src/cli/formatters/simple-formatter.d.ts +2 -2
  117. package/dist/types/src/cli/output-manager.d.ts +31 -0
  118. package/dist/types/src/cli/summary-reporter.d.ts +3 -3
  119. package/dist/types/src/cli.d.ts +3 -1
  120. package/dist/types/src/rules/erb-no-empty-tags.d.ts +2 -2
  121. package/dist/types/src/rules/erb-no-output-control-flow.d.ts +2 -2
  122. package/dist/types/src/rules/erb-prefer-image-tag-helper.d.ts +2 -2
  123. package/dist/types/src/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
  124. package/dist/types/src/rules/html-anchor-require-href.d.ts +2 -2
  125. package/dist/types/src/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
  126. package/dist/types/src/rules/html-aria-level-must-be-valid.d.ts +2 -2
  127. package/dist/types/src/rules/html-aria-role-heading-requires-level.d.ts +2 -2
  128. package/dist/types/src/rules/html-aria-role-must-be-valid.d.ts +2 -2
  129. package/dist/types/src/rules/html-attribute-double-quotes.d.ts +2 -2
  130. package/dist/types/src/rules/html-attribute-values-require-quotes.d.ts +2 -2
  131. package/dist/types/src/rules/html-boolean-attributes-no-value.d.ts +2 -2
  132. package/dist/types/src/rules/html-img-require-alt.d.ts +2 -2
  133. package/dist/types/src/rules/html-no-block-inside-inline.d.ts +2 -2
  134. package/dist/types/src/rules/html-no-duplicate-attributes.d.ts +2 -2
  135. package/dist/types/src/rules/html-no-duplicate-ids.d.ts +2 -2
  136. package/dist/types/src/rules/html-no-empty-headings.d.ts +2 -2
  137. package/dist/types/src/rules/html-no-nested-links.d.ts +2 -2
  138. package/dist/types/src/rules/html-tag-name-lowercase.d.ts +2 -2
  139. package/dist/types/src/rules/parser-no-errors.d.ts +8 -0
  140. package/dist/types/src/rules/svg-tag-name-capitalization.d.ts +2 -2
  141. package/dist/types/src/types.d.ts +3 -3
  142. package/dist/types/types.d.ts +3 -3
  143. package/docs/rules/README.md +1 -0
  144. package/docs/rules/parser-no-errors.md +84 -0
  145. package/package.json +4 -4
  146. package/src/cli/argument-parser.ts +33 -19
  147. package/src/cli/file-processor.ts +25 -17
  148. package/src/cli/formatters/base-formatter.ts +2 -2
  149. package/src/cli/formatters/detailed-formatter.ts +9 -9
  150. package/src/cli/formatters/github-actions-formatter.ts +70 -0
  151. package/src/cli/formatters/index.ts +2 -0
  152. package/src/cli/formatters/json-formatter.ts +107 -0
  153. package/src/cli/formatters/simple-formatter.ts +15 -15
  154. package/src/cli/output-manager.ts +143 -0
  155. package/src/cli/summary-reporter.ts +24 -24
  156. package/src/cli.ts +48 -31
  157. package/src/default-rules.ts +2 -0
  158. package/src/linter.ts +1 -1
  159. package/src/rules/erb-no-empty-tags.ts +3 -3
  160. package/src/rules/erb-no-output-control-flow.ts +3 -3
  161. package/src/rules/erb-prefer-image-tag-helper.ts +3 -3
  162. package/src/rules/erb-require-whitespace-inside-tags.ts +3 -3
  163. package/src/rules/erb-requires-trailing-newline.ts +2 -0
  164. package/src/rules/html-anchor-require-href.ts +3 -3
  165. package/src/rules/html-aria-attribute-must-be-valid.ts +3 -3
  166. package/src/rules/html-aria-level-must-be-valid.ts +3 -3
  167. package/src/rules/html-aria-role-heading-requires-level.ts +3 -3
  168. package/src/rules/html-aria-role-must-be-valid.ts +3 -3
  169. package/src/rules/html-attribute-double-quotes.ts +3 -3
  170. package/src/rules/html-attribute-values-require-quotes.ts +3 -3
  171. package/src/rules/html-boolean-attributes-no-value.ts +3 -3
  172. package/src/rules/html-img-require-alt.ts +3 -3
  173. package/src/rules/html-no-block-inside-inline.ts +5 -5
  174. package/src/rules/html-no-duplicate-attributes.ts +3 -3
  175. package/src/rules/html-no-duplicate-ids.ts +3 -3
  176. package/src/rules/html-no-empty-headings.ts +3 -3
  177. package/src/rules/html-no-nested-links.ts +3 -3
  178. package/src/rules/html-tag-name-lowercase.ts +3 -3
  179. package/src/rules/parser-no-errors.ts +25 -0
  180. package/src/rules/svg-tag-name-capitalization.ts +3 -3
  181. package/src/types.ts +3 -3
package/README.md CHANGED
@@ -6,41 +6,238 @@
6
6
 
7
7
  The Herb Linter provides comprehensive HTML+ERB validation with a set of configurable rules to enforce best practices and catch common errors.
8
8
 
9
+ ## Installation
10
+
11
+ ### Global Installation
12
+
13
+ :::code-group
14
+
15
+ ```shell [npm]
16
+ npm install -g @herb-tools/linter
17
+ ```
18
+
19
+ ```shell [pnpm]
20
+ pnpm add -g @herb-tools/linter
21
+ ```
22
+
23
+ ```shell [yarn]
24
+ yarn global add @herb-tools/linter
25
+ ```
26
+
27
+ ```shell [bun]
28
+ bun add -g @herb-tools/linter
29
+ ```
30
+
31
+ :::
32
+
33
+ Then run directly:
34
+ ```bash
35
+ herb-lint template.html.erb
36
+ ```
37
+
38
+ ### One-time Usage
39
+ For occasional use without installing:
40
+ ```bash
41
+ npx @herb-tools/linter template.html.erb
42
+ ```
43
+
44
+ ### Project Installation
45
+
46
+ :::code-group
47
+
48
+ ```shell [npm]
49
+ npm add -D @herb-tools/linter
50
+ ```
51
+
52
+ ```shell [pnpm]
53
+ pnpm add -D @herb-tools/linter
54
+ ```
55
+
56
+ ```shell [yarn]
57
+ yarn add -D @herb-tools/linter
58
+ ```
59
+
60
+ ```shell [bun]
61
+ bun add -D @herb-tools/linter
62
+ ```
63
+
64
+ :::
65
+
66
+ After installing as a dev dependency, add a lint NPM script to your `package.json`:
67
+ ```json
68
+ {
69
+ "scripts": {
70
+ "herb:lint": "herb-lint '**/*.html.erb'"
71
+ }
72
+ }
73
+ ```
74
+
75
+ Then run the scripts:
76
+
77
+ :::code-group
78
+
79
+ ```shell [npm]
80
+ npm run herb:lint
81
+ ```
82
+
83
+ ```shell [pnpm]
84
+ pnpm herb:lint
85
+ ```
86
+
87
+ ```shell [yarn]
88
+ yarn herb:lint
89
+ ```
90
+
91
+ ```shell [bun]
92
+ bun run herb:lint
93
+ ```
94
+
95
+ :::
96
+
9
97
  ## Usage
10
98
 
11
99
  ### Command Line
100
+
101
+ Basic usage:
12
102
  ```bash
13
103
  npx @herb-tools/linter template.html.erb
104
+ npx @herb-tools/linter "**/*.html.erb"
105
+ npx @herb-tools/linter app/
14
106
  ```
15
107
 
16
- ### Language Server Integration
108
+ #### Options
17
109
 
18
- The linter is automatically integrated into the [Herb Language Server](https://herb-tools.dev/projects/language-server), providing real-time validation in supported editors like VS Code, Zed, and Neovim.
110
+ **Output Format:**
111
+ ```bash
112
+ # Use detailed output (default)
113
+ npx @herb-tools/linter template.html.erb --format detailed
114
+
115
+ # Use simple output format
116
+ npx @herb-tools/linter template.html.erb --simple
117
+ # or
118
+ npx @herb-tools/linter template.html.erb --format simple
119
+
120
+ # Use JSON output format
121
+ npx @herb-tools/linter template.html.erb --json
122
+ # or
123
+ npx @herb-tools/linter template.html.erb --format json
124
+
125
+ # Use GitHub Actions output format
126
+ npx @herb-tools/linter template.html.erb --github
127
+ # or
128
+ npx @herb-tools/linter template.html.erb --format github
129
+ ```
130
+
131
+ **Display Options:**
132
+ ```bash
133
+ # Disable colored output
134
+ npx @herb-tools/linter template.html.erb --no-color
135
+
136
+ # Set syntax highlighting theme
137
+ npx @herb-tools/linter template.html.erb --theme github-dark
138
+
139
+ # Disable timing information
140
+ npx @herb-tools/linter template.html.erb --no-timing
141
+
142
+ # Disable line wrapping
143
+ npx @herb-tools/linter template.html.erb --no-wrap-lines
144
+
145
+ # Enable line truncation (mutually exclusive with line wrapping)
146
+ npx @herb-tools/linter template.html.erb --truncate-lines --no-wrap-lines
147
+ ```
19
148
 
20
- ## Configuration
149
+ **Help and Version:**
150
+ ```bash
151
+ # Show help
152
+ npx @herb-tools/linter --help
153
+
154
+ # Show version information
155
+ npx @herb-tools/linter --version
156
+ ```
157
+
158
+ #### GitHub Actions Output Format
159
+
160
+ The linter supports GitHub Actions annotation format with the `--github` flag, which outputs errors and warnings in a format that GitHub Actions can parse to create inline annotations in pull requests:
161
+
162
+ ```bash
163
+ npx @herb-tools/linter "**/*.html.erb" --github
164
+ ```
165
+
166
+ Example output:
167
+ ```
168
+ ::error file=template.html.erb,line=5,col=5::File must end with trailing newline [erb-requires-trailing-newline]
169
+ ::warning file=template.html.erb,line=3,col=10::Consider using semantic HTML tags [html-semantic-tags]
170
+ ```
21
171
 
22
- By default, all rules are enabled. You can customize the rules by passing a custom set to the Linter constructor:
172
+ This format is ideal for CI/CD workflows in GitHub Actions:
23
173
 
24
- ```typescript
25
- import { Herb } from "@herb-tools/node-wasm"
26
- import { Linter, HTMLTagNameLowercaseRule } from "@herb-tools/linter"
174
+ ```yaml [.github/workflows/herb-lint.yml]
175
+ name: Herb Lint
176
+ on: [push, pull_request]
27
177
 
28
- await Herb.load()
178
+ jobs:
179
+ lint:
180
+ runs-on: ubuntu-latest
181
+ steps:
182
+ - uses: actions/checkout@v4
183
+ - uses: actions/setup-node@v4
184
+ - run: npx @herb-tools/linter "**/*.html.erb" --github
185
+ ```
29
186
 
30
- // Only run specific rules
31
- const linter = new Linter(Herb, [HTMLTagNameLowercaseRule])
187
+ #### JSON Output Format
32
188
 
33
- // Run with no rules (disabled)
34
- const linter = new Linter(Herb, [])
189
+ The linter supports structured JSON output with the `--json` flag, useful for programmatic consumption:
35
190
 
36
- // Lint source code
37
- const result = linter.lint(sourceCode)
191
+ ```bash
192
+ npx @herb-tools/linter template.html.erb --json
38
193
  ```
39
194
 
40
- The Linter supports three types of rules:
195
+ <details>
196
+ <summary>Example output:</summary>
197
+
198
+ ```json
199
+ {
200
+ "offenses": [
201
+ {
202
+ "filename": "template.html.erb",
203
+ "message": "File must end with trailing newline",
204
+ "location": {
205
+ "start": { "line": 1, "column": 21 },
206
+ "end": { "line": 1, "column": 22 }
207
+ },
208
+ "severity": "error",
209
+ "code": "erb-requires-trailing-newline",
210
+ "source": "Herb Linter"
211
+ }
212
+ ],
213
+ "summary": {
214
+ "filesChecked": 1,
215
+ "filesWithOffenses": 1,
216
+ "totalErrors": 1,
217
+ "totalWarnings": 0,
218
+ "totalOffenses": 1,
219
+ "ruleCount": 21
220
+ },
221
+ "timing": {
222
+ "startTime": "2025-08-14T16:00:48.845Z",
223
+ "duration": 27
224
+ },
225
+ "completed": true,
226
+ "clean": false,
227
+ "message": null
228
+ }
229
+ ```
41
230
 
42
- - **Parser/AST Rules**: Semantic validation using the parsed document tree
43
- - **Lexer Rules**: Token-based validation using the lexer output
44
- - **Source Rules**: Raw text validation using the original source code
231
+ </details>
45
232
 
46
- Each rule type uses its own visitor pattern for clean, extensible implementations.
233
+ JSON output fields:
234
+ - `offenses`: Array of linting offenses with location and severity
235
+ - `summary`: Statistics about the linting run (null on errors)
236
+ - `timing`: Timing information with ISO timestamp (null with `--no-timing`)
237
+ - `completed`: Whether the linter ran successfully on files
238
+ - `clean`: Whether there were no offenses (null when `completed=false`)
239
+ - `message`: Error or informational message (null on success)
240
+
241
+ ### Language Server Integration
242
+
243
+ The linter is automatically integrated into the [Herb Language Server](https://herb-tools.dev/projects/language-server), providing real-time validation in supported editors like VS Code, Zed, and Neovim.