eslint-plugin-greasemonkey 1.8.2 → 1.8.4

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
@@ -6,7 +6,7 @@
6
6
  <img alt="[Latest Build]" src="https://img.shields.io/npm/v/eslint-plugin-greasemonkey?logo=icinga&style=for-the-badge&label=Latest%20Build&color=32fcee"></a>
7
7
  <a href="#license">
8
8
  <img alt="[License: MIT]" src="https://img.shields.io/badge/License-MIT-f1f20a.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
9
- <a>
9
+ <a target="_blank" href="https://getnpmstats.com/?package=eslint-plugin-greasemonkey&range=last-year&interval=monthly">
10
10
  <img src="https://img.shields.io/npm/dm/eslint-plugin-greasemonkey?style=for-the-badge&logo=npm&color=black"></a>
11
11
  <a target="_blank" href="https://eslint.org/">
12
12
  <img alt="[Requires ESLint >=9.0.0]" src="https://img.shields.io/badge/Requires-ESLint_%3E%3D9.0.0-4B32C3?style=for-the-badge&logo=eslint"></a>
@@ -52,7 +52,7 @@ export default [
52
52
  ]
53
53
  ```
54
54
 
55
- Available bundles: `recommended`, `strict`, `problem`, `tampermonkey`, `violentmonkey`, `greasemonkey`, `scriptcat`, `adguard`
55
+ Available bundles: `recommended`, `strict` (everything), `problem` (deterministic bugs only), `tampermonkey`, `violentmonkey`, `greasemonkey`, `scriptcat`, `adguard`
56
56
 
57
57
  **Note:** Rule config is either a severity string (`'off'`, `'warn'`, `'error'`) or an array `[severity, options]` when the rule accepts options.
58
58
 
@@ -82,7 +82,7 @@ Available bundles: `recommended`, `strict`, `problem`, `tampermonkey`, `violentm
82
82
 
83
83
  <summary>Enforces a preferred order for metadata keys.</summary>
84
84
 
85
- #### Options
85
+ <h4 id="meta-order-options">Options</h4>
86
86
 
87
87
  - `order` (default `[]`) – metadata keys in custom order (e.g. `['license', 'namespace']`) to selectively override built-in order with
88
88
 
@@ -125,7 +125,18 @@ If you don't care about the order of metadata fields.
125
125
  #### See also
126
126
 
