@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.
- package/README.md +216 -19
- package/dist/herb-lint.js +420 -205
- package/dist/herb-lint.js.map +1 -1
- package/dist/index.cjs +61 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +61 -43
- package/dist/index.js.map +1 -1
- package/dist/package.json +4 -4
- package/dist/src/cli/argument-parser.js +28 -18
- package/dist/src/cli/argument-parser.js.map +1 -1
- package/dist/src/cli/file-processor.js +19 -13
- package/dist/src/cli/file-processor.js.map +1 -1
- package/dist/src/cli/formatters/detailed-formatter.js +9 -9
- package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
- package/dist/src/cli/formatters/github-actions-formatter.js +50 -0
- package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -0
- package/dist/src/cli/formatters/index.js +2 -0
- package/dist/src/cli/formatters/index.js.map +1 -1
- package/dist/src/cli/formatters/json-formatter.js +58 -0
- package/dist/src/cli/formatters/json-formatter.js.map +1 -0
- package/dist/src/cli/formatters/simple-formatter.js +15 -15
- package/dist/src/cli/formatters/simple-formatter.js.map +1 -1
- package/dist/src/cli/output-manager.js +120 -0
- package/dist/src/cli/output-manager.js.map +1 -0
- package/dist/src/cli/summary-reporter.js +22 -22
- package/dist/src/cli/summary-reporter.js.map +1 -1
- package/dist/src/cli.js +41 -26
- package/dist/src/cli.js.map +1 -1
- package/dist/src/default-rules.js +2 -0
- package/dist/src/default-rules.js.map +1 -1
- package/dist/src/linter.js +1 -1
- package/dist/src/linter.js.map +1 -1
- package/dist/src/rules/erb-no-empty-tags.js +2 -2
- package/dist/src/rules/erb-no-empty-tags.js.map +1 -1
- package/dist/src/rules/erb-no-output-control-flow.js +2 -2
- package/dist/src/rules/erb-no-output-control-flow.js.map +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js +2 -2
- package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
- package/dist/src/rules/erb-require-whitespace-inside-tags.js +2 -2
- package/dist/src/rules/erb-require-whitespace-inside-tags.js.map +1 -1
- package/dist/src/rules/erb-requires-trailing-newline.js.map +1 -1
- package/dist/src/rules/html-anchor-require-href.js +2 -2
- package/dist/src/rules/html-anchor-require-href.js.map +1 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-attribute-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-level-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-level-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js +2 -2
- package/dist/src/rules/html-aria-role-heading-requires-level.js.map +1 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js +2 -2
- package/dist/src/rules/html-aria-role-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-attribute-double-quotes.js +2 -2
- package/dist/src/rules/html-attribute-double-quotes.js.map +1 -1
- package/dist/src/rules/html-attribute-values-require-quotes.js +2 -2
- package/dist/src/rules/html-attribute-values-require-quotes.js.map +1 -1
- package/dist/src/rules/html-boolean-attributes-no-value.js +2 -2
- package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
- package/dist/src/rules/html-img-require-alt.js +2 -2
- package/dist/src/rules/html-img-require-alt.js.map +1 -1
- package/dist/src/rules/html-no-block-inside-inline.js +4 -4
- package/dist/src/rules/html-no-block-inside-inline.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-attributes.js +2 -2
- package/dist/src/rules/html-no-duplicate-attributes.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-ids.js +2 -2
- package/dist/src/rules/html-no-duplicate-ids.js.map +1 -1
- package/dist/src/rules/html-no-empty-headings.js +2 -2
- package/dist/src/rules/html-no-empty-headings.js.map +1 -1
- package/dist/src/rules/html-no-nested-links.js +2 -2
- package/dist/src/rules/html-no-nested-links.js.map +1 -1
- package/dist/src/rules/html-tag-name-lowercase.js +2 -2
- package/dist/src/rules/html-tag-name-lowercase.js.map +1 -1
- package/dist/src/rules/parser-no-errors.js +18 -0
- package/dist/src/rules/parser-no-errors.js.map +1 -0
- package/dist/src/rules/svg-tag-name-capitalization.js +2 -2
- package/dist/src/rules/svg-tag-name-capitalization.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/cli/argument-parser.d.ts +2 -1
- package/dist/types/cli/file-processor.d.ts +6 -5
- package/dist/types/cli/formatters/base-formatter.d.ts +2 -2
- package/dist/types/cli/formatters/detailed-formatter.d.ts +2 -2
- package/dist/types/cli/formatters/github-actions-formatter.d.ts +12 -0
- package/dist/types/cli/formatters/index.d.ts +2 -0
- package/dist/types/cli/formatters/json-formatter.d.ts +42 -0
- package/dist/types/cli/formatters/simple-formatter.d.ts +2 -2
- package/dist/types/cli/output-manager.d.ts +31 -0
- package/dist/types/cli/summary-reporter.d.ts +3 -3
- package/dist/types/cli.d.ts +3 -1
- package/dist/types/rules/erb-no-empty-tags.d.ts +2 -2
- package/dist/types/rules/erb-no-output-control-flow.d.ts +2 -2
- package/dist/types/rules/erb-prefer-image-tag-helper.d.ts +2 -2
- package/dist/types/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
- package/dist/types/rules/html-anchor-require-href.d.ts +2 -2
- package/dist/types/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-aria-level-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-aria-role-heading-requires-level.d.ts +2 -2
- package/dist/types/rules/html-aria-role-must-be-valid.d.ts +2 -2
- package/dist/types/rules/html-attribute-double-quotes.d.ts +2 -2
- package/dist/types/rules/html-attribute-values-require-quotes.d.ts +2 -2
- package/dist/types/rules/html-boolean-attributes-no-value.d.ts +2 -2
- package/dist/types/rules/html-img-require-alt.d.ts +2 -2
- package/dist/types/rules/html-no-block-inside-inline.d.ts +2 -2
- package/dist/types/rules/html-no-duplicate-attributes.d.ts +2 -2
- package/dist/types/rules/html-no-duplicate-ids.d.ts +2 -2
- package/dist/types/rules/html-no-empty-headings.d.ts +2 -2
- package/dist/types/rules/html-no-nested-links.d.ts +2 -2
- package/dist/types/rules/html-tag-name-lowercase.d.ts +2 -2
- package/dist/types/rules/parser-no-errors.d.ts +8 -0
- package/dist/types/rules/svg-tag-name-capitalization.d.ts +2 -2
- package/dist/types/src/cli/argument-parser.d.ts +2 -1
- package/dist/types/src/cli/file-processor.d.ts +6 -5
- package/dist/types/src/cli/formatters/base-formatter.d.ts +2 -2
- package/dist/types/src/cli/formatters/detailed-formatter.d.ts +2 -2
- package/dist/types/src/cli/formatters/github-actions-formatter.d.ts +12 -0
- package/dist/types/src/cli/formatters/index.d.ts +2 -0
- package/dist/types/src/cli/formatters/json-formatter.d.ts +42 -0
- package/dist/types/src/cli/formatters/simple-formatter.d.ts +2 -2
- package/dist/types/src/cli/output-manager.d.ts +31 -0
- package/dist/types/src/cli/summary-reporter.d.ts +3 -3
- package/dist/types/src/cli.d.ts +3 -1
- package/dist/types/src/rules/erb-no-empty-tags.d.ts +2 -2
- package/dist/types/src/rules/erb-no-output-control-flow.d.ts +2 -2
- package/dist/types/src/rules/erb-prefer-image-tag-helper.d.ts +2 -2
- package/dist/types/src/rules/erb-require-whitespace-inside-tags.d.ts +2 -2
- package/dist/types/src/rules/html-anchor-require-href.d.ts +2 -2
- package/dist/types/src/rules/html-aria-attribute-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-aria-level-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-aria-role-heading-requires-level.d.ts +2 -2
- package/dist/types/src/rules/html-aria-role-must-be-valid.d.ts +2 -2
- package/dist/types/src/rules/html-attribute-double-quotes.d.ts +2 -2
- package/dist/types/src/rules/html-attribute-values-require-quotes.d.ts +2 -2
- package/dist/types/src/rules/html-boolean-attributes-no-value.d.ts +2 -2
- package/dist/types/src/rules/html-img-require-alt.d.ts +2 -2
- package/dist/types/src/rules/html-no-block-inside-inline.d.ts +2 -2
- package/dist/types/src/rules/html-no-duplicate-attributes.d.ts +2 -2
- package/dist/types/src/rules/html-no-duplicate-ids.d.ts +2 -2
- package/dist/types/src/rules/html-no-empty-headings.d.ts +2 -2
- package/dist/types/src/rules/html-no-nested-links.d.ts +2 -2
- package/dist/types/src/rules/html-tag-name-lowercase.d.ts +2 -2
- package/dist/types/src/rules/parser-no-errors.d.ts +8 -0
- package/dist/types/src/rules/svg-tag-name-capitalization.d.ts +2 -2
- package/dist/types/src/types.d.ts +3 -3
- package/dist/types/types.d.ts +3 -3
- package/docs/rules/README.md +1 -0
- package/docs/rules/parser-no-errors.md +84 -0
- package/package.json +4 -4
- package/src/cli/argument-parser.ts +33 -19
- package/src/cli/file-processor.ts +25 -17
- package/src/cli/formatters/base-formatter.ts +2 -2
- package/src/cli/formatters/detailed-formatter.ts +9 -9
- package/src/cli/formatters/github-actions-formatter.ts +70 -0
- package/src/cli/formatters/index.ts +2 -0
- package/src/cli/formatters/json-formatter.ts +107 -0
- package/src/cli/formatters/simple-formatter.ts +15 -15
- package/src/cli/output-manager.ts +143 -0
- package/src/cli/summary-reporter.ts +24 -24
- package/src/cli.ts +48 -31
- package/src/default-rules.ts +2 -0
- package/src/linter.ts +1 -1
- package/src/rules/erb-no-empty-tags.ts +3 -3
- package/src/rules/erb-no-output-control-flow.ts +3 -3
- package/src/rules/erb-prefer-image-tag-helper.ts +3 -3
- package/src/rules/erb-require-whitespace-inside-tags.ts +3 -3
- package/src/rules/erb-requires-trailing-newline.ts +2 -0
- package/src/rules/html-anchor-require-href.ts +3 -3
- package/src/rules/html-aria-attribute-must-be-valid.ts +3 -3
- package/src/rules/html-aria-level-must-be-valid.ts +3 -3
- package/src/rules/html-aria-role-heading-requires-level.ts +3 -3
- package/src/rules/html-aria-role-must-be-valid.ts +3 -3
- package/src/rules/html-attribute-double-quotes.ts +3 -3
- package/src/rules/html-attribute-values-require-quotes.ts +3 -3
- package/src/rules/html-boolean-attributes-no-value.ts +3 -3
- package/src/rules/html-img-require-alt.ts +3 -3
- package/src/rules/html-no-block-inside-inline.ts +5 -5
- package/src/rules/html-no-duplicate-attributes.ts +3 -3
- package/src/rules/html-no-duplicate-ids.ts +3 -3
- package/src/rules/html-no-empty-headings.ts +3 -3
- package/src/rules/html-no-nested-links.ts +3 -3
- package/src/rules/html-tag-name-lowercase.ts +3 -3
- package/src/rules/parser-no-errors.ts +25 -0
- package/src/rules/svg-tag-name-capitalization.ts +3 -3
- 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
|
-
|
|
108
|
+
#### Options
|
|
17
109
|
|
|
18
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
+
This format is ideal for CI/CD workflows in GitHub Actions:
|
|
23
173
|
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
174
|
+
```yaml [.github/workflows/herb-lint.yml]
|
|
175
|
+
name: Herb Lint
|
|
176
|
+
on: [push, pull_request]
|
|
27
177
|
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
const linter = new Linter(Herb, [HTMLTagNameLowercaseRule])
|
|
187
|
+
#### JSON Output Format
|
|
32
188
|
|
|
33
|
-
|
|
34
|
-
const linter = new Linter(Herb, [])
|
|
189
|
+
The linter supports structured JSON output with the `--json` flag, useful for programmatic consumption:
|
|
35
190
|
|
|
36
|
-
|
|
37
|
-
|
|
191
|
+
```bash
|
|
192
|
+
npx @herb-tools/linter template.html.erb --json
|
|
38
193
|
```
|
|
39
194
|
|
|
40
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|