fix: Migrate to addons-linter JSONSchema validator and Firefox JSONSchema import to ajv v8 (#4263)

* fix(deps): update dependency ajv to v8
* fix(deps): update dependency ajv-merge-patch to v5
* fix: Update JSONSchema based validation to ajv v8
* fix: Update Firefox JSONSchema import to ajv v8
* chore: Increase test coverage for localejson parser and rename the remaining dataPath properties into instancePath
* chore: fix missing instancePath in cryptominer validation errors
* chore: removed inline comment mentioning deprecated ajv options
* chore: rename collector.messagesAtDataPath into messagesAtInstancePath

Co-authored-by: Renovate Bot <bot@renovateapp.com>
This commit is contained in:
Luca Greco 2022-04-28 11:18:44 +02:00 коммит произвёл GitHub
Родитель f3804a15be
Коммит d10e01a9bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
98 изменённых файлов: 551 добавлений и 373 удалений

362
package-lock.json сгенерированный
Просмотреть файл

@ -12,8 +12,8 @@
"@mdn/browser-compat-data": "4.1.17",
"addons-moz-compare": "1.2.0",
"addons-scanner-utils": "7.0.0",
"ajv": "6.12.6",
"ajv-merge-patch": "4.1.0",
"ajv": "8.11.0",
"ajv-merge-patch": "5.0.1",
"chalk": "4.1.2",
"cheerio": "1.0.0-rc.10",
"columnify": "1.6.0",
@ -2044,6 +2044,21 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@eslint/eslintrc/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@eslint/eslintrc/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -3215,13 +3230,13 @@
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
@ -3239,17 +3254,22 @@
}
},
"node_modules/ajv-merge-patch": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz",
"integrity": "sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-5.0.1.tgz",
"integrity": "sha512-0UP3aJCzfzBOkmLR+EinJDCfg6DNtprj3bVPo7JJNgUpZMKt097t9xxQOWFGRoB4JvKKIHE2qe0HkVaS/HyrjQ==",
"dependencies": {
"fast-json-patch": "^2.0.6",
"json-merge-patch": "^0.2.3"
"json-merge-patch": "^1.0.2"
},
"peerDependencies": {
"ajv": ">=6.0.0"
"ajv": ">=8.0.0"
}
},
"node_modules/ajv/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -3999,6 +4019,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
@ -4721,22 +4742,6 @@
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
"dev": true
},
"node_modules/deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"dependencies": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@ -4762,6 +4767,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
"dev": true,
"dependencies": {
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
@ -5756,6 +5762,21 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/eslint/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/eslint/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -6401,7 +6422,8 @@
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
@ -6412,6 +6434,7 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -6437,6 +6460,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
@ -6680,6 +6704,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
@ -6717,6 +6742,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.1.1"
},
@ -6737,6 +6763,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
@ -6760,6 +6787,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"dev": true,
"dependencies": {
"has-symbols": "^1.0.2"
},
@ -7060,21 +7088,6 @@
"node": ">= 0.10"
}
},
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@ -7150,6 +7163,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@ -7298,6 +7312,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@ -8352,11 +8367,11 @@
"peer": true
},
"node_modules/json-merge-patch": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz",
"integrity": "sha1-+ixrWvh9p3uuKWalidUuI+2B/kA=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-1.0.2.tgz",
"integrity": "sha512-M6Vp2GN9L7cfuMXiWOmHj9bEFbeC250iVtcKQbqVgEsDVYnIsrNsbU+h/Y/PkbBQCtEa4Bez+Ebv0zfbC8ObLg==",
"dependencies": {
"deep-equal": "^1.0.0"
"fast-deep-equal": "^3.1.3"
}
},
"node_modules/json-parse-better-errors": {
@ -9093,25 +9108,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-is": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
@ -10145,6 +10146,22 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/raw-loader/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/raw-loader/node_modules/schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@ -10253,6 +10270,7 @@
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
@ -10421,6 +10439,14 @@
"node": ">=0.10.0"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@ -10600,6 +10626,22 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/schema-utils/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/seek-bzip": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
@ -11374,6 +11416,22 @@
}
}
},
"node_modules/terser-webpack-plugin/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/terser-webpack-plugin/node_modules/schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@ -12134,6 +12192,22 @@
"node": ">=10.13.0"
}
},
"node_modules/webpack/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/webpack/node_modules/schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@ -13726,6 +13800,17 @@
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -14695,14 +14780,21 @@
}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"dependencies": {
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
}
}
},
"ajv-keywords": {
@ -14713,12 +14805,12 @@
"requires": {}
},
"ajv-merge-patch": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz",
"integrity": "sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-5.0.1.tgz",
"integrity": "sha512-0UP3aJCzfzBOkmLR+EinJDCfg6DNtprj3bVPo7JJNgUpZMKt097t9xxQOWFGRoB4JvKKIHE2qe0HkVaS/HyrjQ==",
"requires": {
"fast-json-patch": "^2.0.6",
"json-merge-patch": "^0.2.3"
"json-merge-patch": "^1.0.2"
}
},
"ansi-escapes": {
@ -15291,6 +15383,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
@ -15837,19 +15930,6 @@
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
"dev": true
},
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
}
},
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@ -15872,6 +15952,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
"dev": true,
"requires": {
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
@ -16284,6 +16365,17 @@
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -17113,7 +17205,8 @@
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"functional-red-black-tree": {
"version": "1.0.1",
@ -17123,7 +17216,8 @@
"functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true
},
"gensync": {
"version": "1.0.0-beta.2",
@ -17140,6 +17234,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
@ -17332,6 +17427,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
@ -17357,6 +17453,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
"dev": true,
"requires": {
"get-intrinsic": "^1.1.1"
}
@ -17370,7 +17467,8 @@
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true
},
"has-to-string-tag-x": {
"version": "1.4.1",
@ -17385,6 +17483,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"dev": true,
"requires": {
"has-symbols": "^1.0.2"
}
@ -17590,15 +17689,6 @@
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"peer": true
},
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
}
},
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@ -17653,6 +17743,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dev": true,
"requires": {
"has-tostringtag": "^1.0.0"
}
@ -17756,6 +17847,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@ -18575,11 +18667,11 @@
"peer": true
},
"json-merge-patch": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz",
"integrity": "sha1-+ixrWvh9p3uuKWalidUuI+2B/kA=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-1.0.2.tgz",
"integrity": "sha512-M6Vp2GN9L7cfuMXiWOmHj9bEFbeC250iVtcKQbqVgEsDVYnIsrNsbU+h/Y/PkbBQCtEa4Bez+Ebv0zfbC8ObLg==",
"requires": {
"deep-equal": "^1.0.0"
"fast-deep-equal": "^3.1.3"
}
},
"json-parse-better-errors": {
@ -19171,19 +19263,11 @@
"integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
"dev": true
},
"object-is": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
}
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
"object.assign": {
"version": "4.1.2",
@ -19939,6 +20023,18 @@
"schema-utils": "^3.0.0"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@ -20030,6 +20126,7 @@
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
@ -20154,6 +20251,11 @@
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
},
"resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@ -20275,6 +20377,20 @@
"@types/json-schema": "^7.0.5",
"ajv": "^6.12.4",
"ajv-keywords": "^3.5.2"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
}
}
},
"seek-bzip": {
@ -20902,6 +21018,18 @@
"terser": "^5.7.2"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@ -21405,6 +21533,18 @@
"webpack-sources": "^3.2.3"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",

Просмотреть файл

@ -47,8 +47,8 @@
"@mdn/browser-compat-data": "4.1.17",
"addons-moz-compare": "1.2.0",
"addons-scanner-utils": "7.0.0",
"ajv": "6.12.6",
"ajv-merge-patch": "4.1.0",
"ajv": "8.11.0",
"ajv-merge-patch": "5.0.1",
"chalk": "4.1.2",
"cheerio": "1.0.0-rc.10",
"columnify": "1.6.0",

Просмотреть файл

@ -10,7 +10,7 @@ import * as constants from 'const';
export default class Collector {
constructor(config = {}) {
this.config = config;
this.messagesByDataPath = {};
this.messagesByInstancePath = {};
this.scannedFiles = {};
constants.MESSAGE_TYPES.forEach((type) => {
@ -51,26 +51,28 @@ export default class Collector {
return this[`${type}s`];
}
messagesAtDataPath(dataPath) {
if (dataPath === undefined) {
throw new Error('dataPath is required');
messagesAtInstancePath(instancePath) {
if (instancePath === undefined) {
throw new Error('instancePath is required');
}
if (!this.messagesByDataPath[dataPath]) {
this.messagesByDataPath[dataPath] = [];
if (!this.messagesByInstancePath[instancePath]) {
this.messagesByInstancePath[instancePath] = [];
}
return this.messagesByDataPath[dataPath];
return this.messagesByInstancePath[instancePath];
}
_recordMessage(message, type) {
if (message.dataPath) {
this.messagesAtDataPath(message.dataPath).push(message);
if (message.instancePath) {
this.messagesAtInstancePath(message.instancePath).push(message);
}
this.messageList(type).push(message);
}
isDuplicateMessage(message) {
if (message.dataPath) {
const previousMessages = this.messagesAtDataPath(message.dataPath);
if (message.instancePath) {
const previousMessages = this.messagesAtInstancePath(
message.instancePath
);
if (message.file === 'manifest.json') {
return previousMessages.some(
(prevMessage) => prevMessage.code === message.code

Просмотреть файл

@ -758,9 +758,9 @@ export default class Linter {
file: filename,
line: matchedLine,
column: matchedColumn,
// use dataPath for our actual match to avoid any obvious
// use instancePath for our actual match to avoid any obvious
// duplicates
dataPath: match[0],
instancePath: match[0],
});
}
});

Просмотреть файл

@ -11,7 +11,7 @@ export const props = [
'column',
'file',
'line',
'dataPath',
'instancePath',
];
export const requiredProps = ['code', 'message', 'description'];

Просмотреть файл

@ -49,7 +49,7 @@ export function manifestPermissionUnsupported(permissionName, error) {
const message = i18n.sprintf(messageTmpl, {
permissionName,
versionRange,
fieldName: error.dataPath.match(PERMS_DATAPATH_REGEX)[1],
fieldName: error.instancePath.match(PERMS_DATAPATH_REGEX)[1],
});
return {

Просмотреть файл

@ -35,7 +35,7 @@ export default class LocaleMessagesJSONParser extends JSONParser {
let baseObject = messages.JSON_INVALID;
const overrides = {
dataPath: error.dataPath,
instancePath: error.instancePath,
line: error.line,
file: this.filename,
};
@ -103,7 +103,7 @@ export default class LocaleMessagesJSONParser extends JSONParser {
...messages.JSON_DUPLICATE_KEY,
file: this.filename,
description: `Case-insensitive duplicate message name: ${message} found in JSON`,
dataPath: `/${message}`,
instancePath: `/${message}`,
});
this.isValid = false;
}
@ -111,7 +111,7 @@ export default class LocaleMessagesJSONParser extends JSONParser {
if (message.startsWith('@@')) {
this.collector.addWarning({
file: this.filename,
dataPath: `/${message}`,
instancePath: `/${message}`,
...messages.PREDEFINED_MESSAGE_NAME,
});
}
@ -122,7 +122,7 @@ export default class LocaleMessagesJSONParser extends JSONParser {
if (!this.hasPlaceholder(message, matches[1])) {
this.collector.addWarning({
file: this.filename,
dataPath: `/${message}/placeholders/${matches[1]}`,
instancePath: `/${message}/placeholders/${matches[1]}`,
...messages.MISSING_PLACEHOLDER,
});
}
@ -147,7 +147,7 @@ export default class LocaleMessagesJSONParser extends JSONParser {
...messages.JSON_DUPLICATE_KEY,
file: this.filename,
description: `Case-insensitive duplicate placeholder name: ${placeholder} found in JSON`,
dataPath: `/${message}/placeholders/${placeholder}`,
instancePath: `/${message}/placeholders/${placeholder}`,
});
this.isValid = false;
}

Просмотреть файл

@ -232,7 +232,7 @@ export default class ManifestJSONParser extends JSONParser {
}
errorLookup(error) {
if (error.dataPath === '/permissions' && error.keyword === 'anyOf') {
if (error.instancePath === '/permissions' && error.keyword === 'anyOf') {
// With the addition of the schema data for the manifest_version 3
// JSONSchema data, permissions has a top level anyOf schema entry
// which include the two alternative set of schema definitions
@ -261,15 +261,15 @@ export default class ManifestJSONParser extends JSONParser {
// super helpful error. We'll tidy it up a bit:
if (error && error.message) {
const lowerCaseMessage = error.message.toLowerCase();
if (lowerCaseMessage === 'should match some schema in anyof') {
if (lowerCaseMessage === 'must match a schema in anyof') {
// eslint-disable-next-line no-param-reassign
error.message = 'is not a valid key or has invalid extra properties';
}
}
const overrides = {
message: `"${error.dataPath}" ${error.message}`,
dataPath: error.dataPath,
message: `"${error.instancePath || '/'}" ${error.message}`,
instancePath: error.instancePath,
};
if (error.keyword === 'required') {
@ -278,10 +278,11 @@ export default class ManifestJSONParser extends JSONParser {
if (
Object.prototype.hasOwnProperty.call(
DEPRECATED_MANIFEST_PROPERTIES,
error.dataPath
error.instancePath
)
) {
baseObject = messages[DEPRECATED_MANIFEST_PROPERTIES[error.dataPath]];
baseObject =
messages[DEPRECATED_MANIFEST_PROPERTIES[error.instancePath]];
if (baseObject === null) {
baseObject = messages.MANIFEST_FIELD_DEPRECATED;
@ -307,10 +308,13 @@ export default class ManifestJSONParser extends JSONParser {
) {
// Choose a different message for permissions unsupported with the
// add-on manifest_version.
if (PERMS_DATAPATH_REGEX.test(error.dataPath)) {
if (PERMS_DATAPATH_REGEX.test(error.instancePath)) {
baseObject = messages.manifestPermissionUnsupported(error.data, error);
} else {
baseObject = messages.manifestFieldUnsupported(error.dataPath, error);
baseObject = messages.manifestFieldUnsupported(
error.instancePath,
error
);
}
// Set the message and description from the one generated by the
@ -318,21 +322,21 @@ export default class ManifestJSONParser extends JSONParser {
overrides.message = baseObject.message;
overrides.description = baseObject.description;
} else if (
error.dataPath.startsWith('/permissions') &&
error.instancePath.startsWith('/permissions') &&
typeof error.data !== 'undefined' &&
typeof error.data !== 'string'
) {
baseObject = messages.MANIFEST_BAD_PERMISSION;
overrides.message = `Permissions ${error.message}.`;
} else if (
error.dataPath.startsWith('/optional_permissions') &&
error.instancePath.startsWith('/optional_permissions') &&
typeof error.data !== 'undefined' &&
typeof error.data !== 'string'
) {
baseObject = messages.MANIFEST_BAD_OPTIONAL_PERMISSION;
overrides.message = `Permissions ${error.message}.`;
} else if (
error.dataPath.startsWith('/host_permissions') &&
error.instancePath.startsWith('/host_permissions') &&
typeof error.data !== 'undefined' &&
typeof error.data !== 'string'
) {
@ -348,8 +352,8 @@ export default class ManifestJSONParser extends JSONParser {
// Note that this works because the 2 regexps use similar patterns. We'll
// want to adjust this if they start to differ.
const match =
error.dataPath.match(PERMS_DATAPATH_REGEX) ||
error.dataPath.match(INSTALL_ORIGINS_DATAPATH_REGEX);
error.instancePath.match(PERMS_DATAPATH_REGEX) ||
error.instancePath.match(INSTALL_ORIGINS_DATAPATH_REGEX);
if (
match &&

Просмотреть файл

@ -12,7 +12,7 @@ const schemaObjectNames = ['types', 'properties'];
const schemas = schemaList.reduce(
(all, current) => ({
...all,
[current.id]: current,
[current.$id]: current,
}),
{}
);

Просмотреть файл

@ -652,9 +652,16 @@ function schemaFiles(basePath) {
function writeSchemasToFile(basePath, importedPath, loadedSchemas) {
const ids = Object.keys(loadedSchemas);
// Write out the schemas.
ids.forEach((id) => {
const { file, schema } = loadedSchemas[id];
writeSchema(importedPath, file, schema);
ids.forEach((currId) => {
const { file, schema } = loadedSchemas[currId];
const { id, ...rest } = schema;
writeSchema(
importedPath,
file,
// Normalize schema to draft7 spec
// (required for ajv v8).
{ $id: id, ...rest }
);
});
// Write out the index.js to easily import all schemas.
const imports = ids

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "action",
"$id": "action",
"description": "Use browser actions to put icons in the main browser toolbar, to the right of the address bar. In addition to its icon, a browser action can also have a tooltip, a badge, and a popup.",
"permissions": [
"manifest:action",

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "activityLog",
"$id": "activityLog",
"description": "Monitor extension activity",
"permissions": [
"activityLog"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "alarms",
"$id": "alarms",
"permissions": [
"alarms"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "bookmarks",
"$id": "bookmarks",
"description": "Use the <code>browser.bookmarks</code> API to create, organize, and otherwise manipulate bookmarks. Also see $(topic:override)[Override Pages], which you can use to create a custom Bookmark Manager page.",
"permissions": [
"bookmarks"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "browserAction",
"$id": "browserAction",
"description": "Use browser actions to put icons in the main browser toolbar, to the right of the address bar. In addition to its icon, a browser action can also have a tooltip, a badge, and a popup.",
"permissions": [
"manifest:action",

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "browserSettings",
"$id": "browserSettings",
"description": "Use the <code>browser.browserSettings</code> API to control global settings of the browser.",
"permissions": [
"browserSettings"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "browsingData",
"$id": "browsingData",
"description": "Use the <code>chrome.browsingData</code> API to remove browsing data from a user's local profile.",
"permissions": [
"browsingData"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "captivePortal",
"$id": "captivePortal",
"description": "This API provides the ability detect the captive portal state of the users connection.",
"permissions": [
"captivePortal"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "chrome_settings_overrides",
"$id": "chrome_settings_overrides",
"definitions": {
"WebExtensionManifest": {
"properties": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "clipboard",
"$id": "clipboard",
"description": "Offers the ability to write to the clipboard. Reading is not supported because the clipboard can already be read through the standard web platform APIs.",
"permissions": [
"clipboardWrite"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "commands",
"$id": "commands",
"description": "Use the commands API to add keyboard shortcuts that trigger actions in your extension, for example, an action to open the browser action or send a command to the xtension.",
"permissions": [
"manifest:commands"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "contentScripts",
"$id": "contentScripts",
"functions": [
{
"name": "register",

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "contextMenus",
"$id": "contextMenus",
"permissions": [
"menus",
"contextMenus"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "contextualIdentities",
"$id": "contextualIdentities",
"description": "Use the <code>browser.contextualIdentities</code> API to query and modify contextual identity, also called as containers.",
"permissions": [
"contextualIdentities"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "cookies",
"$id": "cookies",
"description": "Use the <code>browser.cookies</code> API to query and modify cookies, and to be notified when they change.",
"permissions": [
"cookies"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "devtools",
"$id": "devtools",
"permissions": [
"manifest:devtools_page"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "dns",
"$id": "dns",
"description": "Asynchronous DNS API",
"permissions": [
"dns"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "downloads",
"$id": "downloads",
"permissions": [
"downloads"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "events",
"$id": "events",
"description": "The <code>chrome.events</code> namespace contains common types used by APIs dispatching events to notify you when something interesting happens.",
"definitions": {},
"refs": {},

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "experiments",
"$id": "experiments",
"definitions": {
"Permission": {
"anyOf": [

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "extension",
"$id": "extension",
"allowedContexts": [
"content",
"devtools"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "extension_protocol_handlers",
"$id": "extension_protocol_handlers",
"definitions": {
"WebExtensionManifest": {
"properties": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "extensionTypes",
"$id": "extensionTypes",
"description": "The <code>browser.extensionTypes</code> API contains type declarations for WebExtensions.",
"definitions": {},
"refs": {},

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "find",
"$id": "find",
"description": "Use the <code>browser.find</code> API to interact with the browser's <code>Find</code> interface.",
"permissions": [
"find"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "geckoProfiler",
"$id": "geckoProfiler",
"description": "Exposes the browser's profiler.",
"permissions": [
"geckoProfiler"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "history",
"$id": "history",
"description": "Use the <code>browser.history</code> API to interact with the browser's record of visited pages. You can add, remove, and query for URLs in the browser's history. To override the history page with your own version, see $(topic:override)[Override Pages].",
"permissions": [
"history"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "i18n",
"$id": "i18n",
"allowedContexts": [
"content",
"devtools"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "identity",
"$id": "identity",
"description": "Use the chrome.identity API to get OAuth2 access tokens. ",
"permissions": [
"identity"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "idle",
"$id": "idle",
"description": "Use the <code>browser.idle</code> API to detect when the machine's idle state changes.",
"permissions": [
"idle"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "management",
"$id": "management",
"description": "The <code>browser.management</code> API provides ways to manage the list of extensions that are installed and running.",
"functions": [
{

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "manifest",
"$id": "manifest",
"permissions": [],
"definitions": {},
"refs": {},

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "menus",
"$id": "menus",
"permissions": [
"menus"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "native_manifest",
"$id": "native_manifest",
"definitions": {},
"refs": {},
"types": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "networkStatus",
"$id": "networkStatus",
"description": "This API provides the ability to determine the status of and detect changes in the network connection. This API can only be used in privileged extensions.",
"permissions": [
"networkStatus"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "normandyAddonStudy",
"$id": "normandyAddonStudy",
"description": "Normandy Study API",
"allowedContexts": [
"content",

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "notifications",
"$id": "notifications",
"permissions": [
"notifications"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "omnibox",
"$id": "omnibox",
"description": "The omnibox API allows you to register a keyword with Firefox's address bar.",
"permissions": [
"manifest:omnibox"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "pageAction",
"$id": "pageAction",
"description": "Use the <code>browser.pageAction</code> API to put icons inside the address bar. Page actions represent actions that can be taken on the current page, but that aren't applicable to all pages.",
"permissions": [
"manifest:page_action"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "permissions",
"$id": "permissions",
"permissions": [
"manifest:optional_permissions"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "pkcs11",
"$id": "pkcs11",
"description": "PKCS#11 module management API",
"permissions": [
"pkcs11"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "privacy",
"$id": "privacy",
"permissions": [
"privacy"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "proxy",
"$id": "proxy",
"description": "Provides access to global proxy settings for Firefox and proxy event listeners to handle dynamic proxy implementations.",
"permissions": [
"proxy"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "runtime",
"$id": "runtime",
"allowedContexts": [
"content",
"devtools"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "scripting",
"$id": "scripting",
"description": "Use the scripting API to execute script in different contexts.",
"permissions": [
"scripting"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "search",
"$id": "search",
"description": "Use browser.search to interact with search engines.",
"permissions": [
"search"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "sessions",
"$id": "sessions",
"description": "Use the <code>chrome.sessions</code> API to query and restore tabs and windows from a browsing session.",
"permissions": [
"sessions"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "sidebarAction",
"$id": "sidebarAction",
"description": "Use sidebar actions to add a sidebar to Firefox.",
"permissions": [
"manifest:sidebar_action"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "storage",
"$id": "storage",
"allowedContexts": [
"content",
"devtools"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "tabs",
"$id": "tabs",
"description": "Use the <code>browser.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
"properties": {
"TAB_ID_NONE": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "telemetry",
"$id": "telemetry",
"description": "Use the <code>browser.telemetry</code> API to send telemetry data to the Mozilla Telemetry service. Restricted to Mozilla privileged webextensions.",
"permissions": [
"telemetry"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "test",
"$id": "test",
"allowedContexts": [
"content",
"devtools"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "theme",
"$id": "theme",
"description": "The theme API allows customizing of visual elements of the browser.",
"events": [
{

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "topSites",
"$id": "topSites",
"description": "Use the chrome.topSites API to access the top sites that are displayed on the new tab page. ",
"permissions": [
"topSites"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "types",
"$id": "types",
"description": "Contains types used by other schemas.",
"definitions": {},
"refs": {},

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "url_overrides",
"$id": "url_overrides",
"definitions": {
"WebExtensionManifest": {
"properties": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "urlbar",
"$id": "urlbar",
"description": "Use the <code>browser.urlbar</code> API to experiment with new features in the URLBar. Restricted to Mozilla privileged WebExtensions.",
"permissions": [
"urlbar"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "userScripts",
"$id": "userScripts",
"permissions": [
"manifest:user_scripts"
],

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "webNavigation",
"$id": "webNavigation",
"description": "Use the <code>browser.webNavigation</code> API to receive notifications about the status of navigation requests in-flight.",
"permissions": [
"webNavigation"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "webRequest",
"$id": "webRequest",
"description": "Use the <code>browser.webRequest</code> API to observe and analyze traffic and to intercept, block, or modify requests in-flight.",
"permissions": [
"webRequest"

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "windows",
"$id": "windows",
"description": "Use the <code>browser.windows</code> API to interact with browser windows. You can use this API to create, modify, and rearrange windows in the browser.",
"properties": {
"WINDOW_ID_NONE": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "messages",
"$id": "messages",
"types": {
"i18nPlaceholder": {
"type": "object",

Просмотреть файл

@ -1,4 +1,4 @@
import ajv from 'ajv';
import Ajv from 'ajv';
import ajvMergePatch from 'ajv-merge-patch';
import { getDefaultConfigValue } from 'yargs-options';
@ -24,8 +24,6 @@ import {
} from './formats';
import schemas from './imported';
const jsonSchemaDraft06 = require('ajv/lib/refs/json-schema-draft-06');
function isRelevantError({
error,
manifest_version,
@ -34,7 +32,7 @@ function isRelevantError({
// The errors related to the manifest_version are always relevant,
// if an error has been collected for it then it is because the
// addon manifest_version is outside or the allowed range.
if (error.dataPath === '/manifest_version') {
if (error.instancePath === '/manifest_version') {
return true;
}
@ -57,7 +55,7 @@ function isRelevantError({
);
const isTopLevelManifestKey =
error.dataPath.split('/').filter((s) => s.length).length === 1;
error.instancePath.split('/').filter((s) => s.length).length === 1;
const errorFromAnyOf = error.schemaPath.includes('/anyOf/');
// Skip the error if it is not in range, only when the error is:
//
@ -86,7 +84,7 @@ function isRelevantError({
// An error collected by an `anyOf` schema entry is relevant only if its the schema
// entries are relevant for the given addon manifest_version.
if (error.keyword === 'anyOf') {
const anyOfSchemaEntries = error.schema.filter((schema) => {
const anyOfSchemaEntries = error.schema?.filter((schema) => {
const min = schema.min_manifest_version ?? minimum;
const max = schema.mix_manifest_version ?? maximum;
@ -98,7 +96,7 @@ function isRelevantError({
// - there is only one relevant entry (in that case an error for that entry would
// have been already collected and there is no need to report it again as part
// of the error collected by anyOf.
if (anyOfSchemaEntries.length <= 1) {
if (anyOfSchemaEntries?.length <= 1) {
return false;
}
}
@ -205,17 +203,18 @@ export class SchemaValidator {
this.allowedManifestVersionsRange =
getManifestVersionsRange(validatorOptions);
const validator = ajv({
const validator = new Ajv({
strict: false,
allErrors: true,
errorDataPath: 'property',
jsonPointers: true,
// include schema and data properties in error objects.
verbose: true,
schemas: this.schemas,
schemaId: 'auto',
});
validator.addMetaSchema(jsonSchemaDraft06);
for (const schema of Object.values(this.schemas)) {
validator.addSchema(schema);
}
ajvMergePatch(validator);
this._addCustomFormats(validator);
this._addCustomKeywords(validator);
this._validator = validator;
@ -298,7 +297,7 @@ export class SchemaValidator {
},
})
),
id: 'static-theme-manifest',
$id: 'static-theme-manifest',
$ref: '#/types/ThemeManifest',
});
}
@ -328,7 +327,7 @@ export class SchemaValidator {
},
},
}),
id: 'langpack-manifest',
$id: 'langpack-manifest',
$ref: '#/types/WebExtensionLangpackManifest',
});
}
@ -356,7 +355,7 @@ export class SchemaValidator {
},
},
}),
id: 'dictionary-manifest',
$id: 'dictionary-manifest',
$ref: '#/types/WebExtensionDictionaryManifest',
});
}
@ -368,7 +367,7 @@ export class SchemaValidator {
if (!this._localeValidator) {
this._localeValidator = this._validator.compile({
...this.messagesSchemaObject,
id: 'messages',
$id: 'messages',
$ref: '#/types/WebExtensionMessages',
});
}
@ -396,7 +395,7 @@ export class SchemaValidator {
},
},
}),
id: 'sitepermission-manifest',
$id: 'sitepermission-manifest',
$ref: '#/types/WebExtensionSitePermissionsManifest',
});
}
@ -422,7 +421,7 @@ export class SchemaValidator {
return validator.compile({
...schemaData,
id: 'manifest',
$id: 'manifest',
$ref: '#/types/WebExtensionManifest',
});
}
@ -454,17 +453,19 @@ export class SchemaValidator {
}
_addCustomKeywords(validator) {
validator.addKeyword('deprecated', {
validator.removeKeyword('deprecated');
validator.addKeyword({
keyword: 'deprecated',
validate: function validateDeprecated(
message,
propValue,
schema,
dataPath
{ instancePath }
) {
if (
!Object.prototype.hasOwnProperty.call(
DEPRECATED_MANIFEST_PROPERTIES,
dataPath
instancePath
)
) {
// Do not emit errors for every deprecated property, as it may introduce
@ -491,10 +492,7 @@ export class SchemaValidator {
keywordSchemaValue,
propValue,
schema,
dataPath,
parentData,
parentDataProperty,
rootData
{ rootData /* instancePath, parentData, parentDataProperty, */ }
) {
const manifestVersion =
(rootData && rootData.manifest_version) || MANIFEST_VERSION_DEFAULT;
@ -526,7 +524,8 @@ export class SchemaValidator {
};
}
validator.addKeyword('max_manifest_version', {
validator.addKeyword({
keyword: 'max_manifest_version',
// function of type SchemaValidateFunction (see ajv typescript signatures).
validate: createManifestVersionValidateFn(
'max_manifest_version',
@ -535,7 +534,8 @@ export class SchemaValidator {
errors: true,
});
validator.addKeyword('min_manifest_version', {
validator.addKeyword({
keyword: 'min_manifest_version',
validate: createManifestVersionValidateFn(
'min_manifest_version',
(minMV, manifestVersion) => minMV <= manifestVersion

2
tests/fixtures/schema/expected/cookies.json поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "cookies",
"$id": "cookies",
"description": "Use the <code>browser.cookies</code> API to query and modify cookies, and to be notified when they change.",
"permissions": ["cookies"],
"types": {

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "manifest",
"$id": "manifest",
"permissions": [],
"definitions": {},
"refs": {},

Просмотреть файл

@ -40,6 +40,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(errors.length).toEqual(1);
expect(errors[0].code).toEqual(messages.NO_PLACEHOLDER_CONTENT.code);
expect(errors[0].message).toEqual(messages.NO_PLACEHOLDER_CONTENT.message);
expect(errors[0].instancePath).toEqual('/blah/placeholders/CONTENT');
});
it('should be invalid without message property for string', () => {
@ -58,6 +59,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(errors.length).toEqual(1);
expect(errors[0].code).toEqual(messages.NO_MESSAGE.code);
expect(errors[0].message).toEqual(messages.NO_MESSAGE.message);
expect(errors[0].instancePath).toEqual('/blah');
});
it('should show a warning for reserved message names', () => {
@ -78,6 +80,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(warnings[0].message).toEqual(
messages.PREDEFINED_MESSAGE_NAME.message
);
expect(warnings[0].instancePath).toEqual('/@@extension_id');
});
it('should show warnings for missing placeholders', () => {
@ -104,8 +107,10 @@ describe('LocaleMessagesJSONParser', () => {
expect(warnings.length).toEqual(2);
expect(warnings[0].code).toEqual(messages.MISSING_PLACEHOLDER.code);
expect(warnings[0].message).toEqual(messages.MISSING_PLACEHOLDER.message);
expect(warnings[0].instancePath).toEqual('/blah/placeholders/BAZ');
expect(warnings[1].code).toEqual(messages.MISSING_PLACEHOLDER.code);
expect(warnings[1].message).toEqual(messages.MISSING_PLACEHOLDER.message);
expect(warnings[1].instancePath).toEqual('/bleh/placeholders/EMPTY');
});
it('should not be invalid on non alphanumeric message name', () => {
@ -161,6 +166,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(errors[0].message).toEqual(
messages.INVALID_PLACEHOLDER_NAME.message
);
expect(errors[0].instancePath).toEqual('/invalid_placeholder/placeholders');
});
it('should not be case sensitive for placeholder names', () => {
@ -236,6 +242,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(errors[0].description).toContain(
'Case-insensitive duplicate message name'
);
expect(errors[0].instancePath).toEqual('/DUPLICATE');
});
it('should be invalid with case-insensitive duplicate placeholder names', () => {
@ -264,6 +271,7 @@ describe('LocaleMessagesJSONParser', () => {
expect(errors[0].description).toContain(
'Case-insensitive duplicate placeholder name'
);
expect(errors[0].instancePath).toEqual('/duplicate/placeholders/foo');
});
describe('getLowercasePlaceholders', () => {

Просмотреть файл

@ -71,8 +71,8 @@ describe('ManifestJSONParser', () => {
expect(addonLinter.collector.errors.length).toEqual(1);
assertHasMatchingError(addonLinter.collector.errors, {
code: messages.JSON_INVALID.code,
message: /update_url" should match format "secureUrl"/,
dataPath: '/browser_specific_settings/gecko/update_url',
message: /update_url" must match format "secureUrl"/,
instancePath: '/browser_specific_settings/gecko/update_url',
});
});
@ -127,7 +127,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
assertHasMatchingError(addonLinter.collector.errors, {
code: messages.JSON_INVALID.code,
message: /"\/applications\/gecko\/id" should match pattern/,
message: /"\/applications\/gecko\/id" must match pattern/,
});
});
@ -143,7 +143,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
assertHasMatchingError(addonLinter.collector.errors, {
code: messages.JSON_INVALID.code,
message: /"\/applications\/gecko\/id" should match pattern/,
message: /"\/applications\/gecko\/id" must match pattern/,
});
});
@ -162,7 +162,7 @@ describe('ManifestJSONParser', () => {
assertHasMatchingError(addonLinter.collector.errors, {
code: messages.JSON_INVALID.code,
message:
/"\/applications\/gecko\/id" should NOT be longer than 80 characters/,
/"\/applications\/gecko\/id" must NOT have more than 80 characters/,
});
});
@ -266,7 +266,7 @@ describe('ManifestJSONParser', () => {
expect.arrayContaining([
expect.objectContaining({
code: 'MANIFEST_PERMISSIONS',
dataPath: '/permissions/0',
instancePath: '/permissions/0',
message: expect.stringMatching(
/Invalid permissions "\*:\/\/example\.org\/\*" at 0/
),
@ -292,7 +292,7 @@ describe('ManifestJSONParser', () => {
expect.arrayContaining([
expect.objectContaining({
code: 'MANIFEST_FIELD_UNSUPPORTED',
dataPath: '/host_permissions',
instancePath: '/host_permissions',
message: expect.stringMatching(
/not supported in manifest versions < 3/
),
@ -332,7 +332,7 @@ describe('ManifestJSONParser', () => {
expect.arrayContaining([
expect.objectContaining({
code: 'MANIFEST_HOST_PERMISSIONS',
dataPath: '/host_permissions/0',
instancePath: '/host_permissions/0',
message: expect.stringMatching(
/Invalid host_permissions "foo" at 0/
),
@ -358,7 +358,7 @@ describe('ManifestJSONParser', () => {
expect.arrayContaining([
expect.objectContaining({
code: 'MANIFEST_PERMISSIONS',
dataPath: '/permissions/0',
instancePath: '/permissions/0',
message: expect.stringMatching(
/Invalid permissions "<all_urls>" at 0/
),
@ -418,7 +418,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
const { errors } = addonLinter.collector;
expect(errors[0].code).toEqual(expectedMsgCode);
expect(errors[0].message).toContain('should be string');
expect(errors[0].message).toContain('must be string');
});
it(`should error if ${manifestKey} is duplicated`, () => {
@ -439,7 +439,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
const { errors } = addonLinter.collector;
expect(errors[0].code).toEqual(expectedMsgCode);
expect(errors[0].message).toContain('should NOT have duplicate items');
expect(errors[0].message).toContain('must NOT have duplicate items');
});
}
});
@ -480,7 +480,7 @@ describe('ManifestJSONParser', () => {
validManifestJSON(),
addonLinter.collector
);
const message = parser.errorLookup({ dataPath: '' });
const message = parser.errorLookup({ instancePath: '' });
expect(message.code).toEqual(messages.JSON_INVALID.code);
});
});
@ -491,7 +491,10 @@ describe('ManifestJSONParser', () => {
validManifestJSON(),
addonLinter.collector
);
const message = parser.errorLookup({ dataPath: '', keyword: 'required' });
const message = parser.errorLookup({
instancePath: '',
keyword: 'required',
});
expect(message.code).toEqual(messages.MANIFEST_FIELD_REQUIRED.code);
});
@ -501,7 +504,7 @@ describe('ManifestJSONParser', () => {
validManifestJSON(),
addonLinter.collector
);
const message = parser.errorLookup({ dataPath: '', keyword: 'type' });
const message = parser.errorLookup({ instancePath: '', keyword: 'type' });
expect(message.code).toEqual(messages.MANIFEST_FIELD_INVALID.code);
});
@ -517,7 +520,9 @@ describe('ManifestJSONParser', () => {
validManifestJSON(),
addonLinter.collector
);
const message = parser.errorLookup({ dataPath: `/${manifestKey}/0` });
const message = parser.errorLookup({
instancePath: `/${manifestKey}/0`,
});
expect(message.code).toEqual(expectedMsgCode);
});
}
@ -530,7 +535,7 @@ describe('ManifestJSONParser', () => {
);
const message = parser.errorLookup({
keyword: 'deprecated',
dataPath: '/theme/images/headerURL',
instancePath: '/theme/images/headerURL',
message: 'This is going to be ignored...',
});
expect(message.message).toEqual(
@ -560,7 +565,7 @@ describe('ManifestJSONParser', () => {
// The following are properties added by ajv to the ones
// explicitly reported by the keyword validate function.
data: isPermission ? 'perm-value' : 'unused-field-value',
dataPath: manifestKey.includes('permissions')
instancePath: manifestKey.includes('permissions')
? `/${manifestKey}/0`
: `/${manifestKey}`,
});
@ -600,7 +605,7 @@ describe('ManifestJSONParser', () => {
// This would need to be changed to /browser_action
// if the manifest_version we test by default becomes
// manifest_version 3.
dataPath: '/action',
instancePath: '/action',
}),
])
);
@ -627,11 +632,11 @@ describe('ManifestJSONParser', () => {
);
expect(manifestJSONParser.isValid).toEqual(false);
const { warnings } = addonLinter.collector;
expect(warnings.length).toEqual(1);
expect(warnings[0].code).toEqual(expectedMsg.code);
expect(warnings[0].message).toContain(
`/${mainfestKey}: Invalid ${mainfestKey} "wat" at 1.`
);
expect(warnings.length).toEqual(1);
});
}
});
@ -660,7 +665,9 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
const { errors } = addonLinter.collector;
expect(errors[0].code).toEqual(messages.MANIFEST_FIELD_REQUIRED.code);
expect(errors[0].message).toContain('/name');
expect(errors[0].message).toContain(
`"/" must have required property 'name'`
);
});
it('should collect an error on non-string name value', () => {
@ -700,7 +707,9 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
const { errors } = addonLinter.collector;
expect(errors[0].code).toEqual(messages.MANIFEST_FIELD_REQUIRED.code);
expect(errors[0].message).toContain('/version');
expect(errors[0].message).toContain(
`"/" must have required property 'version'`
);
});
it('should collect an error on non-string version value', () => {
@ -1341,7 +1350,6 @@ describe('ManifestJSONParser', () => {
json,
addonLinter.collector
);
expect(manifestJSONParser.isValid).toEqual(false);
const { errors } = addonLinter.collector;
assertHasMatchingError(errors, {
code: messages.JSON_INVALID.code,
@ -1349,6 +1357,7 @@ describe('ManifestJSONParser', () => {
'"/background" is not a valid key or has invalid ' +
'extra properties',
});
expect(manifestJSONParser.isValid).toEqual(false);
});
it('does not break when background.scripts is not an array', () => {
@ -1364,7 +1373,7 @@ describe('ManifestJSONParser', () => {
const { errors } = addonLinter.collector;
assertHasMatchingError(errors, {
code: messages.MANIFEST_FIELD_INVALID.code,
message: '"/background/scripts" should be array',
message: '"/background/scripts" must be array',
});
});
});
@ -2133,10 +2142,10 @@ describe('ManifestJSONParser', () => {
expect(linter.collector.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
dataPath: '/background/service_worker',
instancePath: '/background',
code: 'JSON_INVALID',
message: expect.stringMatching(
/"\/background\/service_worker" is an invalid additional property/
/"\/background" .* has invalid extra properties/
),
}),
])
@ -2485,7 +2494,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
assertHasMatchingError(linter.collector.errors, {
code: messages.JSON_INVALID.code,
message: '"/content_scripts" is an invalid additional property',
message: '"/" must NOT have additional properties',
description: 'Your JSON file could not be parsed.',
});
});
@ -2505,7 +2514,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(true);
});
it('throws warning on missing langpack_id', () => {
it('adds a validation error on missing langpack_id', () => {
const linter = new Linter({ _: ['bar'] });
const json = validLangpackManifestJSON({ langpack_id: null });
const manifestJSONParser = new ManifestJSONParser(
@ -2518,7 +2527,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
});
it('throws error on additional properties', () => {
it('adds a validation error on additional properties', () => {
const linter = new Linter({ _: ['bar'] });
const json = validLangpackManifestJSON({ content_scripts: ['foo.js'] });
const manifestJSONParser = new ManifestJSONParser(
@ -2531,7 +2540,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
assertHasMatchingError(linter.collector.errors, {
code: messages.JSON_INVALID.code,
message: '"/content_scripts" is an invalid additional property',
message: '"/" must NOT have additional properties',
description: 'Your JSON file could not be parsed.',
});
});
@ -2551,7 +2560,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(true);
});
it('throws warning on additional properties', () => {
it('adds a validation error on additional properties', () => {
const linter = new Linter({ _: ['bar'] });
const json = validStaticThemeManifestJSON({
content_scripts: ['foo.js'],
@ -2566,7 +2575,7 @@ describe('ManifestJSONParser', () => {
expect(manifestJSONParser.isValid).toEqual(false);
assertHasMatchingError(linter.collector.errors, {
code: messages.JSON_INVALID.code,
message: '"/content_scripts" is an invalid additional property',
message: '"/" must NOT have additional properties',
description: 'Your JSON file could not be parsed.',
});
});
@ -2886,15 +2895,15 @@ describe('ManifestJSONParser', () => {
expect(warnings).toEqual([]);
const actualErrors = errors.map((err) => {
const { code, dataPath, file, message, description } = err;
return { code, dataPath, file, message, description };
const { code, instancePath, file, message, description } = err;
return { code, instancePath, file, message, description };
});
const expectedErrors = [
{
code: messages.MANIFEST_THEME_LWT_ALIAS.code,
file: 'manifest.json',
dataPath: '/theme/images/headerURL',
instancePath: '/theme/images/headerURL',
message: 'This theme LWT alias has been removed in Firefox 70.',
description:
'See https://mzl.la/2T11Lkc (MDN Docs) for more information.',
@ -2902,7 +2911,7 @@ describe('ManifestJSONParser', () => {
{
code: messages.MANIFEST_THEME_LWT_ALIAS.code,
file: 'manifest.json',
dataPath: '/theme/colors/accentcolor',
instancePath: '/theme/colors/accentcolor',
message: 'This theme LWT alias has been removed in Firefox 70.',
description:
'See https://mzl.la/2T11Lkc (MDN Docs) for more information.',
@ -2910,7 +2919,7 @@ describe('ManifestJSONParser', () => {
{
code: messages.MANIFEST_THEME_LWT_ALIAS.code,
file: 'manifest.json',
dataPath: '/theme/colors/textcolor',
instancePath: '/theme/colors/textcolor',
message: 'This theme LWT alias has been removed in Firefox 70.',
description:
'See https://mzl.la/2T11Lkc (MDN Docs) for more information.',
@ -2989,8 +2998,8 @@ describe('ManifestJSONParser', () => {
expect.arrayContaining([
expect.objectContaining({
code: messages.JSON_INVALID.code,
message: '"/install_origins" should NOT have more than 1 items',
dataPath: '/install_origins',
message: '"/install_origins" must NOT have more than 1 items',
instancePath: '/install_origins',
}),
])
);
@ -3009,7 +3018,7 @@ describe('ManifestJSONParser', () => {
code: messages.JSON_INVALID.code,
message:
'"/site_permissions/1" is not a valid key or has invalid extra properties',
dataPath: '/site_permissions/1',
instancePath: '/site_permissions/1',
}),
])
);

Просмотреть файл

@ -39,7 +39,7 @@ export function createValidManifest(overriddenProps) {
*
* {
* page_action: {
* id: "page_action",
* $id: "page_action",
* definitions: {
* WebExtensionManifest: { ... }
* },
@ -86,8 +86,8 @@ export function getValidatorWithFakeSchema({
// We are only interested in the api Schemas
return !!schema.definitions?.WebExtensionManifest;
})
.map(({ id }) => {
return { $ref: `${id}#/definitions/WebExtensionManifest` };
.map(({ $id }) => {
return { $ref: `${$id}#/definitions/WebExtensionManifest` };
});
const fakeWebExtensionManifest = {
@ -112,7 +112,7 @@ export function getValidatorWithFakeSchema({
maxManifestVersion,
schemas: apiSchemas,
schemaObject: {
id: 'manifest',
$id: 'manifest',
refs: {},
types: {
ExtensionURL: {

Просмотреть файл

@ -23,7 +23,7 @@ describe('/browser_action', () => {
{ maxManifestVersion: 3 }
);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/browser_action',
instancePath: '/browser_action',
keyword: 'max_manifest_version',
params: { max_manifest_version: 2 },
});
@ -50,7 +50,7 @@ describe('/action', () => {
})
);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/action',
instancePath: '/action',
keyword: 'min_manifest_version',
params: { min_manifest_version: 3 },
});

Просмотреть файл

@ -26,7 +26,7 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.update_url = 'whatevs';
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/update_url'
);
});
@ -36,7 +36,7 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.update_url = 'http://foo.com';
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/update_url'
);
});
@ -53,7 +53,7 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.strict_min_version = 42;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/strict_min_version'
);
});
@ -76,7 +76,7 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.strict_min_version = version;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/strict_min_version'
);
});
@ -87,7 +87,7 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.strict_max_version = 42;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/strict_max_version'
);
});
@ -131,7 +131,9 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.id = 10;
validateAddon(manifest);
expect(validateAddon.errors.length >= 1).toBeTruthy();
expect(validateAddon.errors[0].dataPath).toEqual('/applications/gecko/id');
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/id'
);
});
it('should be invalid id format', () => {
@ -139,7 +141,9 @@ describe('/applications/gecko/*', () => {
manifest.applications.gecko.id = 'whatevs';
validateAddon(manifest);
expect(validateAddon.errors.length >= 1).toBeTruthy();
expect(validateAddon.errors[0].dataPath).toEqual('/applications/gecko/id');
expect(validateAddon.errors[0].instancePath).toEqual(
'/applications/gecko/id'
);
});
it('should accept an add-on without an id', () => {

Просмотреть файл

@ -17,6 +17,6 @@ describe('/author', () => {
manifest.author = {};
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/author');
expect(validateAddon.errors[0].instancePath).toEqual('/author');
});
});

Просмотреть файл

@ -11,8 +11,8 @@ describe('/background', () => {
manifest.background = { scripts: ['http://foo'] };
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/background/scripts/0',
message: /should match format "strictRelativeUrl"/,
instancePath: '/background/scripts/0',
message: /must match format "strictRelativeUrl"/,
});
});
@ -42,8 +42,8 @@ describe('/background', () => {
manifest.background = { page: 'http://foo' };
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/background/page',
message: /should match format "strictRelativeUrl"/,
instancePath: '/background/page',
message: /must match format "strictRelativeUrl"/,
});
});

Просмотреть файл

@ -31,8 +31,8 @@ describe('/commands', () => {
};
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/commands/up/suggested_key/mac',
message: 'should match format "manifestShortcutKey"',
instancePath: '/commands/up/suggested_key/mac',
message: 'must match format "manifestShortcutKey"',
});
});
});

Просмотреть файл

@ -42,8 +42,8 @@ describe('/content_scripts', () => {
];
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/content_scripts/0/run_at',
message: 'should be equal to one of the allowed values',
instancePath: '/content_scripts/0/run_at',
message: 'must be equal to one of the allowed values',
});
});
});

Просмотреть файл

@ -32,11 +32,11 @@ describe('/developer', () => {
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/developer/url',
message: /should match format "url"/,
instancePath: '/developer/url',
message: /must match format "url"/,
});
assertHasMatchingError(validateAddon.errors, {
message: 'should match pattern "^__MSG_.*?__$"',
message: 'must match pattern "^__MSG_.*?__$"',
});
});
});
@ -66,7 +66,7 @@ describe('/developer', () => {
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/developer/name');
expect(validateAddon.errors[0].instancePath).toEqual('/developer/name');
});
});
});

Просмотреть файл

@ -28,11 +28,11 @@ describe('/homepage_url', () => {
manifest.homepage_url = invalidURL;
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/homepage_url',
message: /should match format "url"/,
instancePath: '/homepage_url',
message: /must match format "url"/,
});
assertHasMatchingError(validateAddon.errors, {
message: 'should match pattern "^__MSG_.*?__$"',
message: 'must match pattern "^__MSG_.*?__$"',
});
});
});

Просмотреть файл

@ -17,8 +17,8 @@ describe('/icons', () => {
manifest.icons = { 48: 1 };
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/icons/48');
expect(validateAddon.errors[0].message).toEqual('should be string');
expect(validateAddon.errors[0].instancePath).toEqual('/icons/48');
expect(validateAddon.errors[0].message).toEqual('must be string');
});
it('should fail on non-number key', () => {
@ -26,9 +26,9 @@ describe('/icons', () => {
manifest.icons = { wat: 'foo' };
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/icons/wat');
expect(validateAddon.errors[0].instancePath).toEqual('/icons');
expect(validateAddon.errors[0].message).toEqual(
'is an invalid additional property'
'must NOT have additional properties'
);
});
});

Просмотреть файл

@ -18,8 +18,8 @@ describe('/incognito', () => {
manifest.incognito = 'wat';
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/incognito',
message: 'should be equal to one of the allowed values',
instancePath: '/incognito',
message: 'must be equal to one of the allowed values',
});
});
});

Просмотреть файл

@ -16,8 +16,10 @@ describe('langpack', () => {
manifest.manifest_version = null;
validateLangPack(manifest);
expect(validateLangPack.errors.length).toEqual(1);
expect(validateLangPack.errors[0].dataPath).toEqual('/manifest_version');
expect(validateLangPack.errors[0].message).toEqual('should be integer');
expect(validateLangPack.errors[0].instancePath).toEqual(
'/manifest_version'
);
expect(validateLangPack.errors[0].message).toEqual('must be integer');
});
it('should fail on missing langpack_id', () => {
@ -25,8 +27,8 @@ describe('langpack', () => {
manifest.langpack_id = null;
validateLangPack(manifest);
expect(validateLangPack.errors.length).toEqual(1);
expect(validateLangPack.errors[0].dataPath).toEqual('/langpack_id');
expect(validateLangPack.errors[0].message).toEqual('should be string');
expect(validateLangPack.errors[0].instancePath).toEqual('/langpack_id');
expect(validateLangPack.errors[0].message).toEqual('must be string');
});
it('should fail on langpack_id < 1 character', () => {
@ -34,9 +36,9 @@ describe('langpack', () => {
manifest.langpack_id = 'a';
validateLangPack(manifest);
expect(validateLangPack.errors.length).toEqual(1);
expect(validateLangPack.errors[0].dataPath).toEqual('/langpack_id');
expect(validateLangPack.errors[0].instancePath).toEqual('/langpack_id');
expect(validateLangPack.errors[0].message).toEqual(
'should match pattern "^[a-zA-Z][a-zA-Z-]+$"'
'must match pattern "^[a-zA-Z][a-zA-Z-]+$"'
);
});
});

Просмотреть файл

@ -16,7 +16,7 @@ describe('messages', () => {
delete messages.foo.message;
validateLocaleMessages(messages);
expect(validateLocaleMessages.errors.length).toEqual(1);
expect(validateLocaleMessages.errors[0].dataPath).toEqual('/foo/message');
expect(validateLocaleMessages.errors[0].instancePath).toEqual('/foo');
});
it('should not validate the message name', () => {
@ -31,8 +31,8 @@ describe('messages', () => {
delete messages.Placeh0lder_Test.placeholders.foo.content;
validateLocaleMessages(messages);
expect(validateLocaleMessages.errors.length).toEqual(1);
expect(validateLocaleMessages.errors[0].dataPath).toEqual(
'/Placeh0lder_Test/placeholders/foo/content'
expect(validateLocaleMessages.errors[0].instancePath).toEqual(
'/Placeh0lder_Test/placeholders/foo'
);
});
@ -41,8 +41,8 @@ describe('messages', () => {
messages.Placeh0lder_Test.placeholders['invalid.placeholder'] = {};
validateLocaleMessages(messages);
expect(validateLocaleMessages.errors.length).toEqual(1);
expect(validateLocaleMessages.errors[0].dataPath).toEqual(
'/Placeh0lder_Test/placeholders/invalid.placeholder'
expect(validateLocaleMessages.errors[0].instancePath).toEqual(
'/Placeh0lder_Test/placeholders'
);
});
});

Просмотреть файл

@ -9,7 +9,7 @@ describe('/manifest_version', () => {
const manifest = cloneDeep(validManifest);
manifest.manifest_version = 1;
validateAddon(manifest);
expect(validateAddon.errors[0].dataPath).toEqual('/manifest_version');
expect(validateAddon.errors[0].instancePath).toEqual('/manifest_version');
expect(validateAddon.errors.length).toEqual(1);
});
@ -19,8 +19,8 @@ describe('/manifest_version', () => {
const manifest = cloneDeep(validManifest);
manifest.manifest_version = 3;
validateAddon(manifest);
expect(validateAddon.errors[0].dataPath).toEqual('/manifest_version');
expect(validateAddon.errors[0].message).toEqual('should be <= 2');
expect(validateAddon.errors[0].instancePath).toEqual('/manifest_version');
expect(validateAddon.errors[0].message).toEqual('must be <= 2');
expect(validateAddon.errors.length).toEqual(1);
});
@ -29,7 +29,7 @@ describe('/manifest_version', () => {
manifest.manifest_version = undefined;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/manifest_version');
expect(validateAddon.errors[0].instancePath).toEqual('');
expect(validateAddon.errors[0].params.missingProperty).toEqual(
'manifest_version'
);

Просмотреть файл

@ -10,7 +10,7 @@ describe('/name', () => {
manifest.name = 'a'.repeat(46);
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/name');
expect(validateAddon.errors[0].instancePath).toEqual('/name');
});
it('should be invalid due to name < 2 chars', () => {
@ -18,7 +18,7 @@ describe('/name', () => {
manifest.name = 'a';
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/name');
expect(validateAddon.errors[0].instancePath).toEqual('/name');
});
it('should be invalid due to missing a name', () => {
@ -26,7 +26,7 @@ describe('/name', () => {
manifest.name = undefined;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/name');
expect(validateAddon.errors[0].instancePath).toEqual('');
expect(validateAddon.errors[0].params.missingProperty).toEqual('name');
});
});

Просмотреть файл

@ -18,7 +18,7 @@ describe('/permissions', () => {
manifest.permissions = ['tabs', 'tabs'];
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/permissions',
instancePath: '/permissions',
});
});
@ -27,7 +27,7 @@ describe('/permissions', () => {
manifest.permissions = ['wat'];
validateAddon(manifest);
assertHasMatchingError(validateAddon.errors, {
dataPath: '/permissions/0',
instancePath: '/permissions/0',
});
});

Просмотреть файл

@ -78,7 +78,7 @@ describe('Schema JSON', () => {
maxManifestVersion: 3,
apiSchemas: {
action: {
id: 'action',
$id: 'action',
definitions: {
WebExtensionManifest: {
properties: {
@ -104,7 +104,7 @@ describe('Schema JSON', () => {
expect(validator.validateAddon.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
dataPath: '/action',
instancePath: '/action',
keyword: 'min_manifest_version',
params: { min_manifest_version: 3 },
}),
@ -130,8 +130,8 @@ describe('Schema JSON', () => {
const validator = getValidatorWithFakeSchema({
maxManifestVersion: 3,
apiSchemas: {
action: {
id: 'page_action',
page_action: {
$id: 'page_action',
definitions: {
WebExtensionManifest: {
properties: {
@ -167,7 +167,7 @@ describe('Schema JSON', () => {
expect(validator.validateAddon.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
dataPath: '/page_action',
instancePath: '/page_action',
keyword: 'max_manifest_version',
params: { max_manifest_version: 2 },
}),

Просмотреть файл

@ -17,8 +17,10 @@ describe('static theme', () => {
validateStaticTheme(manifest);
expect(validateStaticTheme.errors.length).toEqual(1);
expect(validateStaticTheme.errors[0].dataPath).toEqual('/manifest_version');
expect(validateStaticTheme.errors[0].message).toEqual('should be integer');
expect(validateStaticTheme.errors[0].instancePath).toEqual(
'/manifest_version'
);
expect(validateStaticTheme.errors[0].message).toEqual('must be integer');
});
it('should fail on missing theme property', () => {
@ -26,8 +28,8 @@ describe('static theme', () => {
manifest.theme = null;
validateStaticTheme(manifest);
expect(validateStaticTheme.errors.length).toEqual(1);
expect(validateStaticTheme.errors[0].dataPath).toEqual('/theme');
expect(validateStaticTheme.errors[0].message).toEqual('should be object');
expect(validateStaticTheme.errors[0].instancePath).toEqual('/theme');
expect(validateStaticTheme.errors[0].message).toEqual('must be object');
});
it('should fail on invalid additional properties', () => {
@ -35,9 +37,9 @@ describe('static theme', () => {
manifest.content_scripts = ['foo.js'];
validateStaticTheme(manifest);
expect(validateStaticTheme.errors.length).toEqual(1);
expect(validateStaticTheme.errors[0].dataPath).toEqual('/content_scripts');
expect(validateStaticTheme.errors[0].instancePath).toEqual('');
expect(validateStaticTheme.errors[0].message).toEqual(
'is an invalid additional property'
'must NOT have additional properties'
);
});
});

Просмотреть файл

@ -10,7 +10,7 @@ describe('/version', () => {
manifest.version = '01';
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/version');
expect(validateAddon.errors[0].instancePath).toEqual('/version');
});
it('should be invalid due to missing version', () => {
@ -18,7 +18,7 @@ describe('/version', () => {
manifest.version = undefined;
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual('/version');
expect(validateAddon.errors[0].instancePath).toEqual('');
expect(validateAddon.errors[0].params.missingProperty).toEqual('version');
});

Просмотреть файл

@ -11,10 +11,10 @@ describe('/web_accessible_resources', () => {
manifest.web_accessible_resources = 'foo.png';
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/web_accessible_resources'
);
expect(validateAddon.errors[0].message).toEqual('should be array');
expect(validateAddon.errors[0].message).toEqual('must be array');
});
it('should fail if not an array of strings', () => {
@ -22,10 +22,10 @@ describe('/web_accessible_resources', () => {
manifest.web_accessible_resources = ['foo.png', 1];
validateAddon(manifest);
expect(validateAddon.errors.length).toEqual(1);
expect(validateAddon.errors[0].dataPath).toEqual(
expect(validateAddon.errors[0].instancePath).toEqual(
'/web_accessible_resources/1'
);
expect(validateAddon.errors[0].message).toEqual('should be string');
expect(validateAddon.errors[0].message).toEqual('must be string');
});
it('should be array of strings', () => {
@ -63,8 +63,8 @@ describe('/web_accessible_resources', () => {
expect(validateAddon.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
dataPath: '/web_accessible_resources/0',
message: expect.stringMatching('should be object'),
instancePath: '/web_accessible_resources/0',
message: expect.stringMatching('must be object'),
}),
])
);
@ -86,8 +86,8 @@ describe('/web_accessible_resources', () => {
expect(validateAddon.errors).toEqual(
expect.arrayContaining([
expect.objectContaining({
dataPath: '/web_accessible_resources/0/resources',
message: expect.stringMatching('should be array'),
instancePath: '/web_accessible_resources/0/resources',
message: expect.stringMatching('must be array'),
}),
])
);

Просмотреть файл

@ -66,10 +66,10 @@ describe('Collector', () => {
expect(collection.notices.length).toEqual(0);
});
it('should not add a duplicate message with a dataPath', () => {
it('should not add a duplicate message with a instancePath', () => {
const collection = new Collector();
collection.addWarning({ ...fakeMessageData, dataPath: '/foo' });
collection.addWarning({ ...fakeMessageData, dataPath: '/foo' });
collection.addWarning({ ...fakeMessageData, instancePath: '/foo' });
collection.addWarning({ ...fakeMessageData, instancePath: '/foo' });
expect(collection.warnings.length).toEqual(1);
expect(collection.warnings[0].type).toEqual('warning');
expect(collection.errors.length).toEqual(0);
@ -88,17 +88,17 @@ describe('Collector', () => {
});
});
it('for manifest should add one message for dataPath', () => {
it('for manifest should add one message for instancePath', () => {
const collection = new Collector();
collection.addError({
...fakeMessageData,
file: 'manifest.json',
dataPath: '/foo/1',
instancePath: '/foo/1',
});
collection.addError({
...fakeMessageData,
file: 'manifest.json',
dataPath: '/foo/1',
instancePath: '/foo/1',
message: 'foo bar',
});
expect(collection.errors.length).toBe(1);
@ -108,13 +108,13 @@ describe('Collector', () => {
const collection = new Collector();
collection.addWarning({
...fakeMessageData,
dataPath: '/foo',
instancePath: '/foo',
file: 'foo.js',
line: 25,
});
collection.addWarning({
...fakeMessageData,
dataPath: '/foo',
instancePath: '/foo',
file: 'foo.js',
line: 26,
});
@ -127,10 +127,10 @@ describe('Collector', () => {
it('should add a message that differs on one prop', () => {
const collection = new Collector();
collection.addWarning({ ...fakeMessageData, dataPath: '/foo' });
collection.addWarning({ ...fakeMessageData, instancePath: '/foo' });
collection.addWarning({
...fakeMessageData,
dataPath: '/foo',
instancePath: '/foo',
message: 'Foo message',
});
expect(collection.warnings.length).toEqual(2);
@ -197,10 +197,10 @@ describe('Collector', () => {
expect(collection.notices[0].file).toEqual('test.js');
});
it('should throw when getting messages for an undefined dataPath', () => {
it('should throw when getting messages for an undefined instancePath', () => {
const collection = new Collector();
expect(() => {
collection.messagesAtDataPath(undefined);
}).toThrow(/dataPath is required/);
collection.messagesAtInstancePath(undefined);
}).toThrow(/instancePath is required/);
});
});

Просмотреть файл

@ -1501,7 +1501,7 @@ describe('Linter.extractMetadata()', () => {
code: 'COINMINER_USAGE_DETECTED',
column: 284,
line: 2,
dataPath: 'CoinHive.CONFIG',
instancePath: 'CoinHive.CONFIG',
file: 'coinhive_disguised_as_preferences.js',
});
@ -1509,7 +1509,7 @@ describe('Linter.extractMetadata()', () => {
code: 'COINMINER_USAGE_DETECTED',
column: 119556,
line: 26,
dataPath: 'CryptonightWASMWrapper',
instancePath: 'CryptonightWASMWrapper',
file: 'coinhive_disguised_as_preferences.js',
});
@ -1524,7 +1524,7 @@ describe('Linter.extractMetadata()', () => {
code: 'COINMINER_USAGE_DETECTED',
column: 134338,
line: 1,
dataPath: 'CryptonightWASMWrapper',
instancePath: 'CryptonightWASMWrapper',
file: 'coinhive_disguised_renamed.js',
});
@ -1532,7 +1532,7 @@ describe('Linter.extractMetadata()', () => {
code: 'COINMINER_USAGE_DETECTED',
column: undefined,
line: undefined,
dataPath: undefined,
instancePath: undefined,
file: 'coinhive.min.js',
});
});