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 +120 -25
- package/package.json +6 -8
- package/src/index.js +4 -22
- package/src/rules/meta-order.js +2 -2
- package/src/rules/meta-spacing.js +1 -1
- package/src/rules/no-duplicate-keys.js +1 -1
- package/src/rules/no-invalid-grants.js +6 -4
- package/src/rules/no-invalid-headers.js +4 -3
- package/src/rules/no-missing-grants.js +3 -2
- package/src/rules/no-missing-resources.js +2 -2
- package/src/rules/prefer-match.js +1 -1
- package/src/rules/require-blank-line-after-meta-block.js +1 -1
- package/src/rules/require-homepage-pair.js +1 -1
- package/src/rules/require-matching-localized-fields.js +6 -5
- package/src/rules/require-required-fields.js +1 -1
- package/src/rules/require-space-before-meta-key.js +1 -1
- package/src/rules/require-update-download-pair.js +1 -1
- package/src/rules/require-user-js-filename.js +1 -1
- package/src/rules/valid-field-values.js +6 -6
- package/src/utils.js +6 -0
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"> <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"> <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
|
-
-
|
|
829
|
-
- <a target="_blank" href="https://
|
|
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"> <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"> <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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
1092
|
-
-
|
|
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"> <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"> <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
|
-
-
|
|
1153
|
-
- <a target="_blank" href="https://
|
|
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"> <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"> <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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
69
|
-
"@eslint/markdown": "^
|
|
67
|
+
"@eslint/json": "^2.1.1",
|
|
68
|
+
"@eslint/markdown": "^7.5.1",
|
|
70
69
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
71
|
-
"eslint": "^10.
|
|
72
|
-
"eslint-plugin-constructors": "^1.4.
|
|
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.
|
|
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:
|
|
64
|
+
rules: bundleRules(plugin.rules, () => true, 'greasemonkey')
|
|
81
65
|
},
|
|
82
66
|
problem: {
|
|
83
67
|
plugins: { greasemonkey: plugin },
|
|
84
|
-
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
|
|
package/src/rules/meta-order.js
CHANGED
|
@@ -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
|
|
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) {
|
|
@@ -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
|
-
|
|
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.
|
|
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
|
|
|
@@ -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
|
-
|
|
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 (!
|
|
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 (!
|
|
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) {
|
|
@@ -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) {
|
|
@@ -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.
|
|
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 = []
|