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.
Files changed (46) hide show
  1. package/README.md +101 -23
  2. package/package.json +4 -3
  3. package/src/data/apis.js +166 -115
  4. package/src/data/deprecations.js +7 -7
  5. package/src/data/i18n.js +11 -69
  6. package/src/data/manifest.js +61 -57
  7. package/src/data/permissions.js +29 -29
  8. package/src/data/regex.js +10 -0
  9. package/src/index.js +7 -123
  10. package/src/rules/manifest-key-order.js +8 -8
  11. package/src/rules/manifest-spacing.js +5 -5
  12. package/src/rules/no-content-style-leak.js +6 -4
  13. package/src/rules/no-deprecated-apis.js +4 -4
  14. package/src/rules/no-duplicate-manifest-keys.js +3 -4
  15. package/src/rules/no-insecure-messaging.js +4 -4
  16. package/src/rules/no-invalid-permissions.js +10 -11
  17. package/src/rules/no-missing-default-locale.js +7 -9
  18. package/src/rules/no-missing-i18n-keys.js +22 -20
  19. package/src/rules/no-missing-permissions.js +7 -5
  20. package/src/rules/no-missing-web-accessible-resources.js +7 -5
  21. package/src/rules/no-remote-code.js +12 -12
  22. package/src/rules/no-sensitive-permissions.js +75 -0
  23. package/src/rules/no-unrestricted-host-permissions.js +8 -7
  24. package/src/rules/no-unused-i18n-keys.js +11 -10
  25. package/src/rules/no-unused-permissions.js +22 -23
  26. package/src/rules/require-license-file.js +9 -8
  27. package/src/rules/require-mv3.js +4 -5
  28. package/src/rules/require-short-name-when-useful.js +4 -3
  29. package/src/rules/valid-filenames.js +3 -10
  30. package/src/rules/valid-license-file.js +18 -11
  31. package/src/rules/valid-manifest-icons.js +6 -5
  32. package/src/rules/valid-mv3-schema.js +21 -21
  33. package/src/rules/valid-service-worker.js +36 -13
  34. package/src/rules/valid-url-fields.js +10 -7
  35. package/src/rules/valid-version-field.js +4 -8
  36. package/src/utils/extension.js +51 -0
  37. package/src/utils/i18n.js +55 -0
  38. package/src/utils/init.js +105 -0
  39. package/src/utils/license.js +55 -0
  40. package/src/utils/node.js +23 -0
  41. package/src/utils/pkg.js +21 -0
  42. package/src/utils/rules.js +7 -0
  43. package/src/utils/text.js +13 -0
  44. package/src/data/license.js +0 -27
  45. package/src/data/text-parser.js +0 -11
  46. package/src/utils.js +0 -95
@@ -1,11 +0,0 @@
1
- export const textParser = {
2
- parse: text => ({
3
- type: 'Program',
4
- body: [],
5
- sourceType: 'module',
6
- range: [0, text.length],
7
- loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 }},
8
- tokens: [],
9
- comments: []
10
- })
11
- }
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
- }