eslint-plugin-chrome-extensions 2.0.0 → 2.2.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 +510 -41
- package/docs/LICENSE.md +1 -1
- package/package.json +3 -5
- package/src/data/apis.js +52 -0
- package/src/data/deprecations.js +10 -0
- package/src/data/manifest.js +22 -11
- package/src/data/permissions.js +1 -1
- package/src/index.js +22 -1
- package/src/rules/manifest-key-order.js +3 -2
- package/src/rules/manifest-spacing.js +160 -0
- package/src/rules/no-duplicate-manifest-keys.js +36 -0
- package/src/rules/no-insecure-fetch.js +52 -0
- package/src/rules/no-insecure-messaging.js +44 -7
- package/src/rules/no-invalid-permissions.js +2 -2
- package/src/rules/no-missing-web-accessible-resources.js +51 -0
- package/src/rules/no-remote-code.js +11 -9
- package/src/rules/no-unrestricted-host-permissions.js +54 -0
- package/src/rules/no-unused-permissions.js +1 -1
- package/src/rules/require-mv3.js +2 -2
- package/src/rules/valid-manifest-icons.js +85 -0
- package/src/rules/valid-mv3-schema.js +50 -20
- package/src/rules/valid-service-worker.js +8 -3
- package/src/rules/valid-version-field.js +3 -3
- package/src/utils.js +11 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
ESLint rules for Chrome extensions.
|
|
14
14
|
|
|
15
|
-
<img src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-chrome-extensions/
|
|
15
|
+
<img src="https://cdn.staticdelivr.com/gl/adamlui/eslint-plugin-chrome-extensions/04d2f53b22/assets/images/screenshots/vs-code/squiggles.png">
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -41,27 +41,25 @@ import json from '@eslint/json'
|
|
|
41
41
|
export default [
|
|
42
42
|
// other configs
|
|
43
43
|
{
|
|
44
|
-
files: ['extension/**/*.js'],
|
|
44
|
+
files: ['**/extension/**/*.js'],
|
|
45
45
|
plugins: { 'chrome-extensions': chromeExtensions },
|
|
46
46
|
rules: {
|
|
47
47
|
...chromeExtensions.configs.recommended.rules,
|
|
48
|
-
'chrome-extensions/no-
|
|
49
|
-
'chrome-extensions/no-deprecated-apis': ['error', { target: 'mv3' }] // selectively tweak rule
|
|
48
|
+
'chrome-extensions/no-deprecated-apis': 'off' // selectively disable rule
|
|
50
49
|
}
|
|
51
50
|
},
|
|
52
51
|
{
|
|
53
|
-
files: ['
|
|
52
|
+
files: ['**/manifest.json'], language: 'json/json',
|
|
54
53
|
plugins: { 'chrome-extensions': chromeExtensions, json },
|
|
55
54
|
rules: {
|
|
56
55
|
...chromeExtensions.configs.manifest.rules,
|
|
57
|
-
'chrome-extensions/require-mv3': 'off', // selectively disable rule
|
|
58
56
|
'chrome-extensions/valid-version-field': ['error', { versionType: 'date' }] // selectively tweak rule
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
]
|
|
62
60
|
```
|
|
63
61
|
|
|
64
|
-
Available bundles: `recommended`, `strict` (everything), `problem` (deterministic bugs only), `manifest`
|
|
62
|
+
Available bundles: `recommended`, `strict` (everything), `problem` (deterministic bugs only), `security`, `manifest`
|
|
65
63
|
|
|
66
64
|
**Note:** Rule config is either a severity string (`'off'`, `'warn'`, `'error'`) or an array `[severity, options]` when the rule accepts options.
|
|
67
65
|
|
|
@@ -74,6 +72,8 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
|
|
|
74
72
|
|
|
75
73
|
<h3 id="manifest-key-order">
|
|
76
74
|
<code>manifest-key-order</code>
|
|
75
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
76
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
77
77
|
<a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix">
|
|
78
78
|
<img height=18 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
|
|
79
79
|
<a title="Doesn't prevent bugs" href="#manifest-key-order">
|
|
@@ -89,7 +89,7 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
|
|
|
89
89
|
|
|
90
90
|
<summary>Enforces a preferred order for manifest keys.</summary>
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
<h4 id="manifest-key-order-options">Options</h4>
|
|
93
93
|
|
|
94
94
|
- `order` (default `[]`) – manifest keys in custom order (e.g. `['name', 'manifest_version']`) to selectively override built-in order with
|
|
95
95
|
|
|
@@ -99,8 +99,8 @@ Available bundles: `recommended`, `strict` (everything), `problem` (deterministi
|
|
|
99
99
|
/* eslint chrome-extensions/manifest-key-order: ['error', { order: ['name', 'manifest_version'] }] */
|
|
100
100
|
|
|
101
101
|
{
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
! "manifest_version": 3,
|
|
103
|
+
"name": "My Extension",
|
|
104
104
|
"version": "1.0.0"
|
|
105
105
|
}
|
|
106
106
|
```
|
|
@@ -129,11 +129,102 @@ If you don't care about the order of manifest keys.
|
|
|
129
129
|
#### See also
|
|
130
130
|
|
|
131
131
|
- [`require-mv3`](#require-mv3)
|
|
132
|
+
<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>
|
|
133
|
+
<a title="Works w/ '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>
|
|
132
134
|
- [`valid-mv3-schema`](#valid-mv3-schema)
|
|
135
|
+
<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>
|
|
136
|
+
<a title="Works w/ '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>
|
|
133
137
|
|
|
134
138
|
<div align="center">
|
|
135
139
|
|
|
136
|
-
[Back to index ↑][
|
|
140
|
+
[Back to index ↑][epce-rules]
|
|
141
|
+
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
<h3 id="manifest-spacing">
|
|
149
|
+
<code>manifest-spacing</code>
|
|
150
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
151
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
152
|
+
<a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix">
|
|
153
|
+
<img height=18 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
|
|
154
|
+
<a title="Doesn't prevent bugs" href="#manifest-spacing">
|
|
155
|
+
<img height=18 alt="[Stylistic]" src="https://img.shields.io/badge/Stylistic-af68ff?style=flat-square" align="middle"></a>
|
|
156
|
+
<a title="Accepts array w/ options" href="#usage">
|
|
157
|
+
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
158
|
+
<a title="Copy rule URL" target="_blank"
|
|
159
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23manifest-spacing">
|
|
160
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
161
|
+
</h3>
|
|
162
|
+
|
|
163
|
+
<details>
|
|
164
|
+
|
|
165
|
+
<summary>Enforces consistent indentation and spacing in <code>manifest.json</code>.</summary>
|
|
166
|
+
|
|
167
|
+
<h4 id="manifest-spacing-options">Options</h4>
|
|
168
|
+
|
|
169
|
+
- `spaces` (default `2`) – number of spaces per indent level
|
|
170
|
+
- `checkColons` (default `true`) – enforce 0 spaces before and 1 space after `:` in key/value pairs
|
|
171
|
+
- `checkCommas` (default `true`) – enforce 0 spaces before and 1 space after `,` in inline objects
|
|
172
|
+
- `checkBraces` (default `true`) – enforce 1 space after `{` and before `}` in inline objects
|
|
173
|
+
- `checkBrackets` (default `true`) – enforce 0 spaces after `[` and before `]` in inline arrays
|
|
174
|
+
|
|
175
|
+
#### <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
|
|
176
|
+
|
|
177
|
+
```diff
|
|
178
|
+
/* eslint chrome-extensions/manifest-spacing: ['error', { spaces: 2 }] */
|
|
179
|
+
|
|
180
|
+
{
|
|
181
|
+
! "manifest_version": 3,
|
|
182
|
+
! "version" : "1.0.0",
|
|
183
|
+
! "permissions": [ "tabs","cookies" ],
|
|
184
|
+
! "icons": {"16": "icon16.png"},
|
|
185
|
+
"name": "My Extension"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### <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
|
|
190
|
+
|
|
191
|
+
```diff
|
|
192
|
+
/* eslint chrome-extensions/manifest-spacing: ['error', { spaces: 2 }] */
|
|
193
|
+
|
|
194
|
+
{
|
|
195
|
+
- "manifest_version": 3,
|
|
196
|
+
+ "manifest_version": 3,
|
|
197
|
+
- "version" : "1.0.0",
|
|
198
|
+
+ "version": "1.0.0",
|
|
199
|
+
- "permissions": [ "tabs","cookies" ],
|
|
200
|
+
+ "permissions": ["tabs", "cookies"],
|
|
201
|
+
- "icons": {"16": "icon16.png"},
|
|
202
|
+
+ "icons": { "16": "icon16.png" },
|
|
203
|
+
"name": "My Extension"
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### When not to use it
|
|
208
|
+
|
|
209
|
+
If you don't care about visual consistency in your manifest.
|
|
210
|
+
|
|
211
|
+
#### Introduced in
|
|
212
|
+
|
|
213
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.2.0">v2.2.0</a> (October 12, 2026)
|
|
214
|
+
|
|
215
|
+
#### See also
|
|
216
|
+
|
|
217
|
+
- [`manifest-key-order`](#manifest-key-order)
|
|
218
|
+
<a title="Only works w/ '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>
|
|
219
|
+
<a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
|
|
220
|
+
<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>
|
|
221
|
+
<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>
|
|
222
|
+
- [`no-duplicate-manifest-keys`](#no-duplicate-manifest-keys)
|
|
223
|
+
<a title="Only works w/ '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>
|
|
224
|
+
|
|
225
|
+
<div align="center">
|
|
226
|
+
|
|
227
|
+
[Back to index ↑][epce-rules]
|
|
137
228
|
|
|
138
229
|
</div>
|
|
139
230
|
|
|
@@ -180,12 +271,12 @@ If you intentionally interact w/ host page styles.
|
|
|
180
271
|
|
|
181
272
|
#### See also
|
|
182
273
|
|
|
183
|
-
- <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts">Chrome for Developers — Content scripts</a>
|
|
184
|
-
- <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM">MDN — Using shadow DOM</a>
|
|
274
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts">Chrome for Developers — Content scripts</a>
|
|
275
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64"> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM">MDN — Using shadow DOM</a>
|
|
185
276
|
|
|
186
277
|
<div align="center">
|
|
187
278
|
|
|
188
|
-
[Back to index ↑][
|
|
279
|
+
[Back to index ↑][epce-rules]
|
|
189
280
|
|
|
190
281
|
</div>
|
|
191
282
|
|
|
@@ -208,7 +299,7 @@ If you intentionally interact w/ host page styles.
|
|
|
208
299
|
|
|
209
300
|
<summary>Disallows deprecated <code>chrome</code> API calls.</summary>
|
|
210
301
|
|
|
211
|
-
|
|
302
|
+
<h4 id="no-deprecated-apis-options">Options</h4>
|
|
212
303
|
|
|
213
304
|
- `target` (default `'mv3'`) – Chrome extension manifest version whose deprecations to validate against (`'mv3'`, `'mv2'`)
|
|
214
305
|
- `allowedAPIs` (default `[]`) – additional deprecated API namespaces to allow, as a single string or array
|
|
@@ -246,11 +337,131 @@ If you don't want deprecation validation at all. For individual deprecated APIs
|
|
|
246
337
|
|
|
247
338
|
#### See also
|
|
248
339
|
|
|
249
|
-
- <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api">Chrome for Developers — API reference</a>
|
|
340
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api">Chrome for Developers — API reference</a>
|
|
250
341
|
|
|
251
342
|
<div align="center">
|
|
252
343
|
|
|
253
|
-
[Back to index ↑][
|
|
344
|
+
[Back to index ↑][epce-rules]
|
|
345
|
+
|
|
346
|
+
</div>
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
</details>
|
|
351
|
+
|
|
352
|
+
<h3 id="no-duplicate-manifest-keys">
|
|
353
|
+
<code>no-duplicate-manifest-keys</code>
|
|
354
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
355
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
356
|
+
<a title="Copy rule URL" target="_blank"
|
|
357
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-duplicate-manifest-keys">
|
|
358
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
359
|
+
</h3>
|
|
360
|
+
|
|
361
|
+
<details>
|
|
362
|
+
|
|
363
|
+
<summary>Disallows duplicate keys in <code>manifest.json</code>.</summary>
|
|
364
|
+
|
|
365
|
+
#### <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
|
|
366
|
+
|
|
367
|
+
```diff
|
|
368
|
+
{
|
|
369
|
+
"manifest_version": 3,
|
|
370
|
+
! "name": "Foo",
|
|
371
|
+
! "name": "Bar",
|
|
372
|
+
! "version": "1.0.0",
|
|
373
|
+
! "version": "2.0.0"
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### <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
|
|
378
|
+
|
|
379
|
+
```diff
|
|
380
|
+
{
|
|
381
|
+
"manifest_version": 3,
|
|
382
|
+
- "name": "Foo",
|
|
383
|
+
- "name": "Bar",
|
|
384
|
+
"name": "My Extension",
|
|
385
|
+
- "version": "1.0.0",
|
|
386
|
+
- "version": "2.0.0"
|
|
387
|
+
"version": "1.0.0"
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### When not to use it
|
|
392
|
+
|
|
393
|
+
If you rely on a Chromium fork resolving duplicate keys in a specific order.
|
|
394
|
+
|
|
395
|
+
#### Introduced in
|
|
396
|
+
|
|
397
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0">v2.1.0</a> (October 5, 2026)
|
|
398
|
+
|
|
399
|
+
#### See also
|
|
400
|
+
|
|
401
|
+
- [`manifest-key-order`](#manifest-key-order)
|
|
402
|
+
<a title="Only works w/ '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>
|
|
403
|
+
<a title="Accepts eslint --fix" target="_blank" href="https://eslint.org/docs/latest/use/command-line-interface#--fix"><img height=14 alt="[Auto-fixable]" src="https://img.shields.io/badge/Auto--fixable-3b5bdb?style=flat-square" align="middle"></a>
|
|
404
|
+
<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>
|
|
405
|
+
<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>
|
|
406
|
+
- [`no-unused-permissions`](#no-unused-permissions)
|
|
407
|
+
<a title="Only works w/ '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>
|
|
408
|
+
|
|
409
|
+
<div align="center">
|
|
410
|
+
|
|
411
|
+
[Back to index ↑][epce-rules]
|
|
412
|
+
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
</details>
|
|
418
|
+
|
|
419
|
+
<h3 id="no-insecure-fetch">
|
|
420
|
+
<code>no-insecure-fetch</code>
|
|
421
|
+
<a title="Included in recommended config" href="#usage">
|
|
422
|
+
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
423
|
+
<a title="Included in security config" href="#usage">
|
|
424
|
+
<img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
|
|
425
|
+
<a title="Copy rule URL" target="_blank"
|
|
426
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-insecure-fetch">
|
|
427
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
428
|
+
</h3>
|
|
429
|
+
|
|
430
|
+
<details>
|
|
431
|
+
|
|
432
|
+
<summary>Flags <code>fetch()</code> and <code>XMLHttpRequest.open()</code> calls that use <code>http://</code>.</summary>
|
|
433
|
+
|
|
434
|
+
#### <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
|
|
435
|
+
|
|
436
|
+
```diff
|
|
437
|
+
! fetch('http://api.example.com/data')
|
|
438
|
+
! xhr.open('GET', 'http://cdn.example.com/lib.js')
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### <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
|
|
442
|
+
|
|
443
|
+
```diff
|
|
444
|
+
- fetch('http://api.example.com/data')
|
|
445
|
+
+ fetch('https://api.example.com/data')
|
|
446
|
+
- xhr.open('GET', 'http://cdn.example.com/lib.js')
|
|
447
|
+
+ xhr.open('GET', 'https://cdn.example.com/lib.js')
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
#### When not to use it
|
|
451
|
+
|
|
452
|
+
If you intentionally target HTTP endpoints.
|
|
453
|
+
|
|
454
|
+
#### Introduced in
|
|
455
|
+
|
|
456
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0">v2.1.0</a> (October 5, 2026)
|
|
457
|
+
|
|
458
|
+
#### See also
|
|
459
|
+
|
|
460
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/network-requests">Chrome for Developers — Cross-origin network requests</a>
|
|
461
|
+
|
|
462
|
+
<div align="center">
|
|
463
|
+
|
|
464
|
+
[Back to index ↑][epce-rules]
|
|
254
465
|
|
|
255
466
|
</div>
|
|
256
467
|
|
|
@@ -262,6 +473,10 @@ If you don't want deprecation validation at all. For individual deprecated APIs
|
|
|
262
473
|
<code>no-insecure-messaging</code>
|
|
263
474
|
<a title="Included in recommended config" href="#usage">
|
|
264
475
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
476
|
+
<a title="Included in security config" href="#usage">
|
|
477
|
+
<img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
|
|
478
|
+
<a title="Accepts array w/ options" href="#usage">
|
|
479
|
+
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
265
480
|
<a title="Copy rule URL" target="_blank"
|
|
266
481
|
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-insecure-messaging">
|
|
267
482
|
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
@@ -269,7 +484,11 @@ If you don't want deprecation validation at all. For individual deprecated APIs
|
|
|
269
484
|
|
|
270
485
|
<details>
|
|
271
486
|
|
|
272
|
-
<summary>Requires
|
|
487
|
+
<summary>Requires sender/origin validation + filtered <code>tabs.query()</code> + explicit <code>window.postMessage()</code> target.</summary>
|
|
488
|
+
|
|
489
|
+
<h4 id="no-insecure-messaging-options">Options</h4>
|
|
490
|
+
|
|
491
|
+
- `disallowWildcardTarget` (default `true`) – flag <code>postMessage()</code> calls that use <code>'*'</code> as <code>targetOrigin</code>
|
|
273
492
|
|
|
274
493
|
#### <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
|
|
275
494
|
|
|
@@ -278,9 +497,15 @@ If you don't want deprecation validation at all. For individual deprecated APIs
|
|
|
278
497
|
! handle(msg)
|
|
279
498
|
})
|
|
280
499
|
|
|
500
|
+
window.addEventListener('message', event => {
|
|
501
|
+
! handle(event.data)
|
|
502
|
+
})
|
|
503
|
+
|
|
281
504
|
! chrome.tabs.query({})
|
|
282
505
|
.then(tabs => tabs.forEach(tab =>
|
|
283
506
|
chrome.tabs.sendMessage(tab.id, { action: 'ping' })))
|
|
507
|
+
|
|
508
|
+
! window.postMessage(payload, '*')
|
|
284
509
|
```
|
|
285
510
|
|
|
286
511
|
#### <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
|
|
@@ -291,15 +516,23 @@ If you don't want deprecation validation at all. For individual deprecated APIs
|
|
|
291
516
|
handle(msg)
|
|
292
517
|
})
|
|
293
518
|
|
|
519
|
+
window.addEventListener('message', event => {
|
|
520
|
+
+ if (event.origin != 'https://allowed-origin.com') return
|
|
521
|
+
handle(event.data)
|
|
522
|
+
})
|
|
523
|
+
|
|
294
524
|
- chrome.tabs.query({})
|
|
295
525
|
+ chrome.tabs.query({ url: 'https://allowed-origin.com/*' })
|
|
296
526
|
.then(tabs => tabs.forEach(tab =>
|
|
297
527
|
chrome.tabs.sendMessage(tab.id, { action: 'ping' })))
|
|
528
|
+
|
|
529
|
+
- window.postMessage(payload, '*')
|
|
530
|
+
+ window.postMessage(payload, 'https://allowed-origin.com')
|
|
298
531
|
```
|
|
299
532
|
|
|
300
533
|
#### When not to use it
|
|
301
534
|
|
|
302
|
-
If you trust every external caller and open tab.
|
|
535
|
+
If you trust every external caller and open tab, or you intentionally broadcast to any origin.
|
|
303
536
|
|
|
304
537
|
#### Introduced in
|
|
305
538
|
|
|
@@ -307,12 +540,13 @@ If you trust every external caller and open tab.
|
|
|
307
540
|
|
|
308
541
|
#### See also
|
|
309
542
|
|
|
310
|
-
- <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onMessageExternal">Chrome for Developers — `runtime.onMessageExternal`</a>
|
|
311
|
-
- <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/tabs#method-query">Chrome for Developers — `tabs.query()`</a>
|
|
543
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onMessageExternal">Chrome for Developers — `runtime.onMessageExternal`</a>
|
|
544
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/tabs#method-query">Chrome for Developers — `tabs.query()`</a>
|
|
545
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.mozilla.org&sz=64"> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#security_concerns">MDN — `window.postMessage()` security concerns</a>
|
|
312
546
|
|
|
313
547
|
<div align="center">
|
|
314
548
|
|
|
315
|
-
[Back to index ↑][
|
|
549
|
+
[Back to index ↑][epce-rules]
|
|
316
550
|
|
|
317
551
|
</div>
|
|
318
552
|
|
|
@@ -324,6 +558,8 @@ If you trust every external caller and open tab.
|
|
|
324
558
|
<code>no-invalid-permissions</code>
|
|
325
559
|
<a title="Included in recommended config" href="#usage">
|
|
326
560
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
561
|
+
<a title="Works w/ 'json/json' config block" href="#usage">
|
|
562
|
+
<img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
|
|
327
563
|
<a title="Accepts array w/ options" href="#usage">
|
|
328
564
|
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
329
565
|
<a title="Copy rule URL" target="_blank"
|
|
@@ -335,7 +571,7 @@ If you trust every external caller and open tab.
|
|
|
335
571
|
|
|
336
572
|
<summary>Disallows invalid or unsupported manifest permission names.</summary>
|
|
337
573
|
|
|
338
|
-
|
|
574
|
+
<h4 id="no-invalid-permissions-options">Options</h4>
|
|
339
575
|
|
|
340
576
|
- `target` (default `'mv3'`) – Chrome manifest version whose permissions to validate against (`'mv3'`, `'mv2'`)
|
|
341
577
|
- `allowedPermissions` (default `[]`) – additional permission names to allow beyond the built-in list, as a single string or array
|
|
@@ -375,11 +611,13 @@ If you don't want permission validation at all. For custom permissions from a Ch
|
|
|
375
611
|
#### See also
|
|
376
612
|
|
|
377
613
|
- [`no-missing-permissions`](#no-missing-permissions)
|
|
614
|
+
<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>
|
|
378
615
|
- [`no-unused-permissions`](#no-unused-permissions)
|
|
616
|
+
<a title="Only works w/ '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>
|
|
379
617
|
|
|
380
618
|
<div align="center">
|
|
381
619
|
|
|
382
|
-
[Back to index ↑][
|
|
620
|
+
[Back to index ↑][epce-rules]
|
|
383
621
|
|
|
384
622
|
</div>
|
|
385
623
|
|
|
@@ -438,11 +676,78 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
438
676
|
#### See also
|
|
439
677
|
|
|
440
678
|
- [`no-invalid-permissions`](#no-invalid-permissions)
|
|
679
|
+
<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>
|
|
680
|
+
<a title="Works w/ '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>
|
|
681
|
+
<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>
|
|
441
682
|
- [`no-unused-permissions`](#no-unused-permissions)
|
|
683
|
+
<a title="Only works w/ '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>
|
|
442
684
|
|
|
443
685
|
<div align="center">
|
|
444
686
|
|
|
445
|
-
[Back to index ↑][
|
|
687
|
+
[Back to index ↑][epce-rules]
|
|
688
|
+
|
|
689
|
+
</div>
|
|
690
|
+
|
|
691
|
+
---
|
|
692
|
+
|
|
693
|
+
</details>
|
|
694
|
+
|
|
695
|
+
<h3 id="no-missing-web-accessible-resources">
|
|
696
|
+
<code>no-missing-web-accessible-resources</code>
|
|
697
|
+
<a title="Included in recommended config" href="#usage">
|
|
698
|
+
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
699
|
+
<a title="Copy rule URL" target="_blank"
|
|
700
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-missing-web-accessible-resources">
|
|
701
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
702
|
+
</h3>
|
|
703
|
+
|
|
704
|
+
<details>
|
|
705
|
+
|
|
706
|
+
<summary>Flags <code>chrome.runtime.getURL()</code> paths missing from <code>web_accessible_resources</code>.</summary>
|
|
707
|
+
|
|
708
|
+
#### <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
|
|
709
|
+
|
|
710
|
+
```diff
|
|
711
|
+
// manifest.json
|
|
712
|
+
{
|
|
713
|
+
"manifest_version": 3,
|
|
714
|
+
! "web_accessible_resources": []
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// content.js
|
|
718
|
+
! img.src = chrome.runtime.getURL('logo.png')
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
#### <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
|
|
722
|
+
|
|
723
|
+
```diff
|
|
724
|
+
// manifest.json
|
|
725
|
+
{
|
|
726
|
+
"manifest_version": 3,
|
|
727
|
+
- "web_accessible_resources": []
|
|
728
|
+
+ "web_accessible_resources": [{ "resources": ["logo.png"], "matches": ["<all_urls>"] }]
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// content.js
|
|
732
|
+
img.src = chrome.runtime.getURL('logo.png')
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
#### When not to use it
|
|
736
|
+
|
|
737
|
+
If your paths are built at runtime.
|
|
738
|
+
|
|
739
|
+
#### Introduced in
|
|
740
|
+
|
|
741
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0">v2.1.0</a> (October 5, 2026)
|
|
742
|
+
|
|
743
|
+
#### See also
|
|
744
|
+
|
|
745
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/web-accessible-resources">Chrome for Developers — `web_accessible_resources`</a>
|
|
746
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/runtime#method-getURL">Chrome for Developers — `runtime.getURL()`</a>
|
|
747
|
+
|
|
748
|
+
<div align="center">
|
|
749
|
+
|
|
750
|
+
[Back to index ↑][epce-rules]
|
|
446
751
|
|
|
447
752
|
</div>
|
|
448
753
|
|
|
@@ -454,6 +759,8 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
454
759
|
<code>no-remote-code</code>
|
|
455
760
|
<a title="Included in recommended config" href="#usage">
|
|
456
761
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
762
|
+
<a title="Included in security config" href="#usage">
|
|
763
|
+
<img height=18 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
|
|
457
764
|
<a title="Accepts array w/ options" href="#usage">
|
|
458
765
|
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
459
766
|
<a title="Copy rule URL" target="_blank"
|
|
@@ -465,7 +772,7 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
465
772
|
|
|
466
773
|
<summary>Disallows remote or dynamically-evaluated code (blocked by MV3's CSP at runtime).</summary>
|
|
467
774
|
|
|
468
|
-
|
|
775
|
+
<h4 id="no-remote-code-options">Options</h4>
|
|
469
776
|
|
|
470
777
|
- `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
|
|
471
778
|
- `checkExecuteScriptClosures` (default `true`) – additionally flag <code>chrome.scripting.executeScript({ func })</code> bodies that capture outer-scope variables
|
|
@@ -492,6 +799,10 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
492
799
|
+ chrome.scripting.executeScript({ target: { tabId }, func: doThing, args: [value] })
|
|
493
800
|
```
|
|
494
801
|
|
|
802
|
+
#### When not to use it
|
|
803
|
+
|
|
804
|
+
If you intentionally target forks w/ relaxed CSPs. For individual patterns you still need, prefer narrowing via `patterns` over disabling the rule.
|
|
805
|
+
|
|
495
806
|
#### Introduced in
|
|
496
807
|
|
|
497
808
|
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v1.0.0">v1.0.0</a> (October 2, 2026)
|
|
@@ -499,11 +810,79 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
499
810
|
#### See also
|
|
500
811
|
|
|
501
812
|
- [`require-mv3`](#require-mv3)
|
|
813
|
+
<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>
|
|
814
|
+
<a title="Works w/ '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>
|
|
502
815
|
- [`valid-mv3-schema`](#valid-mv3-schema)
|
|
816
|
+
<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>
|
|
817
|
+
<a title="Works w/ '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>
|
|
818
|
+
|
|
819
|
+
<div align="center">
|
|
820
|
+
|
|
821
|
+
[Back to index ↑][epce-rules]
|
|
822
|
+
|
|
823
|
+
</div>
|
|
824
|
+
|
|
825
|
+
---
|
|
826
|
+
|
|
827
|
+
</details>
|
|
828
|
+
|
|
829
|
+
<h3 id="no-unrestricted-host-permissions">
|
|
830
|
+
<code>no-unrestricted-host-permissions</code>
|
|
831
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
832
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
833
|
+
<a title="Accepts array w/ options" href="#usage">
|
|
834
|
+
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
835
|
+
<a title="Copy rule URL" target="_blank"
|
|
836
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-unrestricted-host-permissions">
|
|
837
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
838
|
+
</h3>
|
|
839
|
+
|
|
840
|
+
<details>
|
|
841
|
+
|
|
842
|
+
<summary>Disallows broad host permissions that grant access to every site.</summary>
|
|
843
|
+
|
|
844
|
+
<h4 id="no-unrestricted-host-permissions-options">Options</h4>
|
|
845
|
+
|
|
846
|
+
- `allowedPatterns` (default `[]`) – host patterns to explicitly allow (e.g. `['<all_urls>']`)
|
|
847
|
+
|
|
848
|
+
#### <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
|
|
849
|
+
|
|
850
|
+
```diff
|
|
851
|
+
{
|
|
852
|
+
"manifest_version": 3,
|
|
853
|
+
! "host_permissions": ["<all_urls>"],
|
|
854
|
+
! "optional_host_permissions": ["*://*/*"]
|
|
855
|
+
}
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
#### <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
|
|
859
|
+
|
|
860
|
+
```diff
|
|
861
|
+
{
|
|
862
|
+
"manifest_version": 3,
|
|
863
|
+
- "host_permissions": ["<all_urls>"],
|
|
864
|
+
+ "host_permissions": ["https://example.com/*", "https://*.trusted.com/*"],
|
|
865
|
+
- "optional_host_permissions": ["*://*/*"]
|
|
866
|
+
+ "optional_host_permissions": ["https://user-content.example.com/*"]
|
|
867
|
+
}
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
#### When not to use it
|
|
871
|
+
|
|
872
|
+
If you legitimately need broad access (e.g. ad blockers or dev tools).
|
|
873
|
+
|
|
874
|
+
#### Introduced in
|
|
875
|
+
|
|
876
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0">v2.1.0</a> (October 5, 2026)
|
|
877
|
+
|
|
878
|
+
#### See also
|
|
879
|
+
|
|
880
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions">Chrome for Developers — Declare permissions</a>
|
|
881
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns">Chrome for Developers — Match patterns</a>
|
|
503
882
|
|
|
504
883
|
<div align="center">
|
|
505
884
|
|
|
506
|
-
[Back to index ↑][
|
|
885
|
+
[Back to index ↑][epce-rules]
|
|
507
886
|
|
|
508
887
|
</div>
|
|
509
888
|
|
|
@@ -513,8 +892,8 @@ If you use APIs through aliases or wrappers that obscure the original call site.
|
|
|
513
892
|
|
|
514
893
|
<h3 id="no-unused-permissions">
|
|
515
894
|
<code>no-unused-permissions</code>
|
|
516
|
-
<a title="
|
|
517
|
-
<img height=18 alt="[
|
|
895
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
896
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
518
897
|
<a title="Copy rule URL" target="_blank"
|
|
519
898
|
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23no-unused-permissions">
|
|
520
899
|
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
@@ -560,11 +939,15 @@ If you access the granted API through an alias or computed property rather than
|
|
|
560
939
|
#### See also
|
|
561
940
|
|
|
562
941
|
- [`no-invalid-permissions`](#no-invalid-permissions)
|
|
942
|
+
<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>
|
|
943
|
+
<a title="Works w/ '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>
|
|
944
|
+
<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>
|
|
563
945
|
- [`no-missing-permissions`](#no-missing-permissions)
|
|
946
|
+
<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>
|
|
564
947
|
|
|
565
948
|
<div align="center">
|
|
566
949
|
|
|
567
|
-
[Back to index ↑][
|
|
950
|
+
[Back to index ↑][epce-rules]
|
|
568
951
|
|
|
569
952
|
</div>
|
|
570
953
|
|
|
@@ -576,6 +959,8 @@ If you access the granted API through an alias or computed property rather than
|
|
|
576
959
|
<code>require-mv3</code>
|
|
577
960
|
<a title="Included in recommended config" href="#usage">
|
|
578
961
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
962
|
+
<a title="Works w/ 'json/json' config block" href="#usage">
|
|
963
|
+
<img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
|
|
579
964
|
<a title="Copy rule URL" target="_blank"
|
|
580
965
|
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23require-mv3">
|
|
581
966
|
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
@@ -608,7 +993,7 @@ If you access the granted API through an alias or computed property rather than
|
|
|
608
993
|
|
|
609
994
|
#### When not to use it
|
|
610
995
|
|
|
611
|
-
If you intentionally target MV2 for a
|
|
996
|
+
If you intentionally target MV2 for a browser that still supports it (e.g. Firefox).
|
|
612
997
|
|
|
613
998
|
#### Introduced in
|
|
614
999
|
|
|
@@ -617,10 +1002,83 @@ If you intentionally target MV2 for a Chromium fork that still supports it.
|
|
|
617
1002
|
#### See also
|
|
618
1003
|
|
|
619
1004
|
- [`valid-mv3-schema`](#valid-mv3-schema)
|
|
1005
|
+
<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>
|
|
1006
|
+
<a title="Works w/ '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>
|
|
1007
|
+
|
|
1008
|
+
<div align="center">
|
|
1009
|
+
|
|
1010
|
+
[Back to index ↑][epce-rules]
|
|
1011
|
+
|
|
1012
|
+
</div>
|
|
1013
|
+
|
|
1014
|
+
---
|
|
1015
|
+
|
|
1016
|
+
</details>
|
|
1017
|
+
|
|
1018
|
+
<h3 id="valid-manifest-icons">
|
|
1019
|
+
<code>valid-manifest-icons</code>
|
|
1020
|
+
<a title="Only works w/ 'json/json' config block" href="#usage">
|
|
1021
|
+
<img height=18 alt="[Manifest only]" src="https://img.shields.io/badge/Manifest_only-999999?style=flat-square" align="middle"></a>
|
|
1022
|
+
<a title="Accepts array w/ options" href="#usage">
|
|
1023
|
+
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
1024
|
+
<a title="Copy rule URL" target="_blank"
|
|
1025
|
+
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-manifest-icons">
|
|
1026
|
+
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
1027
|
+
</h3>
|
|
1028
|
+
|
|
1029
|
+
<details>
|
|
1030
|
+
|
|
1031
|
+
<summary>Ensures manifest <code>icons</code> exist and use the recommended sizes.</summary>
|
|
1032
|
+
|
|
1033
|
+
<h4 id="valid-manifest-icons-options">Options</h4>
|
|
1034
|
+
|
|
1035
|
+
- `requireRecommendedSizes` (default `true`) – require all of `16`, `32`, `48`, `128`
|
|
1036
|
+
- `checkIconExists` (default `true`) – flag icon paths that don't resolve to an existing file
|
|
1037
|
+
- `noSVG` (default `true`) – flag SVG icon paths (unsupported by Chrome)
|
|
1038
|
+
|
|
1039
|
+
#### <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
|
|
1040
|
+
|
|
1041
|
+
```diff
|
|
1042
|
+
{
|
|
1043
|
+
"manifest_version": 3,
|
|
1044
|
+
"icons": {
|
|
1045
|
+
! "48": "icon48.svg",
|
|
1046
|
+
"256": "icon256.png"
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
#### <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
|
|
1052
|
+
|
|
1053
|
+
```diff
|
|
1054
|
+
{
|
|
1055
|
+
"manifest_version": 3,
|
|
1056
|
+
"icons": {
|
|
1057
|
+
+ "16": "icon16.png",
|
|
1058
|
+
+ "32": "icon32.png",
|
|
1059
|
+
- "48": "icon48.svg",
|
|
1060
|
+
+ "48": "icon48.png",
|
|
1061
|
+
+ "128": "icon128.png",
|
|
1062
|
+
"256": "icon256.png"
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
#### When not to use it
|
|
1068
|
+
|
|
1069
|
+
If your icons are injected at build time, or you target browsers that support SVGs (e.g. Firefox).
|
|
1070
|
+
|
|
1071
|
+
#### Introduced in
|
|
1072
|
+
|
|
1073
|
+
<a target="_blank" href="https://codeberg.org/adamlui/eslint-plugin-chrome-extensions/releases/tag/v2.1.0">v2.1.0</a> (October 5, 2026)
|
|
1074
|
+
|
|
1075
|
+
#### See also
|
|
1076
|
+
|
|
1077
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/icons">Chrome for Developers — `icons`</a>
|
|
620
1078
|
|
|
621
1079
|
<div align="center">
|
|
622
1080
|
|
|
623
|
-
[Back to index ↑][
|
|
1081
|
+
[Back to index ↑][epce-rules]
|
|
624
1082
|
|
|
625
1083
|
</div>
|
|
626
1084
|
|
|
@@ -632,6 +1090,8 @@ If you intentionally target MV2 for a Chromium fork that still supports it.
|
|
|
632
1090
|
<code>valid-mv3-schema</code>
|
|
633
1091
|
<a title="Included in recommended config" href="#usage">
|
|
634
1092
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
1093
|
+
<a title="Works w/ 'json/json' config block" href="#usage">
|
|
1094
|
+
<img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
|
|
635
1095
|
<a title="Copy rule URL" target="_blank"
|
|
636
1096
|
href="https://copy-to-clipboard.onrender.com/copy/https%3A%2F%2Fcodeberg.org%2Fadamlui%2Feslint-plugin-chrome-extensions%2F%23valid-mv3-schema">
|
|
637
1097
|
<img height=16 width=21 alt="[Copy rule URL]" src="https://api.iconify.design/mdi/content-copy.svg?color=%23cccccc" align="middle"></a>
|
|
@@ -670,7 +1130,7 @@ If you intentionally target MV2 for a Chromium fork that still supports it.
|
|
|
670
1130
|
|
|
671
1131
|
#### When not to use it
|
|
672
1132
|
|
|
673
|
-
If you intentionally target MV2 for a
|
|
1133
|
+
If you intentionally target MV2 for a browser that still supports it (e.g. Firefox).
|
|
674
1134
|
|
|
675
1135
|
#### Introduced in
|
|
676
1136
|
|
|
@@ -679,11 +1139,15 @@ If you intentionally target MV2 for a Chromium fork that still supports it.
|
|
|
679
1139
|
#### See also
|
|
680
1140
|
|
|
681
1141
|
- [`require-mv3`](#require-mv3)
|
|
1142
|
+
<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>
|
|
1143
|
+
<a title="Works w/ '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>
|
|
682
1144
|
- [`no-deprecated-apis`](#no-deprecated-apis)
|
|
1145
|
+
<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>
|
|
1146
|
+
<a title="Accepts array w/ options" href="#no-deprecated-apis-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
683
1147
|
|
|
684
1148
|
<div align="center">
|
|
685
1149
|
|
|
686
|
-
[Back to index ↑][
|
|
1150
|
+
[Back to index ↑][epce-rules]
|
|
687
1151
|
|
|
688
1152
|
</div>
|
|
689
1153
|
|
|
@@ -737,11 +1201,16 @@ If your background context isn't a service worker.
|
|
|
737
1201
|
#### See also
|
|
738
1202
|
|
|
739
1203
|
- [`require-mv3`](#require-mv3)
|
|
1204
|
+
<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>
|
|
1205
|
+
<a title="Works w/ '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>
|
|
740
1206
|
- [`no-remote-code`](#no-remote-code)
|
|
1207
|
+
<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>
|
|
1208
|
+
<a title="Included in security config" href="#usage"><img height=14 alt="[Security]" src="https://img.shields.io/badge/Security-e8357a?style=flat-square" align="middle"></a>
|
|
1209
|
+
<a title="Accepts array w/ options" href="#no-remote-code-options"><img height=14 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
741
1210
|
|
|
742
1211
|
<div align="center">
|
|
743
1212
|
|
|
744
|
-
[Back to index ↑][
|
|
1213
|
+
[Back to index ↑][epce-rules]
|
|
745
1214
|
|
|
746
1215
|
</div>
|
|
747
1216
|
|
|
@@ -753,6 +1222,8 @@ If your background context isn't a service worker.
|
|
|
753
1222
|
<code>valid-version-field</code>
|
|
754
1223
|
<a title="Included in recommended config" href="#usage">
|
|
755
1224
|
<img height=18 alt="[Recommended]" src="https://img.shields.io/badge/Recommended-f1f20a?style=flat-square" align="middle"></a>
|
|
1225
|
+
<a title="Works w/ 'json/json' config block" href="#usage">
|
|
1226
|
+
<img height=18 alt="[Manifest]" src="https://img.shields.io/badge/Manifest-999999?style=flat-square" align="middle"></a>
|
|
756
1227
|
<a title="Accepts array w/ options" href="#usage">
|
|
757
1228
|
<img height=18 alt="[Configurable]" src="https://img.shields.io/badge/Configurable-black?style=flat-square" align="middle"></a>
|
|
758
1229
|
<a title="Copy rule URL" target="_blank"
|
|
@@ -764,7 +1235,7 @@ If your background context isn't a service worker.
|
|
|
764
1235
|
|
|
765
1236
|
<summary>Validates the manifest <code>version</code> field.</summary>
|
|
766
1237
|
|
|
767
|
-
|
|
1238
|
+
<h4 id="valid-version-field-options">Options</h4>
|
|
768
1239
|
|
|
769
1240
|
- `versionType` (default `'chrome'`) – version format to enforce (`'chrome'`, `'semver'`, `'date'`)
|
|
770
1241
|
- `allowFutureDate` (default `false`) – allow `version` dates later than the current date
|
|
@@ -775,7 +1246,6 @@ If your background context isn't a service worker.
|
|
|
775
1246
|
```diff
|
|
776
1247
|
/* eslint chrome-extensions/valid-version-field: ['error', { versionType: 'date' }] */
|
|
777
1248
|
|
|
778
|
-
// manifest.json
|
|
779
1249
|
{
|
|
780
1250
|
"manifest_version": 3,
|
|
781
1251
|
! "version": "2026.1.111",
|
|
@@ -788,7 +1258,6 @@ If your background context isn't a service worker.
|
|
|
788
1258
|
```diff
|
|
789
1259
|
/* eslint chrome-extensions/valid-version-field: ['error', { versionType: 'date' }] */
|
|
790
1260
|
|
|
791
|
-
// manifest.json
|
|
792
1261
|
{
|
|
793
1262
|
"manifest_version": 3,
|
|
794
1263
|
- "version": "2026.1.111",
|
|
@@ -807,11 +1276,11 @@ If you don't care about version format consistency, or your version is injected
|
|
|
807
1276
|
|
|
808
1277
|
#### See also
|
|
809
1278
|
|
|
810
|
-
- <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/version">Chrome for Developers — `version`</a>
|
|
1279
|
+
- <img height=12 src="https://www.google.com/s2/favicons?domain=developer.chrome.com&sz=64"> <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest/version">Chrome for Developers — `version`</a>
|
|
811
1280
|
|
|
812
1281
|
<div align="center">
|
|
813
1282
|
|
|
814
|
-
[Back to index ↑][
|
|
1283
|
+
[Back to index ↑][epce-rules]
|
|
815
1284
|
|
|
816
1285
|
</div>
|
|
817
1286
|
|
|
@@ -902,4 +1371,4 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
902
1371
|
|
|
903
1372
|
<!-- Links -->
|
|
904
1373
|
|
|
905
|
-
[
|
|
1374
|
+
[epce-rules]: #supported-rules
|