eslint-plugin-chrome-extensions 2.5.0 → 2.6.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
@@ -6,6 +6,8 @@
6
6
  <img alt="[Latest Build]" src="https://img.shields.io/npm/v/eslint-plugin-chrome-extensions?logo=icinga&style=for-the-badge&label=Latest%20Build&color=32fcee"></a>
7
7
  <a href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/src/branch/main/docs/LICENSE.md">
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 target="_blank" href="https://getnpmstats.com/?package=eslint-plugin-chrome-extensions&range=last-year&interval=monthly">
10
+ <img src="https://img.shields.io/npm/dm/eslint-plugin-chrome-extensions?style=for-the-badge&logo=npm&color=black"></a>
9
11
  <a target="_blank" href="https://eslint.org/">
10
12
  <img alt="[Requires ESLint >=9.6.0]" src="https://img.shields.io/badge/Requires-ESLint_%3E%3D9.6.0-4B32C3?style=for-the-badge&logo=eslint"></a>
11
13
  <br><br>
@@ -84,7 +86,7 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
84
86
  <img height=18 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
85
87
  <a title="Accepts array w/ options" href="#usage">
86
88
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
87
- <a title="Copy rule URL" target="_blank"
89
+ <a title="Copy rule URL" target="_blank"
88
90
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23manifest-key-order">
89
91
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
90
92
  </h3>
@@ -95,13 +97,13 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
95
97
 
96
98
  <h4 id="manifest-key-order-options">Options</h4>
97
99
 
98
- - `order` (default `[]`) – manifest keys in custom order (e.g. `['name', 'manifest_version']`) to selectively override built-in order with
100
+ - `order` (default `[]`) – manifest keys in custom order (e.g. `['name', 'manifest_version']`) to selectively override built-in order with <a title="Introduced in v2.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.0.0"><img height=14 alt="[Since v2.0.0]" src="https://img.shields.io/badge/since-v2.0.0-8a9199?style=flat-square" align="middle"></a>
99
101
 
100
102
  #### <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
101
103
 
102
104
  ```diff
103
105
  /* eslint chrome-extensions/manifest-key-order: ['error', { order: ['name', 'manifest_version'] }] */
104
-
106
+
105
107
  {
106
108
  ! "manifest_version": 3,
107
109
  "name": "My Extension",
@@ -113,7 +115,7 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
113
115
 
114
116
  ```diff
115
117
  /* eslint chrome-extensions/manifest-key-order: ['error', { order: ['name', 'manifest_version'] }] */
