@tony.ganchev/eslint-plugin-header 3.3.4 → 3.4.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 CHANGED
@@ -7,13 +7,17 @@
7
7
  The native ESLint 9/10 standard header-validating plugin. A zero-bloat, drop-in
8
8
  replacement for [eslint-plugin-header](https://github.com/Stuk/eslint-plugin-header)
9
9
  with first-class Flat Config & TypeScript support. Auto-fix copyright, license,
10
- and banner comments in JavaScript and TypeScript files. Supports _oxlint_.
10
+ and banner comments in JavaScript, TypeScript, CSS, HTML, and Markdown files.
11
+ Supports _oxlint_.
11
12
 
12
13
  ## Table of Contents
13
14
 
14
15
  1. [Motivation and Acknowledgements](#motivation-and-acknowledgements)
15
16
  2. [Major Consumers](#major-consumers)
16
17
  3. [Compatibility](#compatibility)
18
+ 1. [Runtimes](#runtimes)
19
+ 2. [Configuration Formats](#configuration-formats)
20
+ 3. [Languages](#languages)
17
21
  4. [Usage](#usage)
18
22
  1. [File-based Configuration](#file-based-configuration)
19
23
  2. [Inline Configuration](#inline-configuration)
@@ -24,6 +28,9 @@ and banner comments in JavaScript and TypeScript files. Supports _oxlint_.
24
28
  3. [Support for Leading Comments](#support-for-leading-comments)
25
29
  1. [Notes on Behavior](#notes-on-behavior)
26
30
  4. [Examples](#examples)
31
+ 5. [Linting CSS](#linting-css)
32
+ 6. [Linting HTML](#linting-html)
33
+ 7. [Linting Markdown](#linting-markdown)
27
34
  5. [Comparison to Alternatives](#comparison-to-alternatives)
28
35
  1. [Compared to eslint-plugin-headers](#compared-to-eslint-plugin-headers)
29
36
  1. [Health Scans](#health-scans)
@@ -88,6 +95,8 @@ consistent header structures. Notable adopters include:
88
95
     
89
96
  [![Mysten Labs](https://github.com/MystenLabs.png?size=48)](./docs/consumers.md#mysten-labs)
90
97
     
98
+ [![Suwayomi](https://github.com/Suwayomi.png?size=48)](./docs/consumers.md#suwayomi)
99
+    
91
100
  [![Wire Swiss GmbH](https://github.com/wireapp.png?size=48)](./docs/consumers.md#wire-swiss-gmbh)
92
101
     
93
102
  [![WPPConnect](https://github.com/wppconnect-team.png?size=48)](./docs/consumers.md#wppconnect)
@@ -97,17 +106,45 @@ Learn more about how these organizations use the plugin on our
97
106
 
98
107
  ## Compatibility
99
108
 
109
+ ### Runtimes
110
+
100
111
  The plugin supports **ESLint 7 / 8 / 9 / 10**. Both **flat** config and legacy,
101
112
  **hierarchical** config can be used. We have a smoke-test running to confirm the
102
- plugin works with the latest version of ESLint.
113
+ plugin works with the latest version of ESLint. Certain features such as linting
114
+ copyright headers in CSS, HTML, or Markdown rely on APIs introduced with ESLint
115
+ 9 and cannot be used with older ESLint versions.
103
116
 
104
117
  The plugin works with latest version of **oxlint** too. We have a smoke-test
105
- running to confirm the plugin works with the latest version of oxlint.
118
+ running to confirm the plugin works with the latest version of oxlint. Features
119
+ relying on the use of non-standard parsers such as linting headers in CSS, HTML,
120
+ or Markdown cannot be supported.
121
+
122
+ ### Configuration Formats
123
+
124
+ The plugin supports hierarchical and flat configuration format for ESLint as
125
+ well as the configuration format for oxlint.
106
126
 
107
127
  The NPM package provides TypeScript type definitions and can be used with
108
128
  TypeScript-based ESLint flat configuration without the need for `@ts-ignore`
109
129
  statements. Smoke tests cover this support as well.
110
130
 
131
+ ### Languages
132
+
133
+ Currently the plugin supports linting copyright headers in JavaScript,
134
+ TypeScript and their JSX / TSX flavors; CSS, HTML, and Markdown files. As
135
+ mentioned in the previous sections, not all languages are supported for oxlint
136
+ or ESLint older than 9. Refer to the table below for more details.
137
+
138
+ | Language | ESLint 7 / 8 | ESLint 9 / 10 | oxlint |
139
+ |------------|---------------|---------------|--------|
140
+ | JavaScript | ✅ Yes | ✅ Yes | ✅ Yes |
141
+ | TypeScript | ✅ Yes | ✅ Yes | ✅ Yes |
142
+ | JSX | ✅ Yes | ✅ Yes | ✅ Yes |
143
+ | TSX | ✅ Yes | ✅ Yes | ✅ Yes |
144
+ | CSS | ❌ No | ✅ Yes | ❌ No |
145
+ | HTML | ❌ No | ✅ Yes | ❌ No |
146
+ | Markdown | ❌ No | ✅ Yes | ❌ No |
147
+
111
148
  ## Usage
112
149
 
113
150
  The plugin and its _header_ rule goes through evolution of its configuration in
@@ -1146,10 +1183,55 @@ export default defineConfig([
1146
1183
  ]);
1147
1184
  ```
1148
1185
 
1186
+ ### Linting CSS
1187
+
1188
+ The rule supports validating and auto-fixing headers in CSS files. To
1189
+ use the plugin with these file types, you need to configure the official
1190
+ `@eslint/css` plugin.
1191
+
1192
+ **Note: the plugin does not support SCSS** as no current popular parser for
1193
+ ESLint supports SCSS / LESS that being a prerequisite for this plugin to be
1194
+ called. It is possible to rely on a dummy pass-through parser to ensure the SCSS
1195
+ / LESS sources simply reach the rule but as of the time of the publisihng of
1196
+ this document we have not tested this approach.
1197
+
1198
+ Back to CSS, let us use the following configuration:
1199
+
1200
+ _eslint.config.js_:
1201
+
1149
1202
  ```js
1150
- //Copyright 2017
1151
- //My Company
1152
- console.log(1)
1203
+ import header from "@tony.ganchev/eslint-plugin-header";
1204
+ import css from "@eslint/css";
1205
+
1206
+ export default [
1207
+ {
1208
+ files: ["**/*.css"],
1209
+ plugins: {
1210
+ "@tony.ganchev": header,
1211
+ css
1212
+ },
1213
+ language: "css/css",
1214
+ rules: {
1215
+ "@tony.ganchev/header": [
1216
+ "error",
1217
+ {
1218
+ header: {
1219
+ commentType: "block",
1220
+ lines: [" Copyright 2025 "]
1221
+ }
1222
+ }
1223
+ ]
1224
+ }
1225
+ }
1226
+ ];
1227
+ ```
1228
+
1229
+ ```css
1230
+ /* Copyright 2025 */
1231
+
1232
+ .foo {
1233
+ color: blue;
1234
+ }
1153
1235
  ```
1154
1236
 
1155
1237
  With more decoration:
@@ -1184,14 +1266,126 @@ export default defineConfig([
1184
1266
  ]);
1185
1267
  ```
1186
1268
 
1187
- ```js
1269
+ ```css
1188
1270
  /*************************
1189
1271
  * Copyright 2015
1190
1272
  * My Company
1191
1273
  *************************/
1192
- console.log(1);
1274
+
1275
+ .foo {
1276
+ color: blue
1277
+ }
1193
1278
  ```
1194
1279
 
1280
+ As you can expect with CSS syntax, line comments and shebangs are not supported.
1281
+ All other features of the rule remain the same.
1282
+
1283
+ ### Linting HTML
1284
+
1285
+ The rule supports linting copyright notices in HTML files. The rule works with
1286
+ the _@html-eslint/eslint-plugin_ plugin and its parser.
1287
+
1288
+ Similar to CSS, all you need to do to turn on header validation is to configure
1289
+ the _\@html-eslint/eslint-plugin_ plugin and the rule:
1290
+
1291
+ ```ts
1292
+ import header from "@tony.ganchev/eslint-plugin-header";
1293
+ import html from "@html-eslint/eslint-plugin";
1294
+
1295
+ export default [
1296
+ {
1297
+ files: ["**/*.html"],
1298
+ plugins: {
1299
+ "@tony.ganchev": header,
1300
+ html
1301
+ },
1302
+ language: "html/html",
1303
+ rules: {
1304
+ "@tony.ganchev/header": [
1305
+ "error",
1306
+ {
1307
+ header: {
1308
+ commentType: "block",
1309
+ lines: [" Copyright 2025 "]
1310
+ }
1311
+ }
1312
+ ]
1313
+ }
1314
+ }
1315
+ ];
1316
+ ```
1317
+
1318
+ ```html
1319
+ <!-- Copyright 2025 -->
1320
+
1321
+ <html>
1322
+ <body>
1323
+ <h1>Hello, world!</h1>
1324
+ <p>Lorem ipsum dolor.</p>
1325
+ </body>
1326
+ </html>
1327
+ ```
1328
+
1329
+ As with CSS, only block comments are supported - no line- or shebang comments.
1330
+
1331
+ ### Linting Markdown
1332
+
1333
+ The rule supports copyright comments in Markdown syntax in both _commonmark_ and
1334
+ _gfm_ flavors using the _\@eslint/markdown_ plugin and parser. Only HTML
1335
+ comments are supported - no anchor hacks or similar are accepted.
1336
+
1337
+ Similar to CSS, all you need to do to turn on header validation is to configure
1338
+ the _\@eslint/markdown_ plugin and the rule:
1339
+
1340
+ ```ts
1341
+ import header from "@tony.ganchev/eslint-plugin-header";
1342
+ import markdown from "@eslint/markdown";
1343
+
1344
+ export default [
1345
+ {
1346
+ files: ["**/*.md"],
1347
+ plugins: {
1348
+ "@tony.ganchev": header,
1349
+ markdown
1350
+ },
1351
+ // ... or "markdown/gfm"
1352
+ language: "markdown/commonmark",
1353
+ rules: {
1354
+ "@tony.ganchev/header": [
1355
+ "error",
1356
+ {
1357
+ header: {
1358
+ commentType: "block",
1359
+ lines: [" Copyright 2025 "]
1360
+ }
1361
+ }
1362
+ ]
1363
+ }
1364
+ }
1365
+ ];
1366
+ ```
1367
+
1368
+ ```md
1369
+ <!-- Copyright 2025 -->
1370
+
1371
+ # Title
1372
+
1373
+ ## Subtitle
1374
+
1375
+ ## Code
1376
+
1377
+ ```js
1378
+ console.log("Hello, world!");
1379
+ ```
1380
+ ```
1381
+
1382
+ Note that if you have configured header for `*.js` files, the linter would fail
1383
+ on the first line of the nested JavaScript snippet. Look up how to differentiate
1384
+ the configuration of JavaScript sources (`**/*.js`) from JavaScript snippets in
1385
+ Markdown (`**/*.md/*.js`). Same applies to `*.ts`, `*.jsx`, `*.tsx`, etc.
1386
+
1387
+ As with CSS, only block comments are supported - no line- or shebang comments.
1388
+
1195
1389
  ## Comparison to Alternatives
1196
1390
 
1197
1391
  A number of projects have been aiming to solve problems similar to
@@ -26,6 +26,10 @@
26
26
 
27
27
  const assert = require("node:assert");
28
28
 
29
+ /**
30
+ * @import { CommentType, Language } from './rules/header'
31
+ */
32
+
29
33
  /**
30
34
  * Parses a line or block comment and returns the type of comment and an array
31
35
  * of content lines.
@@ -33,24 +37,34 @@ const assert = require("node:assert");
33
37
  * This is a really simple and dumb parser, that looks just for a
34
38
  * single kind of comment. It won't detect multiple block comments.
35
39
  * @param {string} commentText Content to parse.
36
- * @returns {[import("./rules/header").CommentType, string[]]} Comment type and
37
- * comment content broken into lines.
40
+ * @param {Language} language The language
41
+ * configuration.
42
+ * @returns {[CommentType, string[]]} Comment type and
43
+ * content.
38
44
  * @throws {Error} If `commentText` starts with an unrecognized comment token.
39
45
  */
40
- module.exports = function commentParser(commentText) {
46
+ module.exports = function commentParser(commentText, language) {
41
47
  assert.strictEqual(typeof commentText, "string");
48
+ assert.ok(language);
49
+
42
50
  const text = commentText.trim();
51
+ const lc = language.lineComment;
52
+ const bc = language.blockComment;
43
53
 
44
- if (text.startsWith("//")) {
54
+ if (lc && text.startsWith(lc.startDelimiter)) {
45
55
  return [
46
56
  "line",
47
- text.split(/\r?\n/).map((line) => line.substring(2))
57
+ text.split(/\r?\n/).map((line) => line.substring(lc.startDelimiter.length))
58
+ ];
59
+ } else if (bc && text.startsWith(bc.startDelimiter) && text.endsWith(bc.endDelimiter)) {
60
+ return [
61
+ "block",
62
+ text.substring(bc.startDelimiter.length, text.length - bc.endDelimiter.length).split(/\r?\n/)
48
63
  ];
49
- } else if (text.startsWith("/*") && text.endsWith("*/")) {
50
- return ["block", text.substring(2, text.length - 2).split(/\r?\n/)];
51
64
  } else {
52
65
  throw new Error(
53
- "Could not parse comment file: the file must contain either just line comments (//) or a single block " +
54
- "comment (/* ... */)");
66
+ "Could not parse comment file: the file must contain a comment " +
67
+ "that matches the supplied language delimiters."
68
+ );
55
69
  }
56
70
  };