127
127
  - [`meta-spacing`](#meta-spacing)
128
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
129
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
130
+ <a title="Doesn't prevent bugs" href="#meta-spacing"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
131
+ <a title="Accepts array w/ options" href="#meta-spacing-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
128
132
  - [`no-invalid-headers`](#no-invalid-headers)
133
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
134
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
135
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
136
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
137
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
138
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
139
+ <a title="Accepts array w/ options" href="#no-invalid-headers-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
129
140
 
130
141
  <div align="center">
131
142
 
@@ -156,7 +167,7 @@ If you don't care about the order of metadata fields.
156
167
 
157
168
  <summary>Aligns metadata values to the column after the longest key.</summary>
158
169
 
159
- #### Options
170
+ <h4 id="meta-spacing-options">Options</h4>
160
171
 
161
172
  - `spaces` (default `3`) – minimum spaces after the longest key
162
173
 
@@ -197,7 +208,13 @@ If you don't care about visual alignment in metadata blocks.
197
208
  #### See also
198
209
 
199
210
  - [`require-blank-line-after-meta-block`](#require-blank-line-after-meta-block)
211
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
212
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
213
+ <a title="Doesn't prevent bugs" href="#require-blank-line-after-meta-block"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
200
214
  - [`require-space-before-meta-key`](#require-space-before-meta-key)
215
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
216
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
217
+ <a title="Doesn't prevent bugs" href="#require-space-before-meta-key"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
201
218
 
202
219
  <div align="center">
203
220
 
@@ -261,7 +278,11 @@ If you intentionally repeat single-value keys.
261
278
  #### See also
262
279
 
263
280
  - [`require-matching-localized-fields`](#require-matching-localized-fields)
281
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
282
+ <a title="Accepts array w/ options" href="#require-matching-localized-fields-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
264
283
  - [`require-required-fields`](#require-required-fields)
284
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
285
+ <a title="Accepts array w/ options" href="#require-required-fields-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
265
286
 
266
287
  <div align="center">
267
288
 
@@ -298,7 +319,7 @@ If you intentionally repeat single-value keys.
298
319
 
299
320
  <summary>Disallows invalid or unsupported <code>@grant</code> values.</summary>
300
321
 
301
- #### Options
322
+ <h4 id="no-invalid-grants-options">Options</h4>
302
323
 
303
324
  - `target` (default `'all'`) – manager(s) whose grants to validate against (`'all'`, `'tampermonkey'`, `'violentmonkey'`, `'greasemonkey'`, `'scriptcat'`, `'adguard'`), as a single string or array
304
325
  - `allowedGrants` (default `[]`) – additional `@grant` values to allow beyond the built-in list (covering Tampermonkey, Violentmonkey, Greasemonkey, ScriptCat and AdGuard), as a single string or array
@@ -354,7 +375,9 @@ If you don't want `@grant` validation at all. For individual uncovered grants, p
354
375
  #### See also
355
376
 
356
377
  - [`no-missing-grants`](#no-missing-grants)
378
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
357
379
  - [`no-unused-grants`](#no-unused-grants)
380
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
358
381
 
359
382
  <div align="center">
360
383
 
@@ -391,7 +414,7 @@ If you don't want `@grant` validation at all. For individual uncovered grants, p
391
414
 
392
415
  <summary>Disallows invalid or unsupported metadata headers.</summary>
393
416
 
394
- #### Options
417
+ <h4 id="no-invalid-headers-options">Options</h4>
395
418
 
396
419
  - `target` (default `'all'`) – manager(s) whose headers to validate against (`'all'`, `'tampermonkey'`, `'violentmonkey'`, `'greasemonkey'`, `'scriptcat'`, `'adguard'`), as a single string or array
397
420
  - `allowedHeaders` (default `[]`) – additional headers to allow (strings or regexes), as a single value or array
@@ -435,7 +458,16 @@ If your script relies heavily on custom headers and you'd rather not maintain `a
435
458
  #### See also
436
459
 
437
460
  - [`no-invalid-grants`](#no-invalid-grants)
461
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
462
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
463
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
464
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
465
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
466
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
467
+ <a title="Accepts array w/ options" href="#no-invalid-grants-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
438
468
  - [`valid-field-values`](#valid-field-values)
469
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
470
+ <a title="Accepts array w/ options" href="#valid-field-values-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
439
471
 
440
472
  <div align="center">
441
473
 
@@ -492,7 +524,15 @@ If you use APIs through aliases or wrappers that obscure the original call site.
492
524
  #### See also
493
525
 
494
526
  - [`no-invalid-grants`](#no-invalid-grants)
527
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
528
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
529
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
530
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
531
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
532
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
533
+ <a title="Accepts array w/ options" href="#no-invalid-grants-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
495
534
  - [`no-unused-grants`](#no-unused-grants)
535
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
496
536
 
497
537
  <div align="center">
498
538
 
@@ -549,6 +589,7 @@ If you reference resources through an alias or computed pattern that obscures th
549
589
  #### See also
550
590
 
551
591
  - [`no-unused-resources`](#no-unused-resources)
592
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
552
593
 
553
594
  <div align="center">
554
595
 
@@ -602,7 +643,15 @@ If you access the granted API through an alias or computed property rather than
602
643
  #### See also
603
644
 
604
645
  - [`no-invalid-grants`](#no-invalid-grants)
646
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
647
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
648
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
649
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
650
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
651
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
652
+ <a title="Accepts array w/ options" href="#no-invalid-grants-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
605
653
  - [`no-missing-grants`](#no-missing-grants)
654
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
606
655
 
607
656
  <div align="center">
608
657
 
@@ -656,6 +705,7 @@ If you pass resource names through variables or aliases rather than use them lit
656
705
  #### See also
657
706
 
658
707
  - [`no-missing-resources`](#no-missing-resources)
708
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
659
709
 
660
710
  <div align="center">
661
711
 
@@ -707,8 +757,8 @@ If you rely on `@include` patterns that cannot be expressed using `@match`.
707
757
 
708
758
  #### See also
709
759
 
710
- - <a target="_blank" href="https://www.tampermonkey.net/documentation.php?locale=en&q=include#meta:match">Tampermonkey — `@match`</a>
711
- - <a target="_blank" href="https://www.tampermonkey.net/documentation.php?locale=en&q=include#meta:include">Tampermonkey — `@include`</a>
760
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=tampermonkey.net&sz=64">&ensp;<a target="_blank" href="https://www.tampermonkey.net/documentation.php?locale=en&q=include#meta:match">Tampermonkey — `@match`</a>
761
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=tampermonkey.net&sz=64">&ensp;<a target="_blank" href="https://www.tampermonkey.net/documentation.php?locale=en&q=include#meta:include">Tampermonkey — `@include`</a>
712
762
 
713
763
  <div align="center">
714
764
 
@@ -771,7 +821,15 @@ If you don't care about visual separation between metadata and code.
771
821
  #### See also
772
822
 
773
823
  - [`meta-order`](#meta-order)
824
+ <a title="Only included in strict config" href="#usage"><img height=14 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
825
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
826
+ <a title="Doesn't prevent bugs" href="#meta-order"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
827
+ <a title="Accepts array w/ options" href="#meta-order-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
774
828
  - [`meta-spacing`](#meta-spacing)
829
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
830
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
831
+ <a title="Doesn't prevent bugs" href="#meta-spacing"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
832
+ <a title="Accepts array w/ options" href="#meta-spacing-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
775
833
 
776
834
  <div align="center">
777
835
 
@@ -825,9 +883,8 @@ If you don't care about ensuring homepage URL compatibility across different man
825
883
 
826
884
  #### See also
827
885
 
828
- - [`require-update-download-pair`](#require-update-download-pair)
829
- - <a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=homepage#meta:homepage">Tampermonkey `@homepage`, `@homepageURL`, `@website`, `@source`</a>
830
- - <a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#homepage-homepageurl-website">ScriptCat `@homepage`, `@homepageURL`, `@website`</a>
886
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=tampermonkey.net&sz=64">&ensp;<a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=homepage#meta:homepage">Tampermonkey `@homepage`, `@homepageURL`, `@website`, `@source`</a>
887
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=docs.scriptcat.org&sz=64">&ensp;<a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#homepage-homepageurl-website">ScriptCat `@homepage`, `@homepageURL`, `@website`</a>
831
888
 
832
889
  <div align="center">
833
890
 
@@ -854,7 +911,7 @@ If you don't care about ensuring homepage URL compatibility across different man
854
911
 
855
912
  <summary>Requires that every <code>@name:xx</code> has a matching <code>@description:xx</code> (and vice versa).</summary>
856
913
 
857
- #### Options
914
+ <h4 id="require-matching-localized-fields-options">Options</h4>
858
915
 
859
916
  - `ignoreLanguages` (default `[]`) – language code(s) to skip (e.g. `'de'` or `['es', 'fr']`)
860
917
 
@@ -896,7 +953,10 @@ If you intentionally provide localized names without descriptions (or vice versa
896
953
  #### See also
897
954
 
898
955
  - [`no-duplicate-keys`](#no-duplicate-keys)
956
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
899
957
  - [`require-required-fields`](#require-required-fields)
958
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
959
+ <a title="Accepts array w/ options" href="#require-required-fields-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
900
960
 
901
961
  <div align="center">
902
962
 
@@ -923,7 +983,7 @@ If you intentionally provide localized names without descriptions (or vice versa
923
983
 
924
984
  <summary>Requires essential metadata fields (<code>@name</code>, <code>@version</code> and at least one <code>@match</code> or <code>@include</code>).</summary>
925
985
 
926
- #### Options
986
+ <h4 id="require-required-fields-options">Options</h4>
927
987
 
928
988
  - `fields` (default `['name', 'version']`) – override the required field list
929
989
  - `requireMatchOrInclude` (default `true`) – require `@match` or `@include`
@@ -962,7 +1022,10 @@ If your script is a work-in-progress, or metadata is injected at build time.
962
1022
  #### See also
963
1023
 
964
1024
  - [`no-duplicate-keys`](#no-duplicate-keys)
1025
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
965
1026
  - [`require-matching-localized-fields`](#require-matching-localized-fields)
1027
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1028
+ <a title="Accepts array w/ options" href="#require-matching-localized-fields-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
966
1029
 
967
1030
  <div align="center">
968
1031
 
@@ -1021,7 +1084,14 @@ If you intentionally use a different prefix style.
1021
1084
  #### See also
1022
1085
 
1023
1086
  - [`meta-spacing`](#meta-spacing)
1087
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1088
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
1089
+ <a title="Doesn't prevent bugs" href="#meta-spacing"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
1090
+ <a title="Accepts array w/ options" href="#meta-spacing-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1024
1091
  - [`require-blank-line-after-meta-block`](#require-blank-line-after-meta-block)
1092
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1093
+ <a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
1094
+ <a title="Doesn't prevent bugs" href="#require-blank-line-after-meta-block"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
1025
1095
 
1026
1096
  <div align="center">
1027
1097
 
@@ -1048,7 +1118,7 @@ If you intentionally use a different prefix style.
1048
1118
 
1049
1119
  <summary>Requires SRI hashes on <code>@require</code> and <code>@resource</code> URLs.</summary>
1050
1120
 
1051
- #### Options
1121
+ <h4 id="require-sri-hashing-options">Options</h4>
1052
1122
 
1053
1123
  - `algorithm` (default `'sha256'`) – SRI hash algorithm(s) to enforce (`'md5'`, `'sha1'`, `'sha256'`, `'sha384'`, `'sha512'`), as a single string or array
1054
1124
 
@@ -1088,10 +1158,8 @@ If you prefer shorter URLs, or don't support users who strictly enforce subresou
1088
1158
 
1089
1159
  #### See also
1090
1160
 
1091
- - [`no-invalid-headers`](#no-invalid-headers)
1092
- - [`require-required-fields`](#require-required-fields)
1093
- - <a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=sri">Tampermonkey — Subresource Integrity</a>
1094
- - <a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#resource-integrity-verification">ScriptCat — Resource Integrity Verification</a>
1161
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=tampermonkey.net&sz=64">&ensp;<a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=sri">Tampermonkey — Subresource Integrity</a>
1162
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=docs.scriptcat.org&sz=64">&ensp;<a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#resource-integrity-verification">ScriptCat — Resource Integrity Verification</a>
1095
1163
 
1096
1164
  <div align="center">
1097
1165
 
@@ -1141,7 +1209,7 @@ If you prefer shorter URLs, or don't support users who strictly enforce subresou
1141
1209
 
1142
1210
  #### When not to use it
1143
1211
 
1144
- If you don't target Tampermonkey, ScriptCat or AdGuard (where `@updateURL` avoids re-downloading the full script on every update check).
1212
+ If you don't strictly target Tampermonkey, ScriptCat or AdGuard (where `@updateURL` avoids re-downloading the full script on every update check).
1145
1213
 
1146
1214
  #### Introduced in
1147
1215
 
@@ -1149,9 +1217,8 @@ If you don't target Tampermonkey, ScriptCat or AdGuard (where `@updateURL` avoid
1149
1217
 
1150
1218
  #### See also
1151
1219
 
1152
- - [`require-homepage-pair`](#require-homepage-pair)
1153
- - <a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=update_url#meta:updateURL">Tampermonkey — `@updateURL`</a>
1154
- - <a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#updateurl">ScriptCat — `@updateURL`</a>
1220
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=tampermonkey.net&sz=64">&ensp;<a target="_blank" href="https://www.tampermonkey.net/documentation.php?q=update_url#meta:updateURL">Tampermonkey — `@updateURL`</a>
1221
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=docs.scriptcat.org&sz=64">&ensp;<a target="_blank" href="https://docs.scriptcat.org/en/docs/dev/meta/#updateurl">ScriptCat — `@updateURL`</a>
1155
1222
 
1156
1223
  <div align="center">
1157
1224
 
@@ -1222,7 +1289,7 @@ If you intentionally name your userscripts something other than `*.user.js`.
1222
1289
 
1223
1290
  <summary>Validates <code>@version</code> (semver or date format) and URL fields.</summary>
1224
1291
 
1225
- #### Options
1292
+ <h4 id="valid-field-values-options">Options</h4>
1226
1293
 
1227
1294
  - `versionType` (default `'semver'`) – version format to enforce (`'semver'`, `'date'`)
1228
1295
  - `allowFutureDate` (default `false`) – allow `@version` dates later than the current date
@@ -1263,7 +1330,21 @@ If you use a custom versioning scheme or URLs that aren't standard.
1263
1330
  #### See also
1264
1331
 
1265
1332
  - [`no-invalid-grants`](#no-invalid-grants)
1266
- - [`no-missing-resources`](#no-missing-resources)
1333
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1334
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
1335
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
1336
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
1337
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
1338
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
1339
+ <a title="Accepts array w/ options" href="#no-invalid-grants-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1340
+ - [`no-invalid-headers`](#no-invalid-headers)
1341
+ <a title="Included in recommended config" href="#usage"><img height=14 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1342
+ <a title="Optimized in tampermonkey config" href="#usage"><img height=14 alt="[Tampermonkey]" src="https://img.shields.io/badge/Tampermonkey-00485b?style=flat-square" align="middle"></a>
1343
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-f01e07?style=flat-square" align="middle"></a>
1344
+ <a title="Optimized in greasemonkey config" href="#usage"><img height=14 alt="[Greasemonkey]" src="https://img.shields.io/badge/Greasemonkey-6c4d8c?style=flat-square" align="middle"></a>
1345
+ <a title="Optimized in scriptcat config" href="#usage"><img height=14 alt="[ScriptCat]" src="https://img.shields.io/badge/ScriptCat-1296dc?style=flat-square" align="middle"></a>
1346
+ <a title="Optimized in adguard config" href="#usage"><img height=14 alt="[AdGuard]" src="https://img.shields.io/badge/AdGuard-68bd72?style=flat-square" align="middle"></a>
1347
+ <a title="Accepts array w/ options" href="#no-invalid-headers-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1267
1348
 
1268
1349
  <div align="center">
1269
1350
 
@@ -1283,7 +1364,7 @@ If you use a custom versioning scheme or URLs that aren't standard.
1283
1364
  #### HTML
1284
1365
 
1285
1366
  ```html
1286
- <a href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/#readme">
1367
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/#readme">
1287
1368
  <img height=32 alt="[Linted by eslint-plugin-greasemonkey]" src="https://img.shields.io/badge/Linted_by-eslint--plugin--greasemonkey-black?logo=eslint&logoColor=white&labelColor=464646&style=for-the-badge"></a>
1288
1369
  ```
1289
1370
 
@@ -1317,6 +1398,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1317
1398
 
1318
1399
  ## <img height=30 width=29 align="top" src="https://api.iconify.design/bxs/package.svg?color=%232b2b2a"> Related
1319
1400
 
1401
+ <!-- eslint-plugin-chrome-extensions -->
1402
+
1403
+ ### <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/#readme"><img height=15 width=auto src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/e9128375d4/assets/images/icons/eslint/purple/icon16.png"> eslint-plugin-chrome-extensions</a>
1404
+
1405
+ <details>
1406
+
1407
+ <summary>ESLint rules for Chrome extensions.</summary><br>
1408
+
1409
+ > <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/#readme"><img width=555 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-chrome-extensions/0b5e3e49/assets/images/screenshots/vs-code/squiggles.png"></a>
1410
+
1411
+ > <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/#installation"><b>Install</b></a> / <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/#readme">Readme</a> / <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/#supported-rules">Supported rules</a>
1412
+
1413
+ </details>
1414
+
1320
1415
  <!-- eslint-plugin-constructors -->
1321
1416
 
1322
1417
  ### <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-constructors/#readme"><img height=15 width=auto src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/e9128375d4/assets/images/icons/eslint/purple/icon16.png"> eslint-plugin-constructors</a>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-greasemonkey",
3
- "version": "1.8.2",
3
+ "version": "1.8.4",
4
4
  "description": "ESLint rules for Greasemonkey/Tampermonkey userscripts",
5
5
  "type": "module",
6
6
  "engines": {
@@ -34,7 +34,6 @@
34
34
  ],
35
35
  "types": "src/index.d.ts",
36
36
  "scripts": {
37
- "prepare": "husky",
38
37
  "lint": "eslint . --cache && yamllint .",
39
38
  "lint:all": "eslint . && yamllint .",
40
39
  "lint:fix": "eslint . --fix --cache && yamllint .",
@@ -65,21 +64,20 @@
65
64
  "devDependencies": {
66
65
  "@e18e/eslint-plugin": "^0.8.1",
67
66
  "@eslint/js": "^10.0.1",
68
- "@eslint/json": "^2.1.0",
69
- "@eslint/markdown": "^8.0.3",
67
+ "@eslint/json": "^2.1.1",
68
+ "@eslint/markdown": "^7.5.1",
70
69
  "@stylistic/eslint-plugin": "^5.10.0",
71
- "eslint": "^10.11.0",
72
- "eslint-plugin-constructors": "^1.4.0",
70
+ "eslint": "^10.12.0",
71
+ "eslint-plugin-constructors": "^1.4.2",
73
72
  "eslint-plugin-eslint-plugin": "^7.6.2",
74
73
  "eslint-plugin-import-x": "^4.17.1",
75
- "eslint-plugin-n": "^18.4.0",
74
+ "eslint-plugin-n": "^18.4.1",
76
75
  "eslint-plugin-no-secrets": "^2.3.3",
77
76
  "eslint-plugin-no-unsanitized": "^4.1.5",
78
77
  "eslint-plugin-promise": "^7.3.0",
79
78
  "eslint-plugin-regexp": "^3.3.1",
80
79
  "eslint-plugin-security": "^4.2.0",
81
80
  "globals": "^17.13.0",
82
- "husky": "^9.1.7",
83
81
  "yamllint-js": "^0.2.4"
84
82
  }
85
83
  }
package/src/index.js CHANGED
@@ -22,7 +22,7 @@ import requireUpdateDownloadPair from './rules/require-update-download-pair.js'
22
22
  import requireUserJsFilename from './rules/require-user-js-filename.js'
23
23
  import validFieldValues from './rules/valid-field-values.js'
24
24
 
25
- import { initDeprecatedAlias } from './utils.js'
25
+ import { bundleRules, initDeprecatedAlias } from './utils.js'
26
26
 
27
27
  const plugin = {
28
28
  rules: {
@@ -57,33 +57,15 @@ for (const entry of Object.entries(oldRules))
57
57
  plugin.configs = {
58
58
  recommended: {
59
59
  plugins: { greasemonkey: plugin },
60
- rules: {
61
- 'greasemonkey/meta-spacing': 'error',
62
- 'greasemonkey/no-duplicate-keys': 'error',
63
- 'greasemonkey/no-invalid-grants': 'error',
64
- 'greasemonkey/no-invalid-headers': 'error',
65
- 'greasemonkey/no-missing-grants': 'error',
66
- 'greasemonkey/no-unused-grants': 'error',
67
- 'greasemonkey/no-missing-resources': 'error',
68
- 'greasemonkey/no-unused-resources': 'error',
69
- 'greasemonkey/prefer-match': 'error',
70
- 'greasemonkey/require-blank-line-after-meta-block': 'error',
71
- 'greasemonkey/require-matching-localized-fields': 'error',
72
- 'greasemonkey/require-required-fields': 'error',
73
- 'greasemonkey/require-space-before-meta-key': 'error',
74
- 'greasemonkey/require-user-js-filename': 'error',
75
- 'greasemonkey/valid-field-values': 'error'
76
- }
60
+ rules: bundleRules(plugin.rules, rule => rule.meta.docs.recommended, 'greasemonkey')
77
61
  },
78
62
  strict: {
79
63
  plugins: { greasemonkey: plugin },
80
- rules: Object.fromEntries(Object.keys(plugin.rules).map(ruleId => [`greasemonkey/${ruleId}`, 'error']))
64
+ rules: bundleRules(plugin.rules, () => true, 'greasemonkey')
81
65
  },
82
66
  problem: {
83
67
  plugins: { greasemonkey: plugin },
84
- rules: Object.fromEntries(Object.entries(plugin.rules)
85
- .filter(([, rule]) => rule.meta.type == 'problem')
86
- .map(([ruleId]) => [`greasemonkey/${ruleId}`, 'error']))
68
+ rules: bundleRules(plugin.rules, rule => rule.meta.type == 'problem', 'greasemonkey')
87
69
  }
88
70
  }
89
71
 
@@ -39,13 +39,13 @@ export default {
39
39
  properties: {
40
40
  order: {
41
41
  type: 'array', items: { type: 'string' },
42
- description: 'Metadata keys in preferred order; unspecified keys are ignored'
42
+ description: 'Metadata keys in preferred order'
43
43
  }
44
44
  },
45
45
  additionalProperties: false
46
46
  }],
47
47
  defaultOptions: [{ order: [] }],
48
- messages: { wrongOrder: '@{{first}} should appear before @{{second}}' }
48
+ messages: { wrongOrder: '@{{first}} should appear before @{{second}}.' }
49
49
  },
50
50
 
51
51
  create(context) {
@@ -22,7 +22,7 @@ export default {
22
22
  additionalProperties: false
23
23
  }],
24
24
  defaultOptions: [{ spaces: 3 }],
25
- messages: { misaligned: 'Metadata values should be aligned at column {{column}}' }
25
+ messages: { misaligned: 'Metadata values should be aligned at column {{column}}.' }
26
26
  },
27
27
 
28
28
  create(context) {
@@ -14,7 +14,7 @@ export default {
14
14
  recommended: true
15
15
  },
16
16
  schema: [],
17
- messages: { dupeKey: 'Duplicate @{{key}}' }
17
+ messages: { dupeKey: 'Duplicate @{{key}}.' }
18
18
  },
19
19
 
20
20
  create(context) {
@@ -1,6 +1,7 @@
1
- import { extractMetadata } from '../utils.js'
2
1
  import { allAPIs, supportsAPI } from '../data/apis.js'
3
2
 
3
+ import { extractMetadata } from '../utils.js'
4
+
4
5
  const managers = ['tampermonkey', 'violentmonkey', 'greasemonkey', 'scriptcat', 'adguard'],
5
6
  specialGrants = new Set(['none', 'unsafeWindow', 'window.close', 'window.focus', 'window.onurlchange']),
6
7
  allGrants = new Set([...allAPIs, ...specialGrants]),
@@ -37,7 +38,7 @@ export default {
37
38
  defaultOptions: [{}],
38
39
  messages: {
39
40
  invalidGrant: 'Invalid @grant: "{{grant}}"',
40
- unsupportedGrant: '"@{{grant}}" is not supported by {{target}} (only by {{supporting}})',
41
+ unsupportedGrant: '"@{{grant}}" is not supported by {{target}} (only by {{supporting}}).',
41
42
  wrongCase: 'Invalid @grant: "{{grant}}" (did you mean "{{suggestion}}"?)'
42
43
  }
43
44
  },
@@ -46,14 +47,15 @@ export default {
46
47
  const options = context.options[0] || {},
47
48
  rawTarget = options.target ?? 'all',
48
49
  targets = Array.isArray(rawTarget) ? rawTarget : [rawTarget],
49
- allowedGrants = [options.allowedGrants ?? []].flat()
50
+ rawAllowed = options.allowedGrants ?? [],
51
+ allowedGrants = new Set(Array.isArray(rawAllowed) ? rawAllowed : [rawAllowed])
50
52
  return {
51
53
  Program() {
52
54
  const metaEntries = extractMetadata(context.sourceCode),
53
55
  grantEntries = metaEntries.filter(entry => entry.key == 'grant')
54
56
  for (const grant of grantEntries) {
55
57
  const grantName = grant.value.trim()
56
- if (specialGrants.has(grantName) || allowedGrants.includes(grantName)) continue
58
+ if (specialGrants.has(grantName) || allowedGrants.has(grantName)) continue
57
59
  if (!allGrants.has(grantName)) {
58
60
  const suggestion = sortedGrants.get(grantName.toLowerCase())
59
61
  if (suggestion && suggestion != grantName)
@@ -1,6 +1,7 @@
1
- import { extractMetadata } from '../utils.js'
2
1
  import { managerHeaders, managers, localizedHeaders, validHeaders } from '../data/headers.js'
3
2
 
3
+ import { extractMetadata } from '../utils.js'
4
+
4
5
  function parseAllowedPattern(entry) {
5
6
  if (typeof entry != 'string' || !entry.startsWith('/')) return null
6
7
  const lastSlash = entry.lastIndexOf('/')
@@ -37,8 +38,8 @@ export default {
37
38
  }],
38
39
  defaultOptions: [{ allowedHeaders: [] }],
39
40
  messages: {
40
- invalidHeader: 'Invalid header: "@{{header}}"',
41
- unsupportedHeader: '"@{{header}}" is not supported by {{target}} (only by {{supporting}})'
41
+ invalidHeader: 'Invalid header: "@{{header}}".',
42
+ unsupportedHeader: '"@{{header}}" is not supported by {{target}} (only by {{supporting}}).'
42
43
  }
43
44
  },
44
45
 
@@ -1,6 +1,7 @@
1
- import { extractMetadata } from '../utils.js'
2
1
  import { gmLegacyAPIs, gmModernAPIs, scAPIs } from '../data/apis.js'
3
2
 
3
+ import { extractMetadata } from '../utils.js'
4
+
4
5
  const apis = new Set([...gmLegacyAPIs, ...gmModernAPIs, ...scAPIs]),
5
6
  grantlessAPIs = new Set(['GM_info', 'GM.info']) // always available, no grant required
6
7
 
@@ -13,7 +14,7 @@ export default {
13
14
  recommended: true
14
15
  },
15
16
  schema: [],
16
- messages: { missingGrant: 'Missing @grant: "{{api}}"' }
17
+ messages: { missingGrant: 'Missing @grant: "{{api}}".' }
17
18
  },
18
19
 
19
20
  create(context) {
@@ -13,8 +13,8 @@ export default {
13
13
  },
14
14
  schema: [],
15
15
  messages: {
16
- missingResource: 'Missing @resource: "{{name}}"',
17
- noMatchingResource: 'No declared @resource matches `{{pattern}}`'
16
+ missingResource: 'Missing @resource: "{{name}}".',
17
+ noMatchingResource: 'No declared @resource matches `{{pattern}}`.'
18
18
  }
19
19
  },
20
20
 
@@ -9,7 +9,7 @@ export default {
9
9
  recommended: true
10
10
  },
11
11
  schema: [],
12
- messages: { preferMatch: 'Use @match instead of @include' }
12
+ messages: { preferMatch: 'Use @match instead of @include.' }
13
13
  },
14
14
 
15
15
  create(context) {
@@ -8,7 +8,7 @@ export default {
8
8
  },
9
9
  fixable: 'whitespace',
10
10
  schema: [],
11
- messages: { missingBlankLine: 'Missing blank line after metadata block' }
11
+ messages: { missingBlankLine: 'Missing blank line after metadata block.' }
12
12
  },
13
13
 
14
14
  create(context) {
@@ -10,7 +10,7 @@ export default {
10
10
  },
11
11
  fixable: 'code',
12
12
  schema: [],
13
- messages: { missingPair: 'Missing @{{missing}} (required when @{{present}} is used)' }
13
+ messages: { missingPair: 'Missing @{{missing}} (required when @{{present}} is used).' }
14
14
  },
15
15
 
16
16
  create(context) {
@@ -4,7 +4,7 @@ export default {
4
4
  meta: {
5
5
  type: 'problem',
6
6
  docs: {
7
- description: 'Require matching localized name and description fields',
7
+ description: 'Require matching localized @name and @description fields',
8
8
  category: 'Possible Errors',
9
9
  recommended: true
10
10
  },
@@ -22,12 +22,13 @@ export default {
22
22
  additionalProperties: false
23
23
  }],
24
24
  defaultOptions: [{}],
25
- messages: { missingPair: 'Missing matching @{{missing}} for @{{present}}' }
25
+ messages: { missingPair: 'Missing matching @{{missing}} for @{{present}}.' }
26
26
  },
27
27
 
28
28
  create(context) {
29
29
  const options = context.options[0] || {},
30
- ignoreLanguages = [options.ignoreLanguages ?? []].flat()
30
+ rawLangs = options.ignoreLanguages ?? [],
31
+ ignoreLangs = new Set(Array.isArray(rawLangs) ? rawLangs : [rawLangs])
31
32
  return {
32
33
  Program() {
33
34
  const metaEntries = extractMetadata(context.sourceCode),
@@ -36,14 +37,14 @@ export default {
36
37
  nameLangs = new Set(nameEntries.map(entry => entry.key.split(':')[1])),
37
38
  descLangs = new Set(descEntries.map(entry => entry.key.split(':')[1]))
38
39
  for (const lang of nameLangs)
39
- if (!ignoreLanguages.includes(lang) && !descLangs.has(lang))
40
+ if (!ignoreLangs.has(lang) && !descLangs.has(lang))
40
41
  context.report({
41
42
  node: nameEntries.find(entry => entry.key == `name:${lang}`).comment,
42
43
  messageId: 'missingPair',
43
44
  data: { missing: `description:${lang}`, present: `name:${lang}` }
44
45
  })
45
46
  for (const lang of descLangs)
46
- if (!ignoreLanguages.includes(lang) && !nameLangs.has(lang))
47
+ if (!ignoreLangs.has(lang) && !nameLangs.has(lang))
47
48
  context.report({
48
49
  node: descEntries.find(entry => entry.key == `description:${lang}`).comment,
49
50
  messageId: 'missingPair',
@@ -24,7 +24,7 @@ export default {
24
24
  additionalProperties: false
25
25
  }],
26
26
  defaultOptions: [{}],
27
- messages: { missingField: 'Missing required metadata field: @{{field}}' }
27
+ messages: { missingField: 'Missing required metadata field: @{{field}}.' }
28
28
  },
29
29
 
30
30
  create(context) {
@@ -12,7 +12,7 @@ export default {
12
12
  },
13
13
  fixable: 'whitespace',
14
14
  schema: [],
15
- messages: { badPrefix: '`{{actual}}` should be `// @{{key}}`' }
15
+ messages: { badPrefix: '`{{actual}}` should be `// @{{key}}`.' }
16
16
  },
17
17
 
18
18
  create(context) {
@@ -9,7 +9,7 @@ export default {
9
9
  recommended: false
10
10
  },
11
11
  schema: [],
12
- messages: { missingPair: 'Missing @{{missing}} (required when @{{present}} is used)' }
12
+ messages: { missingPair: 'Missing @{{missing}} (required when @{{present}} is used).' }
13
13
  },
14
14
 
15
15
  create(context) {
@@ -9,7 +9,7 @@ export default {
9
9
  recommended: true
10
10
  },
11
11
  schema: [],
12
- messages: { requireUserJS: 'Userscript filename should end in ".user.js"' }
12
+ messages: { requireUserJS: 'Userscript filename should end in ".user.js".' }
13
13
  },
14
14
 
15
15
  create(context) {
@@ -42,17 +42,17 @@ export default {
42
42
  }],
43
43
  defaultOptions: [{}],
44
44
  messages: {
45
- invalidVersion: 'Invalid @version: must be a valid {{versionType}} (expected format: {{example}})',
46
- futureVersion: 'Invalid @version: date cannot be in the future',
47
- invalidURL: 'Invalid URL for @{{field}}',
48
- invalidGrant: 'Unknown @grant: "{{grant}}"'
45
+ invalidVersion: 'Invalid @version: must be a valid {{versionType}} (expected format: {{example}}).',
46
+ futureVersion: 'Invalid @version: date cannot be in the future.',
47
+ invalidURL: 'Invalid URL for @{{field}}.',
48
+ invalidGrant: 'Unknown @grant: "{{grant}}".'
49
49
  }
50
50
  },
51
51
 
52
52
  create(context) {
53
53
  const options = context.options[0] || {},
54
54
  versionType = options.versionType || 'semver',
55
- allowedGrants = options.allowedGrants || [],
55
+ allowedGrants = new Set(options.allowedGrants || []),
56
56
  allowFutureDate = options.allowFutureDate ?? false,
57
57
  timezone = options.timezone,
58
58
  example = versionType == 'semver' ? '1.2.3' : 'YYYY.M.D or YYYY.MM.DD'
@@ -66,7 +66,7 @@ export default {
66
66
  Program() {
67
67
  const metaEntries = extractMetadata(context.sourceCode)
68
68
  for (const entry of metaEntries) {
69
- if (entry.key == 'grant' && allowedGrants.length && !allowedGrants.includes(entry.value))
69
+ if (entry.key == 'grant' && allowedGrants.size && !allowedGrants.has(entry.value))
70
70
  context.report({ node: entry.comment, messageId: 'invalidGrant', data: { grant: entry.value }})
71
71
  else if (entry.key == 'resource') {
72
72
  const url = entry.value.trim().split(re.whitespace)[1]
package/src/utils.js CHANGED
@@ -1,5 +1,11 @@
1
1
  const re = { whitespace: /\s/ }
2
2
 
3
+ export function bundleRules(rules, predicate, pluginName) {
4
+ return Object.fromEntries(Object.entries(rules)
5
+ .filter(([, rule]) => predicate(rule))
6
+ .map(([ruleId]) => [`${pluginName}/${ruleId}`, 'error']))
7
+ }
8
+
3
9
  export function extractMetadata(sourceCode) {
4
10
  const comments = sourceCode.getAllComments(),
5
11
  metaEntries = []