116
-
118
+
117
119
  {
118
120
  - "manifest_version": 3,
119
121
  "name": "My Extension",
@@ -159,7 +161,7 @@ If you don't care about the order of manifest keys.
159
161
  <img height=18 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
160
162
  <a title="Accepts array w/ options" href="#usage">
161
163
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
162
- <a title="Copy rule URL" target="_blank"
164
+ <a title="Copy rule URL" target="_blank"
163
165
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23manifest-spacing">
164
166
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
165
167
  </h3>
@@ -170,17 +172,17 @@ If you don't care about the order of manifest keys.
170
172
 
171
173
  <h4 id="manifest-spacing-options">Options</h4>
172
174
 
173
- - `spaces` (default `2`) – number of spaces per indent level
174
- - `checkColons` (default `true`) – enforce 0 spaces before and 1 space after `:` in key/value pairs
175
- - `checkCommas` (default `true`) – enforce 0 spaces before and 1 space after `,` in inline objects
176
- - `checkBraces` (default `true`) – enforce 1 space after `{` and before `}` in inline objects
177
- - `checkBrackets` (default `true`) – enforce 0 spaces after `[` and before `]` in inline arrays
175
+ - `spaces` (default `2`) – number of spaces per indent level <a title="Introduced in v2.2.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0"><img height=14 alt="[Since v2.2.0]" src="https://img.shields.io/badge/since-v2.2.0-8a9199?style=flat-square" align="middle"></a>
176
+ - `checkColons` (default `true`) – enforce 0 spaces before and 1 space after `:` in key/value pairs <a title="Introduced in v2.2.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0"><img height=14 alt="[Since v2.2.0]" src="https://img.shields.io/badge/since-v2.2.0-8a9199?style=flat-square" align="middle"></a>
177
+ - `checkCommas` (default `true`) – enforce 0 spaces before and 1 space after `,` in inline objects <a title="Introduced in v2.2.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0"><img height=14 alt="[Since v2.2.0]" src="https://img.shields.io/badge/since-v2.2.0-8a9199?style=flat-square" align="middle"></a>
178
+ - `checkBraces` (default `true`) – enforce 1 space after `{` and before `}` in inline objects <a title="Introduced in v2.2.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0"><img height=14 alt="[Since v2.2.0]" src="https://img.shields.io/badge/since-v2.2.0-8a9199?style=flat-square" align="middle"></a>
179
+ - `checkBrackets` (default `true`) – enforce 0 spaces after `[` and before `]` in inline arrays <a title="Introduced in v2.2.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0"><img height=14 alt="[Since v2.2.0]" src="https://img.shields.io/badge/since-v2.2.0-8a9199?style=flat-square" align="middle"></a>
178
180
 
179
181
  #### <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
180
182
 
181
183
  ```diff
182
184
  /* eslint chrome-extensions/manifest-spacing: ['error', { spaces: 2 }] */
183
-
185
+
184
186
  {
185
187
  ! "manifest_version": 3,
186
188
  ! "version" : "1.0.0",
@@ -194,7 +196,7 @@ If you don't care about the order of manifest keys.
194
196
 
195
197
  ```diff
196
198
  /* eslint chrome-extensions/manifest-spacing: ['error', { spaces: 2 }] */
197
-
199
+
198
200
  {
199
201
  - "manifest_version": 3,
200
202
  + "manifest_version": 3,
@@ -240,7 +242,7 @@ If you don't care about visual consistency in your manifest.
240
242
  <code>no-content-style-leak</code>
241
243
  <a title="Only included in strict config" href="#usage">
242
244
  <img height=18 alt="[Strict only]" src="https://img.shields.io/badge/Strict_only-ff8c42?style=flat-square" align="middle"></a>
243
- <a title="Copy rule URL" target="_blank"
245
+ <a title="Copy rule URL" target="_blank"
244
246
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-content-style-leak">
245
247
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
246
248
  </h3>
@@ -294,7 +296,7 @@ If you intentionally interact w/ host page styles.
294
296
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
295
297
  <a title="Accepts array w/ options" href="#usage">
296
298
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
297
- <a title="Copy rule URL" target="_blank"
299
+ <a title="Copy rule URL" target="_blank"
298
300
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-deprecated-apis">
299
301
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
300
302
  </h3>
@@ -305,14 +307,14 @@ If you intentionally interact w/ host page styles.
305
307
 
306
308
  <h4 id="no-deprecated-apis-options">Options</h4>
307
309
 
308
- - `target` (default `'mv3'`) – Chrome extension manifest version whose deprecations to validate against (`'mv3'`, `'mv2'`)
309
- - `allowedAPIs` (default `[]`) – additional deprecated API namespaces to allow, as a single string or array
310
+ - `target` (default `'mv3'`) – Chrome extension manifest version whose deprecations to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
311
+ - `allowedAPIs` (default `[]`) – additional deprecated API namespaces to allow, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
310
312
 
311
313
  #### <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
312
314
 
313
315
  ```diff
314
316
  /* eslint chrome-extensions/no-deprecated-apis: ['error', { target: 'mv3' }] */
315
-
317
+
316
318
  ! chrome.pageAction.show(tabId)
317
319
  ! chrome.extension.getBackgroundPage().doThing()
318
320
  ! chrome.tabs.executeScript(tabId, { code: 'doThing()' })
@@ -357,7 +359,7 @@ If you don't want deprecation validation at all. For individual deprecated APIs
357
359
  <code>no-duplicate-manifest-keys</code>
358
360
  <a title="Only works in 'json/json' config block" href="#usage">
359
361
  <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
360
- <a title="Copy rule URL" target="_blank"
362
+ <a title="Copy rule URL" target="_blank"
361
363
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-duplicate-manifest-keys">
362
364
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
363
365
  </h3>
@@ -407,7 +409,8 @@ If you rely on a Chromium fork resolving duplicate keys in a specific order.
407
409
  <a title="Doesn't prevent bugs" href="#manifest-key-order"><img height=14 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
408
410
  <a title="Accepts array w/ options" href="#manifest-key-order-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
409
411
  - [`no-unused-permissions`](#no-unused-permissions)
410
- <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
412
+ <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>
413
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
411
414
 
412
415
  <div align="center">
413
416
 
@@ -425,7 +428,7 @@ If you rely on a Chromium fork resolving duplicate keys in a specific order.
425
428
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
426
429
  <a title="Included in security config" href="#usage">
427
430
  <img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
428
- <a title="Copy rule URL" target="_blank"
431
+ <a title="Copy rule URL" target="_blank"
429
432
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-insecure-fetch">
430
433
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
431
434
  </h3>
@@ -480,7 +483,7 @@ If you intentionally target HTTP endpoints.
480
483
  <img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
481
484
  <a title="Accepts array w/ options" href="#usage">
482
485
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
483
- <a title="Copy rule URL" target="_blank"
486
+ <a title="Copy rule URL" target="_blank"
484
487
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-insecure-messaging">
485
488
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
486
489
  </h3>
@@ -491,7 +494,7 @@ If you intentionally target HTTP endpoints.
491
494
 
492
495
  <h4 id="no-insecure-messaging-options">Options</h4>
493
496
 
494
- - `disallowWildcardTarget` (default `true`) – flag <code>postMessage()</code> calls that use <code>'*'</code> as <code>targetOrigin</code>
497
+ - `disallowWildcardTarget` (default `true`) – flag <code>postMessage()</code> calls that use <code>'*'</code> as <code>targetOrigin</code> <a title="Introduced in v2.1.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0"><img height=14 alt="[Since v2.1.0]" src="https://img.shields.io/badge/since-v2.1.0-8a9199?style=flat-square" align="middle"></a>
495
498
 
496
499
  #### <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
497
500
 
@@ -557,6 +560,79 @@ If you trust every external caller and open tab, or you intentionally broadcast
557
560
 
558
561
  </details>
559
562
 
563
+ <h3 id="no-invalid-locales">
564
+ <code>no-invalid-locales</code>
565
+ <a title="Included in recommended config" href="#usage">
566
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
567
+ <a title="Works in 'json/json' config block" href="#usage">
568
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
569
+ <a title="Accepts array w/ options" href="#usage">
570
+ <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
571
+ <a title="Copy rule URL" target="_blank"
572
+ href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-invalid-locales">
573
+ <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
574
+ </h3>
575
+
576
+ <details>
577
+
578
+ <summary>Disallows invalid Chrome locale codes in <code>_locales/</code> folders and <code>default_locale</code>.</summary>
579
+
580
+ <h4 id="no-invalid-locales-options">Options</h4>
581
+
582
+ - `allowedLocales` (default `[]`) – additional locale codes to allow, as a single string or array <a title="Introduced in v2.6.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.6.0"><img height=14 alt="[Since v2.6.0]" src="https://img.shields.io/badge/since-v2.6.0-8a9199?style=flat-square" align="middle"></a>
583
+
584
+ #### <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
585
+
586
+ ```diff
587
+ // manifest.json
588
+ {
589
+ "manifest_version": 3,
590
+ ! "default_locale": "pt-BR"
591
+ }
592
+
593
+ ! // _locales/pt-BR/messages.json
594
+ ```
595
+
596
+ #### <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
597
+
598
+ ```diff
599
+ // manifest.json
600
+ {
601
+ "manifest_version": 3,
602
+ - "default_locale": "pt-BR"
603
+ + "default_locale": "pt_BR"
604
+ }
605
+
606
+ - // _locales/pt-BR/messages.json
607
+ + // _locales/pt_BR/messages.json
608
+ ```
609
+
610
+ #### When not to use it
611
+
612
+ If your `_locales/` is externally populated at build time. If you target a Chromium fork w/ additional supported locales, prefer `allowedLocales` over disabling the rule.
613
+
614
+ #### Introduced in
615
+
616
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.6.0">v2.6.0</a> (October 16, 2026)
617
+
618
+ #### See also
619
+
620
+ - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/i18n">Chrome for Developers — `i18n`</a>
621
+ - [`no-missing-default-locale`](#no-missing-default-locale)
622
+ <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>
623
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
624
+ <a title="Accepts array w/ options" href="#no-missing-default-locale-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
625
+
626
+ <div align="center">
627
+
628
+ [Back to index ↑][epce-rules]
629
+
630
+ </div>
631
+
632
+ ---
633
+
634
+ </details>
635
+
560
636
  <h3 id="no-invalid-permissions">
561
637
  <code>no-invalid-permissions</code>
562
638
  <a title="Included in recommended config" href="#usage">
@@ -565,7 +641,7 @@ If you trust every external caller and open tab, or you intentionally broadcast
565
641
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
566
642
  <a title="Accepts array w/ options" href="#usage">
567
643
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
568
- <a title="Copy rule URL" target="_blank"
644
+ <a title="Copy rule URL" target="_blank"
569
645
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-invalid-permissions">
570
646
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
571
647
  </h3>
@@ -576,14 +652,14 @@ If you trust every external caller and open tab, or you intentionally broadcast
576
652
 
577
653
  <h4 id="no-invalid-permissions-options">Options</h4>
578
654
 
579
- - `target` (default `'mv3'`) – Chrome manifest version whose permissions to validate against (`'mv3'`, `'mv2'`)
580
- - `allowedPermissions` (default `[]`) – additional permission names to allow beyond the built-in list, as a single string or array
655
+ - `target` (default `'mv3'`) – Chrome manifest version whose permissions to validate against (`'mv3'`, `'mv2'`) <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
656
+ - `allowedPermissions` (default `[]`) – additional permission names to allow beyond the built-in list, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
581
657
 
582
658
  #### <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
583
659
 
584
660
  ```diff
585
661
  /* eslint chrome-extensions/no-invalid-permissions: ['error', { target: 'mv3' }] */
586
-
662
+
587
663
  {
588
664
  ! "permissions": ["browserAction", "tabs"],
589
665
  ! "optional_permissions": ["history", "pageAction"]
@@ -594,7 +670,7 @@ If you trust every external caller and open tab, or you intentionally broadcast
594
670
 
595
671
  ```diff
596
672
  /* eslint chrome-extensions/no-invalid-permissions: ['error', { target: 'mv3' }] */
597
-
673
+
598
674
  {
599
675
  - "permissions": ["browserAction", "tabs"],
600
676
  + "permissions": ["tabs"],
@@ -616,7 +692,8 @@ If you don't want permission validation at all. For custom permissions from a Ch
616
692
  - [`no-missing-permissions`](#no-missing-permissions)
617
693
  <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>
618
694
  - [`no-unused-permissions`](#no-unused-permissions)
619
- <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
695
+ <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>
696
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
620
697
 
621
698
  <div align="center">
622
699
 
@@ -630,11 +707,13 @@ If you don't want permission validation at all. For custom permissions from a Ch
630
707
 
631
708
  <h3 id="no-missing-default-locale">
632
709
  <code>no-missing-default-locale</code>
633
- <a title="Only works in 'json/json' config block" href="#usage">
634
- <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
710
+ <a title="Included in recommended config" href="#usage">
711
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
712
+ <a title="Works in 'json/json' config block" href="#usage">
713
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
635
714
  <a title="Accepts array w/ options" href="#usage">
636
715
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
637
- <a title="Copy rule URL" target="_blank"
716
+ <a title="Copy rule URL" target="_blank"
638
717
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-missing-default-locale">
639
718
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
640
719
  </h3>
@@ -645,7 +724,8 @@ If you don't want permission validation at all. For custom permissions from a Ch
645
724
 
646
725
  <h4 id="no-missing-default-locale-options">Options</h4>
647
726
 
648
- - `ignoreKeys` (default `[]`) – keys to skip when checking the default locale
727
+ - `ignoreKeys` (default `[]`) – keys to skip when checking locales <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
728
+ - `checkAllLocales` (default `false`) – also flag keys missing from any locale <a title="Introduced in v2.6.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.6.0"><img height=14 alt="[Since v2.6.0]" src="https://img.shields.io/badge/since-v2.6.0-8a9199?style=flat-square" align="middle"></a>
649
729
 
650
730
  #### <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
651
731
 
@@ -723,17 +803,9 @@ If your `_locales/` is externally populated at build time.
723
803
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
724
804
  <a title="Works in 'css/css' config block" href="#usage">
725
805
  <img height=18 alt="[CSS]" src="https://img.shields.io/badge/CSS-dcd6f7?style=flat-square" align="middle"></a>
726
- <a title="Works in 'html/html' config block" href="#usage">
727
- <img height=18 alt="[HTML]" src="https://img.shields.io/badge/HTML-a8d8ea?style=flat-square" align="middle"></a>
728
- <a title="Works in 'json/json' config block" href="#usage">
729
- <img height=18 alt="[JSON]" src="https://img.shields.io/badge/JSON-a8e6cf?style=flat-square" align="middle"></a>
730
- <a title="Works in 'json/json5' config block" href="#usage">
731
- <img height=18 alt="[JSON5]" src="https://img.shields.io/badge/JSON5-c7e6b8?style=flat-square" align="middle"></a>
732
- <a title="Works in 'json/jsonc' config block" href="#usage">
733
- <img height=18 alt="[JSONC]" src="https://img.shields.io/badge/JSONC-e6e6a8?style=flat-square" align="middle"></a>
734
806
  <a title="Accepts array w/ options" href="#usage">
735
807
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
736
- <a title="Copy rule URL" target="_blank"
808
+ <a title="Copy rule URL" target="_blank"
737
809
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-missing-i18n-keys">
738
810
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
739
811
  </h3>
@@ -744,7 +816,7 @@ If your `_locales/` is externally populated at build time.
744
816
 
745
817
  <h4 id="no-missing-i18n-keys-options">Options</h4>
746
818
 
747
- - `ignoreKeys` (default `[]`) – keys to skip (e.g. `['customKey']`)
819
+ - `ignoreKeys` (default `[]`) – keys to skip (e.g. `['customKey']`) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
748
820
 
749
821
  #### <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
750
822
 
@@ -811,7 +883,7 @@ If your `_locales/` is externally populated at build time.
811
883
  <code>no-missing-permissions</code>
812
884
  <a title="Included in recommended config" href="#usage">
813
885
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
814
- <a title="Copy rule URL" target="_blank"
886
+ <a title="Copy rule URL" target="_blank"
815
887
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-missing-permissions">
816
888
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
817
889
  </h3>
@@ -862,7 +934,8 @@ If you use APIs through aliases or wrappers that obscure the original call site.
862
934
  <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
863
935
  <a title="Accepts array w/ options" href="#no-invalid-permissions-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
864
936
  - [`no-unused-permissions`](#no-unused-permissions)
865
- <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
937
+ <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>
938
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
866
939
 
867
940
  <div align="center">
868
941
 
@@ -878,7 +951,7 @@ If you use APIs through aliases or wrappers that obscure the original call site.
878
951
  <code>no-missing-web-accessible-resources</code>
879
952
  <a title="Included in recommended config" href="#usage">
880
953
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
881
- <a title="Copy rule URL" target="_blank"
954
+ <a title="Copy rule URL" target="_blank"
882
955
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-missing-web-accessible-resources">
883
956
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
884
957
  </h3>
@@ -945,7 +1018,7 @@ If your paths are built at runtime.
945
1018
  <img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
946
1019
  <a title="Accepts array w/ options" href="#usage">
947
1020
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
948
- <a title="Copy rule URL" target="_blank"
1021
+ <a title="Copy rule URL" target="_blank"
949
1022
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-remote-code">
950
1023
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
951
1024
  </h3>
@@ -956,8 +1029,8 @@ If your paths are built at runtime.
956
1029
 
957
1030
  <h4 id="no-remote-code-options">Options</h4>
958
1031
 
959
- - `patterns` (default `['eval', 'new-function', 'string-timer', 'dynamic-import', 'remote-script-src', 'execute-script-url']`) – detection paths to enable, as a single string or array
960
- - `checkExecuteScriptClosures` (default `true`) – additionally flag <code>chrome.scripting.executeScript({ func })</code> bodies that capture outer-scope variables
1032
+ - `patterns` (default `['eval', 'new-function', 'string-timer', 'dynamic-import', 'remote-script-src', 'execute-script-url']`) – detection paths to enable, as a single string or array <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
1033
+ - `checkExecuteScriptClosures` (default `true`) – additionally flag <code>chrome.scripting.executeScript({ func })</code> bodies that capture outer-scope variables <a title="Introduced in v1.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0"><img height=14 alt="[Since v1.0.0]" src="https://img.shields.io/badge/since-v1.0.0-6b8e6b?style=flat-square&labelColor=464646" align="middle"></a>
961
1034
 
962
1035
  #### <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
963
1036
 
@@ -1018,18 +1091,18 @@ If you intentionally target forks w/ relaxed CSPs. For individual patterns you s
1018
1091
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1019
1092
  <a title="Accepts array w/ options" href="#usage">
1020
1093
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1021
- <a title="Copy rule URL" target="_blank"
1094
+ <a title="Copy rule URL" target="_blank"
1022
1095
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-sensitive-permissions">
1023
1096
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1024
1097
  </h3>
1025
1098
 
1026
1099
  <details>
1027
1100
 
1028
- <summary>Flags sensitive manifest permissions that warrant security review.</summary>
1101
+ <summary>Flags sensitive manifest permissions.</summary>
1029
1102
 
1030
1103
  <h4 id="no-sensitive-permissions-options">Options</h4>
1031
1104
 
1032
- - `allowedPermissions` (default `[]`) – sensitive permission names to explicitly allow, as a single string or array
1105
+ - `allowedPermissions` (default `[]`) – sensitive permission names to explicitly allow, as a single string or array <a title="Introduced in v2.5.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.5.0"><img height=14 alt="[Since v2.5.0]" src="https://img.shields.io/badge/since-v2.5.0-8a9199?style=flat-square" align="middle"></a>
1033
1106
 
1034
1107
  #### <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
1035
1108
 
@@ -1056,7 +1129,7 @@ If you legitimately require sensitive permissions, or prefer manual security rev
1056
1129
 
1057
1130
  #### Introduced in
1058
1131
 
1059
- v2.5.0 (Unreleased)
1132
+ <a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.5.0">v2.5.0</a> (October 15, 2026)
1060
1133
 
1061
1134
  #### See also
1062
1135
 
@@ -1065,7 +1138,8 @@ v2.5.0 (Unreleased)
1065
1138
  <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1066
1139
  <a title="Accepts array w/ options" href="#no-invalid-permissions-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1067
1140
  - [`no-unused-permissions`](#no-unused-permissions)
1068
- <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1141
+ <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>
1142
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1069
1143
  - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions">Chrome for Developers — Declare permissions</a>
1070
1144
 
1071
1145
  <div align="center">
@@ -1080,11 +1154,15 @@ v2.5.0 (Unreleased)
1080
1154
 
1081
1155
  <h3 id="no-unrestricted-host-permissions">
1082
1156
  <code>no-unrestricted-host-permissions</code>
1083
- <a title="Only works in 'json/json' config block" href="#usage">
1084
- <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1157
+ <a title="Included in recommended config" href="#usage">
1158
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1159
+ <a title="Included in security config" href="#usage">
1160
+ <img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
1161
+ <a title="Works in 'json/json' config block" href="#usage">
1162
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1085
1163
  <a title="Accepts array w/ options" href="#usage">
1086
1164
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1087
- <a title="Copy rule URL" target="_blank"
1165
+ <a title="Copy rule URL" target="_blank"
1088
1166
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-unrestricted-host-permissions">
1089
1167
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1090
1168
  </h3>
@@ -1095,7 +1173,7 @@ v2.5.0 (Unreleased)
1095
1173
 
1096
1174
  <h4 id="no-unrestricted-host-permissions-options">Options</h4>
1097
1175
 
1098
- - `allowedPatterns` (default `[]`) – host patterns to explicitly allow (e.g. `['<all_urls>']`)
1176
+ - `allowedPatterns` (default `[]`) – host patterns to explicitly allow (e.g. `['<all_urls>']`) <a title="Introduced in v2.1.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0"><img height=14 alt="[Since v2.1.0]" src="https://img.shields.io/badge/since-v2.1.0-8a9199?style=flat-square" align="middle"></a>
1099
1177
 
1100
1178
  #### <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
1101
1179
 
@@ -1148,7 +1226,7 @@ If you legitimately need broad access (e.g. ad blockers or dev tools).
1148
1226
  <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1149
1227
  <a title="Accepts array w/ options" href="#usage">
1150
1228
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1151
- <a title="Copy rule URL" target="_blank"
1229
+ <a title="Copy rule URL" target="_blank"
1152
1230
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-unused-i18n-keys">
1153
1231
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1154
1232
  </h3>
@@ -1159,8 +1237,8 @@ If you legitimately need broad access (e.g. ad blockers or dev tools).
1159
1237
 
1160
1238
  <h4 id="no-unused-i18n-keys-options">Options</h4>
1161
1239
 
1162
- - `ignoreKeys` (default `[]`) – keys to always treat as used (e.g. `['customKey']`)
1163
- - `scanExtensions` (default `['cjs', 'css', 'htm', 'html', 'js', 'json', 'jsx', 'md', 'mjs', 'svg', 'ts', 'tsx', 'txt']`) – file extensions to scan for references
1240
+ - `ignoreKeys` (default `[]`) – keys to always treat as used (e.g. `['customKey']`) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1241
+ - `scanExtensions` (default `['cjs', 'css', 'htm', 'html', 'js', 'json', 'jsx', 'md', 'mjs', 'svg', 'ts', 'tsx', 'txt']`) – file extensions to scan for references <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1164
1242
 
1165
1243
  #### <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
1166
1244
 
@@ -1202,10 +1280,6 @@ If your i18n keys are referenced dynamically.
1202
1280
  <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>
1203
1281
  <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1204
1282
  <a title="Works in 'css/css' config block" href="#usage"><img height=14 alt="[CSS]" src="https://img.shields.io/badge/CSS-dcd6f7?style=flat-square" align="middle"></a>
1205
- <a title="Works in 'html/html' config block" href="#usage"><img height=14 alt="[HTML]" src="https://img.shields.io/badge/HTML-a8d8ea?style=flat-square" align="middle"></a>
1206
- <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[JSON]" src="https://img.shields.io/badge/JSON-a8e6cf?style=flat-square" align="middle"></a>
1207
- <a title="Works in 'json/json5' config block" href="#usage"><img height=14 alt="[JSON5]" src="https://img.shields.io/badge/JSON5-c7e6b8?style=flat-square" align="middle"></a>
1208
- <a title="Works in 'json/jsonc' config block" href="#usage"><img height=14 alt="[JSONC]" src="https://img.shields.io/badge/JSONC-e6e6a8?style=flat-square" align="middle"></a>
1209
1283
  <a title="Accepts array w/ options" href="#no-missing-i18n-keys-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1210
1284
  - <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64">&ensp;<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/i18n">Chrome for Developers — `i18n`</a>
1211
1285
 
@@ -1221,9 +1295,11 @@ If your i18n keys are referenced dynamically.
1221
1295
 
1222
1296
  <h3 id="no-unused-permissions">
1223
1297
  <code>no-unused-permissions</code>
1224
- <a title="Only works in 'json/json' config block" href="#usage">
1225
- <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1226
- <a title="Copy rule URL" target="_blank"
1298
+ <a title="Included in recommended config" href="#usage">
1299
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1300
+ <a title="Works in 'json/json' config block" href="#usage">
1301
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1302
+ <a title="Copy rule URL" target="_blank"
1227
1303
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-unused-permissions">
1228
1304
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1229
1305
  </h3>
@@ -1288,14 +1364,14 @@ If you access the granted API through an alias or computed property rather than
1288
1364
  <code>require-license-file</code>
1289
1365
  <a title="Only works in 'json/json' config block" href="#usage">
1290
1366
  <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1291
- <a title="Copy rule URL" target="_blank"
1367
+ <a title="Copy rule URL" target="_blank"
1292
1368
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23require-license-file">
1293
1369
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1294
1370
  </h3>
1295
1371
 
1296
1372
  <details>
1297
1373
 
1298
- <summary>Requires a license file in the extension.</summary>
1374
+ <summary>Requires a license file.</summary>
1299
1375
 
1300
1376
  #### <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 directory structure
1301
1377
 
@@ -1308,7 +1384,7 @@ If you access the granted API through an alias or computed property rather than
1308
1384
 
1309
1385
  ```diff
1310
1386
  /extension/manifest.json
1311
- + /extension/LICENSE.md
1387
+ + /LICENSE.md
1312
1388
  ```
1313
1389
 
1314
1390
  #### When not to use it
@@ -1342,7 +1418,7 @@ If you intentionally omit a license, or it's injected at build time.
1342
1418
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1343
1419
  <a title="Works in 'json/json' config block" href="#usage">
1344
1420
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1345
- <a title="Copy rule URL" target="_blank"
1421
+ <a title="Copy rule URL" target="_blank"
1346
1422
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23require-mv3">
1347
1423
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1348
1424
  </h3>
@@ -1402,7 +1478,7 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1402
1478
  <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1403
1479
  <a title="Accepts array w/ options" href="#usage">
1404
1480
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1405
- <a title="Copy rule URL" target="_blank"
1481
+ <a title="Copy rule URL" target="_blank"
1406
1482
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23require-short-name-when-useful">
1407
1483
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1408
1484
  </h3>
@@ -1413,9 +1489,9 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1413
1489
 
1414
1490
  <h4 id="require-short-name-when-useful-options">Options</h4>
1415
1491
 
1416
- - `maxNameLength` (default `12`) – length of `name` above which `short_name` is required
1417
- - `always` (default `false`) – require `short_name` regardless of `name` length
1418
- - `checkRedundant` (default `false`) – also flag `short_name` that duplicates `name`
1492
+ - `maxNameLength` (default `12`) – length of `name` above which `short_name` is required <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1493
+ - `always` (default `false`) – require `short_name` regardless of `name` length <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1494
+ - `checkRedundant` (default `false`) – also flag `short_name` that duplicates `name` <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1419
1495
 
1420
1496
  #### <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
1421
1497
 
@@ -1428,7 +1504,7 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1428
1504
 
1429
1505
  #### <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
1430
1506
 
1431
- ```diff
1507
+ ```diff
1432
1508
  {
1433
1509
  "manifest_version": 3,
1434
1510
  "name": "Extension Infinity",
@@ -1477,7 +1553,7 @@ If you primarily target a browser that doesn't support `short_name`.
1477
1553
  <img height=18 alt="[JSONC]" src="https://img.shields.io/badge/JSONC-e6e6a8?style=flat-square" align="middle"></a>
1478
1554
  <a title="Accepts array w/ options" href="#usage">
1479
1555
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1480
- <a title="Copy rule URL" target="_blank"
1556
+ <a title="Copy rule URL" target="_blank"
1481
1557
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-filenames">
1482
1558
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1483
1559
  </h3>
@@ -1488,16 +1564,15 @@ If you primarily target a browser that doesn't support `short_name`.
1488
1564
 
1489
1565
  <h4 id="valid-filenames-options">Options</h4>
1490
1566
 
1491
- - `noReservedPrefix` (default `true`) – disallow filenames/dirs starting w/ `_` (except `_locales`)
1492
- - `noSpecialChars` (default `true`) – warn on chars outside `a-z`, `0-9`, `-`, `_`, `.`
1493
- - `checkFileExists` (default `true`) – verify files referenced in `manifest.json` actually exist
1494
- - `enforceCaseSensitivity` (default `true`) – verify manifest references match actual file case
1495
- - `maxFullPathLength` (default `260`) – max full path char length
1567
+ - `noReservedPrefix` (default `true`) – disallow filenames/dirs starting w/ `_` (except `_locales`) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1568
+ - `noSpecialChars` (default `true`) – warn on chars outside `a-z`, `0-9`, `-`, `_`, `.` <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1569
+ - `checkFileExists` (default `true`) – verify files referenced in `manifest.json` actually exist <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1570
+ - `enforceCaseSensitivity` (default `true`) – verify manifest references match actual file case <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1571
+ - `maxFullPathLength` (default `260`) – max full path char length <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1496
1572
 
1497
- #### <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
1573
+ #### <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 names/paths
1498
1574
 
1499
1575
  ```diff
1500
- // files
1501
1576
  ! /extension/_metadata/extension.json
1502
1577
  ! /extension/content script.js
1503
1578
 
@@ -1508,7 +1583,7 @@ If you primarily target a browser that doesn't support `short_name`.
1508
1583
  }
1509
1584
  ```
1510
1585
 
1511
- #### <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
1586
+ #### <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 names/paths
1512
1587
 
1513
1588
  ```diff
1514
1589
  - /extension/_metadata/extension.json
@@ -1538,7 +1613,8 @@ If you don't use conventional filenames or paths, or they're generated at build
1538
1613
  - [`no-missing-web-accessible-resources`](#no-missing-web-accessible-resources)
1539
1614
  <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>
1540
1615
  - [`valid-manifest-icons`](#valid-manifest-icons)
1541
- <a title="Only works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1616
+ <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>
1617
+ <a title="Works in 'json/json' config block" href="#usage"><img height=14 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1542
1618
  <a title="Accepts array w/ options" href="#valid-manifest-icons-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1543
1619
 
1544
1620
  <div align="center">
@@ -1559,19 +1635,19 @@ If you don't use conventional filenames or paths, or they're generated at build
1559
1635
  <img height=18 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
1560
1636
  <a title="Accepts array w/ options" href="#usage">
1561
1637
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1562
- <a title="Copy rule URL" target="_blank"
1638
+ <a title="Copy rule URL" target="_blank"
1563
1639
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-license-file">
1564
1640
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1565
1641
  </h3>
1566
1642
 
1567
1643
  <details>
1568
1644
 
1569
- <summary>Validates SPDX identifiers in license files.</summary>
1645
+ <summary>Validates SPDX identifiers in license files (for compliance scanners + SBOM generators + CI gates).</summary>
1570
1646
 
1571
1647
  <h4 id="valid-license-file-options">Options</h4>
1572
1648
 
1573
- - `requireSPDX` (default `false`) – require <a target="_blank" href="https://spdx.dev/learn/handling-license-info/">`SPDX-License-Identifier`</a> in the license
1574
- - `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
1649
+ - `requireSPDX` (default `false`) – require <a target="_blank" href="https://spdx.dev/learn/handling-license-info/">`SPDX-License-Identifier`</a> in the license <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1650
+ - `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 <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1575
1651
 
1576
1652
  #### <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
1577
1653
 
@@ -1595,10 +1671,6 @@ If you don't use conventional filenames or paths, or they're generated at build
1595
1671
  + SPDX-License-Identifier: MIT
1596
1672
  ```
1597
1673
 
1598
- #### Benefits
1599
-
1600
- Enables machine-readability for compliance scanners, SBOM generators & CI gates.
1601
-
1602
1674
  #### When not to use it
1603
1675
 
1604
1676
  If your license is injected at build time, or you use one w/ no existing SPDX identifier.
@@ -1625,11 +1697,13 @@ If your license is injected at build time, or you use one w/ no existing SPDX id
1625
1697
 
1626
1698
  <h3 id="valid-manifest-icons">
1627
1699
  <code>valid-manifest-icons</code>
1628
- <a title="Only works in 'json/json' config block" href="#usage">
1629
- <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1700
+ <a title="Included in recommended config" href="#usage">
1701
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1702
+ <a title="Works in 'json/json' config block" href="#usage">
1703
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1630
1704
  <a title="Accepts array w/ options" href="#usage">
1631
1705
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1632
- <a title="Copy rule URL" target="_blank"
1706
+ <a title="Copy rule URL" target="_blank"
1633
1707
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-manifest-icons">
1634
1708
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1635
1709
  </h3>
@@ -1640,9 +1714,9 @@ If your license is injected at build time, or you use one w/ no existing SPDX id
1640
1714
 
1641
1715
  <h4 id="valid-manifest-icons-options">Options</h4>
1642
1716
 
1643
- - `requireRecommendedSizes` (default `true`) – require all of `16`, `32`, `48`, `128`
1644
- - `checkIconExists` (default `true`) – flag icon paths that don't resolve to an existing file
1645
- - `noSVG` (default `true`) – flag SVG icon paths (unsupported by Chrome)
1717
+ - `requireRecommendedSizes` (default `true`) – require all of `16`, `32`, `48`, `128` <a title="Introduced in v2.1.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0"><img height=14 alt="[Since v2.1.0]" src="https://img.shields.io/badge/since-v2.1.0-8a9199?style=flat-square" align="middle"></a>
1718
+ - `checkIconExists` (default `true`) – flag icon paths that don't resolve to an existing file <a title="Introduced in v2.1.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0"><img height=14 alt="[Since v2.1.0]" src="https://img.shields.io/badge/since-v2.1.0-8a9199?style=flat-square" align="middle"></a>
1719
+ - `noSVG` (default `true`) – flag SVG icon paths (unsupported by Chrome) <a title="Introduced in v2.1.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0"><img height=14 alt="[Since v2.1.0]" src="https://img.shields.io/badge/since-v2.1.0-8a9199?style=flat-square" align="middle"></a>
1646
1720
 
1647
1721
  #### <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
1648
1722
 
@@ -1700,7 +1774,7 @@ If your icons are injected at build time, or you target browsers that support SV
1700
1774
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1701
1775
  <a title="Works in 'json/json' config block" href="#usage">
1702
1776
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1703
- <a title="Copy rule URL" target="_blank"
1777
+ <a title="Copy rule URL" target="_blank"
1704
1778
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-mv3-schema">
1705
1779
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1706
1780
  </h3>
@@ -1769,7 +1843,7 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1769
1843
  <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1770
1844
  <a title="Accepts array w/ options" href="#usage">
1771
1845
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1772
- <a title="Copy rule URL" target="_blank"
1846
+ <a title="Copy rule URL" target="_blank"
1773
1847
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-service-worker">
1774
1848
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1775
1849
  </h3>
@@ -1778,11 +1852,11 @@ If you intentionally target MV2 for a browser that still supports it (e.g. Firef
1778
1852
 
1779
1853
  <summary>Enforces valid service worker lifecycle and isolation.</summary>
1780
1854
 
1781
- <h4 id="mit-worker-options">Options</h4>
1855
+ <h4 id="valid-service-worker-options">Options</h4>
1782
1856
 
1783
- - `checkListenerTopLevel` (default `true`) – require `chrome.*.addListener()` calls at module top level
1784
- - `checkKeepaliveTimer` (default `true`) – flag sub-30s timers used as a keepalive workaround
1785
- - `checkDOMglobals` (default `true`) – flag DOM globals (`window`, `document`, `localStorage`) inside the service worker
1857
+ - `checkListenerTopLevel` (default `true`) – require `chrome.*.addListener()` calls at module top level <a title="Introduced in v2.5.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.5.0"><img height=14 alt="[Since v2.5.0]" src="https://img.shields.io/badge/since-v2.5.0-8a9199?style=flat-square" align="middle"></a>
1858
+ - `checkKeepaliveTimer` (default `true`) – flag sub-30s timers used as a keepalive workaround <a title="Introduced in v2.5.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.5.0"><img height=14 alt="[Since v2.5.0]" src="https://img.shields.io/badge/since-v2.5.0-8a9199?style=flat-square" align="middle"></a>
1859
+ - `checkDOMglobals` (default `true`) – flag DOM globals (`window`, `document`, `localStorage`) inside the service worker <a title="Introduced in v2.5.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.5.0"><img height=14 alt="[Since v2.5.0]" src="https://img.shields.io/badge/since-v2.5.0-8a9199?style=flat-square" align="middle"></a>
1786
1860
 
1787
1861
  #### <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
1788
1862
 
@@ -1836,11 +1910,13 @@ If your background context isn't a service worker.
1836
1910
 
1837
1911
  <h3 id="valid-url-fields">
1838
1912
  <code>valid-url-fields</code>
1839
- <a title="Only works in 'json/json' config block" href="#usage">
1840
- <img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
1913
+ <a title="Included in recommended config" href="#usage">
1914
+ <img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
1915
+ <a title="Works in 'json/json' config block" href="#usage">
1916
+ <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1841
1917
  <a title="Accepts array w/ options" href="#usage">
1842
1918
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1843
- <a title="Copy rule URL" target="_blank"
1919
+ <a title="Copy rule URL" target="_blank"
1844
1920
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-url-fields">
1845
1921
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1846
1922
  </h3>
@@ -1851,10 +1927,10 @@ If your background context isn't a service worker.
1851
1927
 
1852
1928
  <h4 id="valid-url-fields-options">Options</h4>
1853
1929
 
1854
- - `checkURLfields` (default `true`) – validate URL fields (<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override">`chrome_settings_overrides`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/homepage-url">`homepage_url`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/oauth2">`oauth2.scopes`</a>, <a target="_blank" href="https://developer.chrome.com/docs/apps/autoupdate#update_url">`update_url`</a>)
1855
- - `checkMatchPatterns` (default `true`) – validate <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">match patterns</a> (in <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts">`content_scripts`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable">`externally_connectable`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions">`host_permissions`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions">`optional_host_permissions`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources">`web_accessible_resources`</a>)
1856
- - `allowedSchemes` (default `['https', 'file']`) – permitted URL schemes for <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">match patterns</a>
1857
- - `allowAllURLs` (default `false`) – allow unrestricted patterns (<a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`<all_urls>`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`https://*/*`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`*://*/*`</a>)
1930
+ - `checkURLfields` (default `true`) – validate URL fields (<a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override">`chrome_settings_overrides`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/homepage-url">`homepage_url`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/oauth2">`oauth2.scopes`</a>, <a target="_blank" href="https://developer.chrome.com/docs/apps/autoupdate#update_url">`update_url`</a>) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1931
+ - `checkMatchPatterns` (default `true`) – validate <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">match patterns</a> (in <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts">`content_scripts`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable">`externally_connectable`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions">`host_permissions`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions">`optional_host_permissions`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources">`web_accessible_resources`</a>) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1932
+ - `allowedSchemes` (default `['https', 'file']`) – permitted URL schemes for <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">match patterns</a> <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1933
+ - `allowAllURLs` (default `false`) – allow unrestricted patterns (<a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`<all_urls>`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`https://*/*`</a>, <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">`*://*/*`</a>) <a title="Introduced in v2.4.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.4.0"><img height=14 alt="[Since v2.4.0]" src="https://img.shields.io/badge/since-v2.4.0-8a9199?style=flat-square" align="middle"></a>
1858
1934
 
1859
1935
  #### <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
1860
1936
 
@@ -1915,7 +1991,7 @@ If your URLs or patterns are generated at build time.
1915
1991
  <img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
1916
1992
  <a title="Accepts array w/ options" href="#usage">
1917
1993
  <img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
1918
- <a title="Copy rule URL" target="_blank"
1994
+ <a title="Copy rule URL" target="_blank"
1919
1995
  href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-version-field">
1920
1996
  <img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
1921
1997
  </h3>
@@ -1926,15 +2002,15 @@ If your URLs or patterns are generated at build time.
1926
2002
 
1927
2003
  <h4 id="valid-version-field-options">Options</h4>
1928
2004
 
1929
- - `versionType` (default `'chrome'`) – version format to enforce (`'chrome'`, `'semver'`, `'date'`)
1930
- - `allowFutureDate` (default `false`) – allow `version` dates later than the current date
1931
- - `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)
2005
+ - `versionType` (default `'chrome'`) – version format to enforce (`'chrome'`, `'semver'`, `'date'`) <a title="Introduced in v2.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.0.0"><img height=14 alt="[Since v2.0.0]" src="https://img.shields.io/badge/since-v2.0.0-8a9199?style=flat-square" align="middle"></a>
2006
+ - `allowFutureDate` (default `false`) – allow `version` dates later than the current date <a title="Introduced in v2.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.0.0"><img height=14 alt="[Since v2.0.0]" src="https://img.shields.io/badge/since-v2.0.0-8a9199?style=flat-square" align="middle"></a>
2007
+ - `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) <a title="Introduced in v2.0.0" target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.0.0"><img height=14 alt="[Since v2.0.0]" src="https://img.shields.io/badge/since-v2.0.0-8a9199?style=flat-square" align="middle"></a>
1932
2008
 
1933
2009
  #### <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
1934
2010
 
1935
2011
  ```diff
1936
2012
  /* eslint chrome-extensions/valid-version-field: ['error', { versionType: 'date' }] */
1937
-
2013
+
1938
2014
  {
1939
2015
  "manifest_version": 3,
1940
2016
  ! "version": "2026.1.111",
@@ -1946,7 +2022,7 @@ If your URLs or patterns are generated at build time.
1946
2022
 
1947
2023
  ```diff
1948
2024
  /* eslint chrome-extensions/valid-version-field: ['error', { versionType: 'date' }] */
1949
-
2025
+
1950
2026
  {
1951
2027
  "manifest_version": 3,
1952
2028
  - "version": "2026.1.111",