| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- const acorn = require('acorn');
- const FILES_INJECTED = [`src/injected/**/*.js`];
- const FILES_CONTENT = [`src/injected/content/**/*.js`];
- const FILES_WEB = [`src/injected/web/**/*.js`];
- // some functions are used by `injected`
- const FILES_SHARED = [
- 'src/common/browser.js',
- 'src/common/consts.js',
- 'src/common/index.js',
- 'src/common/object.js',
- 'src/common/util.js',
- ];
- const GLOBALS_COMMON = getGlobals('src/common/safe-globals.js');
- const GLOBALS_INJECTED = getGlobals(`src/injected/safe-globals-injected.js`);
- const GLOBALS_CONTENT = {
- ...getGlobals(`src/injected/content/safe-globals-content.js`),
- ...GLOBALS_INJECTED,
- };
- const GLOBALS_WEB = {
- ...getGlobals(`src/injected/web/safe-globals-web.js`),
- ...GLOBALS_INJECTED,
- IS_FIREFOX: false, // passed as a parameter to VMInitInjection in webpack.conf.js
- };
- module.exports = {
- root: true,
- extends: [
- require.resolve('@gera2ld/plaid/eslint'),
- require.resolve('@gera2ld/plaid-vue/eslint/vue'),
- ],
- parserOptions: {
- ecmaFeatures: {
- legacyDecorators: true,
- },
- },
- overrides: [{
- // `browser` is a local variable since we remove the global `chrome` and `browser` in injected*
- // to prevent exposing them to userscripts with `@inject-into content`
- files: ['*'],
- excludedFiles: [...FILES_INJECTED, ...FILES_SHARED],
- globals: {
- browser: false,
- ...GLOBALS_COMMON,
- },
- }, {
- files: FILES_SHARED,
- globals: GLOBALS_COMMON,
- }, {
- files: FILES_WEB,
- globals: GLOBALS_WEB,
- }, {
- files: FILES_CONTENT,
- globals: GLOBALS_CONTENT,
- }, {
- files: FILES_INJECTED,
- excludedFiles: [...FILES_CONTENT, ...FILES_WEB],
- // intersection of globals in CONTENT and WEB
- globals: Object.keys(GLOBALS_CONTENT).reduce((res, key) => (
- Object.assign(res, key in GLOBALS_WEB && { [key]: false })
- ), {}),
- }, {
- files: [...FILES_INJECTED, ...FILES_SHARED],
- rules: {
- /* Our .browserslistrc targets old browsers so the compiled code for {...objSpread} uses
- babel's polyfill that calls methods like `Object.assign` instead of our safe `assign`.
- Ideally, `eslint-plugin-compat` should be used but I couldn't make it work. */
- 'no-restricted-syntax': ['error', {
- selector: 'ObjectExpression > ExperimentalSpreadProperty',
- message: 'Object spread adds a polyfill in injected* even if unused by it',
- }, {
- selector: 'OptionalCallExpression',
- message: 'Optional call uses .call(), which may be spoofed/broken in an unsafe environment',
- // TODO: write a Babel plugin to use safeCall for this.
- }, {
- selector: 'ArrayPattern',
- message: 'Destructuring via Symbol.iterator may be spoofed/broken in an unsafe environment',
- }, {
- selector: ':matches(ArrayExpression, CallExpression) > SpreadElement',
- message: 'Spreading via Symbol.iterator may be spoofed/broken in an unsafe environment',
- }],
- },
- }, {
- // build scripts
- files: [
- '*.js',
- 'scripts/*.js',
- ],
- env: { node: true },
- rules: {
- 'global-require': 0,
- 'import/newline-after-import': 0,
- 'import/no-extraneous-dependencies': 0, // spits errors in github action
- }
- }],
- rules: {
- 'import/extensions': ['error', 'ignorePackages', {
- js: 'never',
- vue: 'never',
- }],
- // copied from airbnb-base, replaced 4 with 8
- 'object-curly-newline': ['error', {
- ObjectExpression: { minProperties: 8, multiline: true, consistent: true },
- ObjectPattern: { minProperties: 8, multiline: true, consistent: true },
- ImportDeclaration: { minProperties: 8, multiline: true, consistent: true },
- ExportDeclaration: { minProperties: 8, multiline: true, consistent: true },
- }],
- },
- };
- function getGlobals(fileName) {
- const text = require('fs').readFileSync(fileName, { encoding: 'utf8' });
- const res = {};
- const tree = acorn.parse(text, { ecmaVersion: 2018, sourceType: 'module' });
- tree.body.forEach(body => {
- const { declarations } = body.declaration || body;
- if (!declarations) return;
- declarations.forEach(function processId({ id: { left, properties, name = left && left.name } }) {
- if (name) {
- // const NAME = whatever
- res[name] = false;
- } else if (properties) {
- // const { NAME1, prototype: { NAME2: ALIAS2 } } = whatever
- properties.forEach(({ value }) => processId({ id: value }));
- }
- });
- });
- return res;
- }
|