eslint-plugin-greasemonkey 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,8 +8,8 @@
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
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
- <a target="_blank" href="https://eslint.org/">
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>
11
+ <a href="#usage">
12
+ <img alt="[Supports ESLint >=9.0.0 / Oxlint >=1.65.0]" src="https://img.shields.io/badge/Supports-ESLint_%3E%3D9.0.0_%2F_Oxlint_%3E%3D1.65.0-4B32C3?style=for-the-badge&logo=eslint"></a>
13
13
  <br><br>
14
14
 
15
15
  ESLint rules for Greasemonkey userscripts.
@@ -33,6 +33,8 @@ npm i -D eslint-plugin-greasemonkey
33
33
  Usage
34
34
  </h2>
35
35
 
36
+ ### <img height=15 width=auto src="https://www.google.com/s2/favicons?domain=eslint.org&sz=64"> ESLint
37
+
36
38
  Add a bundled config to your `eslint.config.*js`:
37
39
 
38
40
  ```js
@@ -52,12 +54,46 @@ export default [
52
54
  ]
53
55
  ```
54
56
 
55
- Available bundles: `recommended`, `strict` (everything), `problem` (deterministic bugs only), `security`, `tampermonkey`, `violentmonkey`, `greasemonkey`, `scriptcat`, `adguard`
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
 
59
59
  ---
60
60
 
61
+ ### <img height=15 width=auto src="https://www.google.com/s2/favicons?domain=oxc.rs&sz=64"> Oxlint
62
+
63
+ Add a JS bundle to your `oxlint.config.ts` (non-JS parsing is unsupported by Oxlint):
64
+
65
+ ```ts
66
+ ...
67
+ import greasemonkey from 'eslint-plugin-greasemonkey'
68
+
69
+ export default defineConfig({
70
+ overrides: [
71
+ // other configs
72
+ {
73
+ files: ['**/*.user.js'],
74
+ jsPlugins: ['eslint-plugin-greasemonkey'],
75
+ rules: {
76
+ ...greasemonkey.configs.recommended.rules,
77
+ 'greasemonkey/no-unused-resources': 'allow', // selectively disable rule
78
+ 'greasemonkey/meta-spacing': ['deny', { spaces: 2 }] // selectively tweak rule
79
+ }
80
+ }
81
+ ]
82
+ })
83
+ ```
84
+
85
+ **Note:** Rule config is either a severity string (`'allow'`, `'warn'`, `'deny'`) or an array `[severity, options]` when the rule accepts options.
86
+
87
+ **Note:** Oxlint is typically **6-20× faster than ESLint** w/ this plugin (due to its Rust core and parallel file processing).
88
+
89
+ ---
90
+
91
+ *Available userscript bundles:* `recommended`, `strict` (everything), `problem` (deterministic bugs only), `security`, `stylistic`
92
+
93
+ *Available manager bundles:* `tampermonkey`, `violentmonkey`, `greasemonkey`, `scriptcat`, `adguard`
94
+
95
+ ---
96
+
61
97
  <h2 id="supported-rules">
62
98
  <img height=30 width=27 align="top" src="https://api.iconify.design/mdi/format-list-checks.svg?color=%232b2b2a">
63
99
  Supported rules
@@ -298,8 +334,6 @@ If you intentionally repeat single-value keys.
298
334
 
299
335
  <h3 id="no-insecure-fetch">
300
336
  <code>no-insecure-fetch</code>
301
- <a title="Introduced in recent release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.9.0">
302
- <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
303
337
  <a title="Included in recommended config" href="#usage">
304
338
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
305
339
  <a title="Included in security config" href="#usage">
@@ -311,7 +345,7 @@ If you intentionally repeat single-value keys.
311
345
 
312
346
  <details>
313
347
 
314
- <summary>Flags <code>fetch()</code>, <code>XMLHttpRequest.open()</code>, <code>GM_xmlhttpRequest()</code>, <code>GM.xmlHttpRequest()</code> calls and URL fields that use <code>http://</code>.</summary>
348
+ <summary>Flags <code>fetch()</code> + XHR requests + URL fields that use <code>http://</code>.</summary>
315
349
 
316
350
  #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
317
351
 
@@ -379,8 +413,6 @@ If you intentionally target HTTP endpoints.
379
413
 
