eslint-plugin-chrome-extensions 2.4.1 → 2.5.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 +101 -23
- package/package.json +4 -3
- package/src/data/apis.js +166 -115
- package/src/data/deprecations.js +7 -7
- package/src/data/i18n.js +11 -69
- package/src/data/manifest.js +61 -57
- package/src/data/permissions.js +29 -29
- package/src/data/regex.js +10 -0
- package/src/index.js +7 -123
- package/src/rules/manifest-key-order.js +8 -8
- package/src/rules/manifest-spacing.js +5 -5
- package/src/rules/no-content-style-leak.js +6 -4
- package/src/rules/no-deprecated-apis.js +4 -4
- package/src/rules/no-duplicate-manifest-keys.js +3 -4
- package/src/rules/no-insecure-messaging.js +4 -4
- package/src/rules/no-invalid-permissions.js +10 -11
- package/src/rules/no-missing-default-locale.js +7 -9
- package/src/rules/no-missing-i18n-keys.js +22 -20
- package/src/rules/no-missing-permissions.js +7 -5
- package/src/rules/no-missing-web-accessible-resources.js +7 -5
- package/src/rules/no-remote-code.js +12 -12
- package/src/rules/no-sensitive-permissions.js +75 -0
- package/src/rules/no-unrestricted-host-permissions.js +8 -7
- package/src/rules/no-unused-i18n-keys.js +11 -10
- package/src/rules/no-unused-permissions.js +22 -23
- package/src/rules/require-license-file.js +9 -8
- package/src/rules/require-mv3.js +4 -5
- package/src/rules/require-short-name-when-useful.js +4 -3
- package/src/rules/valid-filenames.js +3 -10
- package/src/rules/valid-license-file.js +18 -11
- package/src/rules/valid-manifest-icons.js +6 -5
- package/src/rules/valid-mv3-schema.js +21 -21
- package/src/rules/valid-service-worker.js +36 -13
- package/src/rules/valid-url-fields.js +10 -7
- package/src/rules/valid-version-field.js +4 -8
- package/src/utils/extension.js +51 -0
- package/src/utils/i18n.js +55 -0
- package/src/utils/init.js +105 -0
- package/src/utils/license.js +55 -0
- package/src/utils/node.js +23 -0
- package/src/utils/pkg.js +21 -0
- package/src/utils/rules.js +7 -0
- package/src/utils/text.js +13 -0
- package/src/data/license.js +0 -27
- package/src/data/text-parser.js +0 -11
- package/src/utils.js +0 -95
package/src/data/text-parser.js
DELETED
package/src/utils.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
|
|
4
|
-
const re = { chromeAPI: /\bchrome(?:\.\w+)+/g }, // eslint-disable-line security/detect-unsafe-regex
|
|
5
|
-
manifestCache = new Map()
|
|
6
|
-
|
|
7
|
-
export function bundleRules(rules, predicate, pluginName) {
|
|
8
|
-
return Object.fromEntries(Object.entries(rules)
|
|
9
|
-
.filter(([, rule]) => predicate(rule))
|
|
10
|
-
.map(([ruleId]) => [`${pluginName}/${ruleId}`, 'error']))
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function findExtensionRoot(context) {
|
|
14
|
-
let dir = path.dirname(getFilename(context))
|
|
15
|
-
while (dir) {
|
|
16
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
17
|
-
if (fs.existsSync(path.join(dir, 'manifest.json'))) return dir
|
|
18
|
-
const parent = path.dirname(dir)
|
|
19
|
-
if (parent == dir) break // reached filesystem root or a stuck relative "."
|
|
20
|
-
dir = parent
|
|
21
|
-
}
|
|
22
|
-
return null
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function getChromeAPIcalls(sourceCode) {
|
|
26
|
-
const calls = new Set()
|
|
27
|
-
for (const match of sourceCode.getText().matchAll(re.chromeAPI))
|
|
28
|
-
calls.add(match[0])
|
|
29
|
-
return calls
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function getFilename(context) { return context.filename || context.getFilename() }
|
|
33
|
-
|
|
34
|
-
export function getMemberPath(node) {
|
|
35
|
-
const parts = []
|
|
36
|
-
let cur = node
|
|
37
|
-
while (cur?.type == 'MemberExpression') {
|
|
38
|
-
if (cur.computed || cur.property.type != 'Identifier') return null
|
|
39
|
-
parts.unshift(cur.property.name)
|
|
40
|
-
cur = cur.object
|
|
41
|
-
}
|
|
42
|
-
if (cur?.type != 'Identifier') return null
|
|
43
|
-
parts.unshift(cur.name)
|
|
44
|
-
return parts.join('.')
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function initBundleDeprecation(plugin, [ruleId, bundleNames], pluginName) {
|
|
48
|
-
for (const bundleName of bundleNames) {
|
|
49
|
-
/* eslint-disable security/detect-object-injection */
|
|
50
|
-
if (plugin.configs[bundleName])
|
|
51
|
-
plugin.configs[bundleName].rules[`${pluginName}/${ruleId}`] = 'error'
|
|
52
|
-
/* eslint-enable security/detect-object-injection */
|
|
53
|
-
if (process.env.DEBUG_MODE)
|
|
54
|
-
console.warn(`[${pluginName}] '${ruleId}' will be removed from '${bundleName}' in a future major release`)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function isContentScriptFile(context, manifest) {
|
|
59
|
-
const scripts = (manifest?.content_scripts || []).flatMap(cs => cs.js || [])
|
|
60
|
-
if (!scripts.length) return false
|
|
61
|
-
const root = findExtensionRoot(context)
|
|
62
|
-
if (!root) return false
|
|
63
|
-
const filename = path.resolve(getFilename(context))
|
|
64
|
-
return scripts.some(s => filename == path.resolve(root, s))
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function isInsideNestedFunction(node) {
|
|
68
|
-
let cur = node.parent
|
|
69
|
-
while (cur) {
|
|
70
|
-
if (['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'].includes(cur.type))
|
|
71
|
-
return true
|
|
72
|
-
cur = cur.parent
|
|
73
|
-
}
|
|
74
|
-
return false
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function isServiceWorkerFile(context, manifest) {
|
|
78
|
-
const sw = manifest?.background?.service_worker
|
|
79
|
-
if (!sw) return false
|
|
80
|
-
const root = findExtensionRoot(context)
|
|
81
|
-
if (!root) return false
|
|
82
|
-
return path.resolve(getFilename(context)) == path.resolve(root, sw)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function readManifest(context) {
|
|
86
|
-
const root = findExtensionRoot(context)
|
|
87
|
-
if (!root) return null
|
|
88
|
-
if (manifestCache.has(root)) return manifestCache.get(root)
|
|
89
|
-
let parsed
|
|
90
|
-
try { // eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
91
|
-
parsed = JSON.parse(fs.readFileSync(path.join(root, 'manifest.json'), 'utf8'))
|
|
92
|
-
} catch { parsed = null }
|
|
93
|
-
manifestCache.set(root, parsed)
|
|
94
|
-
return parsed
|
|
95
|
-
}
|