From 5a143edc4caf289d67e8229baea9d27bb8c9180b Mon Sep 17 00:00:00 2001 From: glacambre Date: Sun, 17 Sep 2023 18:08:53 +0200 Subject: [PATCH] Add custom eslint rule detecting uses of potentially unsupported APIs --- .eslintrc.js | 1 + ci/lint.sh | 2 +- custom-eslint-rules/unsupported-apis.js | 42 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 custom-eslint-rules/unsupported-apis.js diff --git a/.eslintrc.js b/.eslintrc.js index ece2ab1a..fc1e490b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { "sonarjs" ], "rules": { + "unsupported-apis": "warn", "sonarjs/cognitive-complexity": "off", //"error", "sonarjs/no-duplicate-string": "off", "sonarjs/no-unused-collection": "off", //"error", // There seems to be a bug with this rule - exported collections are assumed unused diff --git a/ci/lint.sh b/ci/lint.sh index 8758e0c8..d07a94ce 100755 --- a/ci/lint.sh +++ b/ci/lint.sh @@ -6,4 +6,4 @@ else echo "Warning: shellcheck is not installed, skipping shell scripts" fi yarn run lint -"$(yarn bin)/eslint" --ext .ts . +"$(yarn bin)/eslint" --rulesdir custom-eslint-rules --ext .ts . diff --git a/custom-eslint-rules/unsupported-apis.js b/custom-eslint-rules/unsupported-apis.js new file mode 100644 index 00000000..2defd153 --- /dev/null +++ b/custom-eslint-rules/unsupported-apis.js @@ -0,0 +1,42 @@ +const bcd = require('@mdn/browser-compat-data'); +const api = bcd.webextensions.api; +const supported_browsers = ["firefox", "chrome"]; + +function detectBrowserUsage(context, node) { + let localApi = api; + let fullName = []; + while (node.type == "MemberExpression" && node.property.name in localApi) { + const n = node; + node = node.parent; + fullName.push(n.property.name); + localApi = localApi[n.property.name]; + if (!localApi.__compat) { + continue; + } + let support = localApi.__compat.support; + for (let browser of supported_browsers) { + if (support[browser].version_added === false) { + context.report({ + node: n, + messageId: "unsupportedApis", + data: { + name: browser, + } + }); + } + } + } +} + +module.exports = { + meta: { + messages: { + unsupportedApis: "Unsupported on '{{ name }}'" + } + }, + create(context) { + return { + 'MemberExpression[object.name="browser"]': (n) => detectBrowserUsage(context, n), + }; + } +};