380
414
  <h3 id="no-insecure-messaging">
381
415
  <code>no-insecure-messaging</code>
382
- <a title="Introduced in recent release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.9.0">
383
- <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
384
416
  <a title="Included in recommended config" href="#usage">
385
417
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
386
418
  <a title="Included in security config" href="#usage">
@@ -769,6 +801,95 @@ If you reference resources through an alias or computed pattern that obscures th
769
801
 
770
802
  </details>
771
803
 
804
+ <h3 id="no-sensitive-grants">
805
+ <code>no-sensitive-grants</code>
806
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
807
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
808
+ <a title="Included in strict config" href="#usage">
809
+ <img height=18 alt="[Strict]" src="https://img.shields.io/badge/Strict-ff8c42?style=flat-square" align="middle"></a>
810
+ <a title="Included in security config" href="#usage">
811
+ <img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
812
+ <a title="Accepts array w/ options" href="#usage">
813
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
814
+ <a title="Copy rule URL" target="_blank"
815
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23no-sensitive-grants">
816
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
817
+ </h3>
818
+
819
+ <details>
820
+
821
+ <summary>Flags security-sensitive <code>@grant</code> values and overbroad <code>@connect</code> patterns.</summary>
822
+
823
+ <h4 id="no-sensitive-grants-options">Options</h4>
824
+
825
+ - `target` (default `'all'`) – manager(s) whose sensitive-grant set to check against (`'all'`, `'tampermonkey'`, `'violentmonkey'`, `'greasemonkey'`, `'scriptcat'`, `'adguard'`), as a single string or array
826
+ - `allowedGrants` (default `[]`) – sensitive `@grant` values to explicitly allow, as a single string or array
827
+ - `allowBroadConnect` (default `false`) – permit `@connect *`, `@connect *.com`, etc. w/o reporting
828
+
829
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
830
+
831
+ ```diff
832
+ /* eslint greasemonkey/no-sensitive-grants: ['error', { allowedGrants: ['GM_xmlhttpRequest'] }] */
833
+
834
+ // ==UserScript==
835
+ ! // @connect *
836
+ // @grant GM_xmlhttpRequest
837
+ ! // @grant GM_download
838
+ ! // @grant GM_setClipboard
839
+ ! // @grant unsafeWindow
840
+ // ==/UserScript==
841
+ ```
842
+
843
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
844
+
845
+ ```diff
846
+ /* eslint greasemonkey/no-sensitive-grants: ['error', { allowedGrants: ['GM_xmlhttpRequest'] }] */
847
+
848
+ // ==UserScript==
849
+ - // @connect *
850
+ + // @connect api.example.com
851
+ // @grant GM_xmlhttpRequest
852
+ - // @grant GM_download
853
+ - // @grant GM_setClipboard
854
+ - // @grant unsafeWindow
855
+ // ==/UserScript==
856
+ ```
857
+
858
+ #### When not to use it
859
+
860
+ If you intentionally require sensitive grants, or prefer manual security review. For individual grants or `@connect` patterns you still need, prefer `allowedGrants` or `allowBroadConnect` over disabling the rule.
861
+
862
+ #### Introduced in
863
+
864
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
865
+
866
+ #### See also
867
+
868
+ - [`no-invalid-grants`](#no-invalid-grants)
869
+ <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>
870
+ <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>
871
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-c68a3c?style=flat-square" align="middle"></a>
872
+ <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>
873
+ <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>
874
+ <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>
875
+ <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>
876
+ - [`no-missing-grants`](#no-missing-grants)
877
+ <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>
878
+ - [`no-unused-grants`](#no-unused-grants)
879
+ <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>
880
+ - <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">Tampermonkey — API reference</a>
881
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=violentmonkey.github.io&sz=64">&ensp;<a target="_blank" href="https://violentmonkey.github.io/api/gm/">Violentmonkey — `GM` API</a>
882
+
883
+ <div align="center">
884
+
885
+ [Back to index ↑][epg-rules]
886
+
887
+ </div>
888
+
889
+ ---
890
+
891
+ </details>
892
+
772
893
  <h3 id="no-unused-grants">
773
894
  <code>no-unused-grants</code>
774
895
  <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.0.0">
@@ -891,8 +1012,6 @@ If you pass resource names through variables or aliases rather than use them lit
891
1012
 
892
1013
  <h3 id="prefer-gm-add-style">
893
1014
  <code>prefer-gm-add-style</code>
894
- <a title="Introduced in recent release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.9.0">
895
- <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
896
1015
  <a title="Only included in strict config" href="#usage">
897
1016
  <img height=18 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
898
1017
  <a title="Copy rule URL" target="_blank"
@@ -933,6 +1052,7 @@ If you deliberately need manual control over the injected `<style>`.
933
1052
 
934
1053
  - <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=GM_addStyle">Tampermonkey — `GM_addStyle`</a>
935
1054
  - <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/api/#gm_addstyle">ScriptCat — `GM_addStyle`</a>
1055
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM">MDN — Using shadow DOM</a>
936
1056
 
937
1057
  <div align="center">
938
1058
 
@@ -1125,6 +1245,63 @@ If you don't care about ensuring homepage URL compatibility across different man
1125
1245
 
1126
1246
  </details>
1127
1247
 
1248
+ <h3 id="require-license-header">
1249
+ <code>require-license-header</code>
1250
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
1251
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1252
+ <a title="Only included in strict config" href="#usage">
1253
+ <img height=18 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
1254
+ <a title="Copy rule URL" target="_blank"
1255
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23require-license-header">
1256
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1257
+ </h3>
1258
+
1259
+ <details>
1260
+
1261
+ <summary>Requires the <code>@license</code> metadata field.</summary>
1262
+
1263
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1264
+
1265
+ ```diff
1266
+ // ==UserScript==
1267
+ // @name My Script
1268
+ // ==/UserScript==
1269
+ ```
1270
+
1271
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1272
+
1273
+ ```diff
1274
+ // ==UserScript==
1275
+ // @name My Script
1276
+ + // @license MIT
1277
+ // ==/UserScript==
1278
+ ```
1279
+
1280
+ #### When not to use it
1281
+
1282
+ If you don't distribute your script, or you intentionally omit a license field.
1283
+
1284
+ #### Introduced in
1285
+
1286
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
1287
+
1288
+ #### See also
1289
+
1290
+ - [`valid-license-header`](#valid-license-header)
1291
+ <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>
1292
+ <a title="Accepts array w/ options" href="#valid-license-header-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1293
+ - <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/#license">ScriptCat — @license</a>
1294
+
1295
+ <div align="center">
1296
+
1297
+ [Back to index ↑][epg-rules]
1298
+
1299
+ </div>
1300
+
1301
+ ---
1302
+
1303
+ </details>
1304
+
1128
1305
  <h3 id="require-matching-localized-fields">
1129
1306
  <code>require-matching-localized-fields</code>
1130
1307
  <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.0.0">
@@ -1592,6 +1769,297 @@ If you use a custom versioning scheme or URLs that aren't standard.
1592
1769
 
1593
1770
  </div>
1594
1771
 
1772
+ ---
1773
+
1774
+ </details>
1775
+
1776
+ <h3 id="valid-icon-headers">
1777
+ <code>valid-icon-headers</code>
1778
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
1779
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1780
+ <a title="Included in recommended config" href="#usage">
1781
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1782
+ <a title="Copy rule URL" target="_blank"
1783
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23valid-icon-headers">
1784
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1785
+ </h3>
1786
+
1787
+ <details>
1788
+
1789
+ <summary>Validates <code>@icon</code>/<code>@icon64</code>/<code>@defaulticon</code> against allowed schemes.</summary>
1790
+
1791
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1792
+
1793
+ ```diff
1794
+ // ==UserScript==
1795
+ // @name My Script
1796
+ ! // @icon data:image/png;base64abc
1797
+ ! // @icon64 data:text/plain;base64,SGVsbG8=
1798
+ ! // @defaulticon ftp://example.com/icon.png
1799
+ // ==/UserScript==
1800
+ ```
1801
+
1802
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1803
+
1804
+ ```diff
1805
+ // ==UserScript==
1806
+ // @name My Script
1807
+ - // @icon data:image/png;base64abc
1808
+ + // @icon data:image/png;base64,iVBORw0KGgo=
1809
+ - // @icon64 data:text/plain;base64,SGVsbG8=
1810
+ + // @icon64 data:image/png;base64,iVBORw0KGgo=
1811
+ - // @defaulticon ftp://example.com/icon.png
1812
+ + // @defaulticon https://example.com/icon.png
1813
+ // ==/UserScript==
1814
+ ```
1815
+
1816
+ #### When not to use it
1817
+
1818
+ If you intentionally use URL schemes outside `http(s)`, `data:`, and relative paths.
1819
+
1820
+ #### Introduced in
1821
+
1822
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
1823
+
1824
+ #### See also
1825
+
1826
+ - [`no-invalid-headers`](#no-invalid-headers)
1827
+ <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>
1828
+ <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>
1829
+ <a title="Optimized in violentmonkey config" href="#usage"><img height=14 alt="[Violentmonkey]" src="https://img.shields.io/badge/Violentmonkey-c68a3c?style=flat-square" align="middle"></a>
1830
+ <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>
1831
+ <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>
1832
+ <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>
1833
+ <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>
1834
+ - <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=icon">Tampermonkey — `@icon`, `@icon64`</a>
1835
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64">&ensp;<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data">MDN — `data:` URLs</a>
1836
+
1837
+ <div align="center">
1838
+
1839
+ [Back to index ↑][epg-rules]
1840
+
1841
+ </div>
1842
+
1843
+ ---
1844
+
1845
+ </details>
1846
+
1847
+ <h3 id="valid-license-header">
1848
+ <code>valid-license-header</code>
1849
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
1850
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1851
+ <a title="Included in recommended config" href="#usage">
1852
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1853
+ <a title="Accepts array w/ options" href="#usage">
1854
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1855
+ <a title="Copy rule URL" target="_blank"
1856
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23valid-license-header">
1857
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1858
+ </h3>
1859
+
1860
+ <details>
1861
+
1862
+ <summary>Validates <code>@license</code> values against the SPDX license list.</summary>
1863
+
1864
+ <h4 id="valid-license-header-options">Options</h4>
1865
+
1866
+ - `allowedLicenses` (default `[]`) – <a target="_blank" href="https://spdx.org/licenses/">SPDX license IDs</a> to restrict to (e.g. `['Apache-2.0', 'MIT']`), as a single string or array
1867
+
1868
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1869
+
1870
+ ```diff
1871
+ // ==UserScript==
1872
+ // @name My Script
1873
+ ! // @license mit
1874
+ // ==/UserScript==
1875
+ ```
1876
+
1877
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1878
+
1879
+ ```diff
1880
+ // ==UserScript==
1881
+ // @name My Script
1882
+ - // @license mit
1883
+ + // @license MIT
1884
+ // ==/UserScript==
1885
+ ```
1886
+
1887
+ #### When not to use it
1888
+
1889
+ If your `@license` uses a custom identifier that isn't a valid SPDX value.
1890
+
1891
+ #### Introduced in
1892
+
1893
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
1894
+
1895
+ #### See also
1896
+
1897
+ - [`require-license-header`](#require-license-header)
1898
+ <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>
1899
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=spdx.org&sz=64">&ensp;<a target="_blank" href="https://spdx.org/licenses/">SPDX — License List</a>
1900
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=spdx.org&sz=64">&ensp;<a target="_blank" href="https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/">SPDX — License Expressions</a>
1901
+
1902
+ <div align="center">
1903
+
1904
+ [Back to index ↑][epg-rules]
1905
+
1906
+ </div>
1907
+
1908
+ ---
1909
+
1910
+ </details>
1911
+
1912
+ <h3 id="valid-url-headers">
1913
+ <code>valid-url-headers</code>
1914
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
1915
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1916
+ <a title="Included in recommended config" href="#usage">
1917
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1918
+ <a title="Accepts array w/ options" href="#usage">
1919
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1920
+ <a title="Copy rule URL" target="_blank"
1921
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23valid-url-headers">
1922
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1923
+ </h3>
1924
+
1925
+ <details>
1926
+
1927
+ <summary>Validates URLs and match patterns in metadata headers.</summary>
1928
+
1929
+ <h4 id="valid-url-headers-options">Options</h4>
1930
+
1931
+ - `checkURLfields` (default `true`) – validate URL fields (`@homepage`, `@require`, `@require-css`, `@resource`, `@source`, `@website`, and any header ending in `url`)
1932
+ - `checkMatchPatterns` (default `true`) – validate match patterns (`@match`, `@include`, `@exclude`, `@exclude-match`)
1933
+ - `allowedSchemes` (default `['http', 'https', 'file', 'ftp', 'http*']`) – permitted URL schemes for match patterns, as a single string or array
1934
+ - `allowBroadPatterns` (default `false`) – permit unrestricted patterns (`*://*/*`, `http*://*/*`, `https://*/*`)
1935
+
1936
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
1937
+
1938
+ ```diff
1939
+ // ==UserScript==
1940
+ // @name My Script
1941
+ ! // @match *://*foo.com/*
1942
+ ! // @match https://example.com
1943
+ ! // @require not-a-valid-url
1944
+ ! // @homepageURL example.com
1945
+ ! // @resource myCSS not-a-url
1946
+ // ==/UserScript==
1947
+ ```
1948
+
1949
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
1950
+
1951
+ ```diff
1952
+ // ==UserScript==
1953
+ // @name My Script
1954
+ - // @match *://*foo.com/*
1955
+ + // @match *://*.foo.com/*
1956
+ - // @match https://example.com
1957
+ + // @match https://example.com/*
1958
+ - // @require not-a-valid-url
1959
+ + // @require https://cdn.example.com/lib.js
1960
+ - // @homepageURL example.com
1961
+ + // @homepageURL https://example.com
1962
+ - // @resource myCSS not-a-url
1963
+ + // @resource myCSS https://example.com/style.css
1964
+ // ==/UserScript==
1965
+ ```
1966
+
1967
+ #### When not to use it
1968
+
1969
+ If your URLs or patterns are generated at build time.
1970
+
1971
+ #### Introduced in
1972
+
1973
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
1974
+
1975
+ #### See also
1976
+
1977
+ - [`valid-field-values`](#valid-field-values)
1978
+ <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>
1979
+ <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>
1980
+ - [`valid-icon-headers`](#valid-icon-headers)
1981
+ <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>
1982
+ - <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=include#meta:match">Tampermonkey — `@match`</a>
1983
+ - <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=include#meta:include">Tampermonkey — `@include`</a>
1984
+
1985
+ <div align="center">
1986
+
1987
+ [Back to index ↑][epg-rules]
1988
+
1989
+ </div>
1990
+
1991
+ ---
1992
+
1993
+ </details>
1994
+
1995
+ <h3 id="valid-version-header">
1996
+ <code>valid-version-header</code>
1997
+ <a title="Introduced in latest minor release" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">
1998
+ <img height=16 align="middle" src="https://api.iconify.design/mdi/sprout.svg?color=%234a4a4a"></a>
1999
+ <a title="Included in recommended config" href="#usage">
2000
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
2001
+ <a title="Accepts array w/ options" href="#usage">
2002
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
2003
+ <a title="Copy rule URL" target="_blank"
2004
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-greasemonkey%2F%23valid-version-header">
2005
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
2006
+ </h3>
2007
+
2008
+ <details>
2009
+
2010
+ <summary>Validates the <code>@version</code> metadata field.</summary>
2011
+
2012
+ <h4 id="valid-version-header-options">Options</h4>
2013
+
2014
+ - `versionType` (default `'semver'`) – version format to enforce (`'semver'`, `'date'`)
2015
+ - `allowFutureDate` (default `false`) – allow `@version` dates later than the current date
2016
+ - `timezone` (default `''`) – <a target="_blank" href="https://data.iana.org/time-zones/tzdb/zone1970.tab">IANA timezone</a> used to determine the current date (when omitted, only year/month are enforced)
2017
+
2018
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/gray.svg" align="bottom"> Incorrect code
2019
+
2020
+ ```diff
2021
+ /* eslint greasemonkey/valid-version-header: ['error', { versionType: 'date' }] */
2022
+
2023
+ // ==UserScript==
2024
+ // @name My Script
2025
+ ! // @version 2026.1.111
2026
+ // ==/UserScript==
2027
+ ```
2028
+
2029
+ #### <img width=13 height=13 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/99f14247b2/assets/images/icons/square/with-symbol/green.svg" align="bottom"> Correct code
2030
+
2031
+ ```diff
2032
+ /* eslint greasemonkey/valid-version-header: ['error', { versionType: 'date' }] */
2033
+
2034
+ // ==UserScript==
2035
+ // @name My Script
2036
+ - // @version 2026.1.111
2037
+ + // @version 2026.10.3
2038
+ // ==/UserScript==
2039
+ ```
2040
+
2041
+ #### When not to use it
2042
+
2043
+ If you use a custom versioning scheme, or your `@version` is injected at build time.
2044
+
2045
+ #### Introduced in
2046
+
2047
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/releases/tag/v1.10.0">v1.10.0</a> (October 22, 2026)
2048
+
2049
+ #### See also
2050
+
2051
+ - [`require-required-fields`](#require-required-fields)
2052
+ <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>
2053
+ <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>
2054
+ - <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=version">Tampermonkey — `@version`</a>
2055
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=wiki.greasespot.net&sz=64">&ensp;<a target="_blank" href="https://wiki.greasespot.net/Metadata_Block#.40version">Greasemonkey — `@version`</a>
2056
+
2057
+ <div align="center">
2058
+
2059
+ [Back to index ↑][epg-rules]
2060
+
2061
+ </div>
2062
+
1595
2063
  </details>
1596
2064
 
1597
2065
  ---
@@ -1618,8 +2086,8 @@ If you use a custom versioning scheme or URLs that aren't standard.
1618
2086
 
1619
2087
  ## <img height=30 width=27 align="top" src="https://api.iconify.design/ic/baseline-account-balance.svg?color=%232b2b2a"> License
1620
2088
 
1621
- <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/src/branch/main/docs/LICENSE.md">
1622
- <img height=80 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-greasemonkey/9e820e5d51/assets/images/logos/mit-license/red-pixelated.png"></a>
2089
+ <a href="https://codeberg.org/adamlui/eslint-plugin-greasemonkey/src/branch/main/docs/LICENSE.md">
2090
+ <img height=88 src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-chrome-extensions/d79e1db7e2/assets/images/banners/mit-license/banner.png"></a>
1623
2091
  <br><br>
1624
2092
 
1625
2093
  <details>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-greasemonkey",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "ESLint rules for Greasemonkey/Tampermonkey userscripts",
5
5
  "keywords": [
6
6
  "eslint",
@@ -60,25 +60,29 @@
60
60
  "lint:all": "pre-commit run --all-files",
61
61
  "test": "node tests/run"
62
62
  },
63
+ "dependencies": {
64
+ "spdx-license-ids": "^3.0.24",
65
+ "spdx-license-list": "^6.12.0"
66
+ },
63
67
  "devDependencies": {
64
68
  "@e18e/eslint-plugin": "^0.8.1",
65
- "@eslint/js": "^10.0.1",
66
69
  "@eslint/json": "^2.1.1",
67
70
  "@eslint/markdown": "^7.5.1",
68
71
  "@stylistic/eslint-plugin": "^5.10.0",
69
- "eslint": "^10.12.0",
70
- "eslint-plugin-constructors": "^1.4.3",
72
+ "eslint": "^10.13.0",
73
+ "eslint-plugin-constructors": "^1.5.0",
71
74
  "eslint-plugin-eslint-plugin": "^7.6.2",
72
75
  "eslint-plugin-import-x": "^4.17.1",
73
- "eslint-plugin-n": "^18.4.1",
76
+ "eslint-plugin-n": "^18.5.0",
74
77
  "eslint-plugin-no-secrets": "^2.3.3",
75
78
  "eslint-plugin-no-unsanitized": "^4.1.5",
76
79
  "eslint-plugin-package-json": "^1.10.1",
77
80
  "eslint-plugin-promise": "^7.3.0",
78
81
  "eslint-plugin-regexp": "^3.3.1",
79
82
  "eslint-plugin-security": "^4.2.0",
80
- "eslint-plugin-woodpecker": "^1.0.1",
81
- "globals": "^17.13.0"
83
+ "eslint-plugin-sonarjs": "^4.2.2",
84
+ "eslint-plugin-woodpecker": "^1.1.0",
85
+ "oxlint": "^1.89.0"
82
86
  },
83
87
  "peerDependencies": {
84
88
  "eslint": ">=9.0.0"