| /** |
| * @license |
| * Copyright 2020 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| // Do not add any bazel-specific properties in this file to keep it clean. |
| // Please add such properties to the .eslintrc-bazel.js file |
| const path = require('path'); |
| |
| module.exports = { |
| extends: ['eslint:recommended', 'google'], |
| parserOptions: { |
| ecmaVersion: 9, |
| sourceType: 'module', |
| }, |
| env: { |
| browser: true, |
| es6: true, |
| }, |
| rules: { |
| // https://eslint.org/docs/rules/no-confusing-arrow |
| 'no-confusing-arrow': 'error', |
| // https://eslint.org/docs/rules/newline-per-chained-call |
| 'newline-per-chained-call': ['error', {ignoreChainWithDepth: 2}], |
| // https://eslint.org/docs/rules/arrow-body-style |
| 'arrow-body-style': ['error', 'as-needed', |
| {requireReturnForObjectLiteral: true}], |
| // https://eslint.org/docs/rules/arrow-parens |
| 'arrow-parens': ['error', 'as-needed'], |
| // https://eslint.org/docs/rules/block-spacing |
| 'block-spacing': ['error', 'always'], |
| // https://eslint.org/docs/rules/brace-style |
| 'brace-style': ['error', '1tbs', {allowSingleLine: true}], |
| // https://eslint.org/docs/rules/camelcase |
| 'camelcase': 'off', |
| // https://eslint.org/docs/rules/comma-dangle |
| 'comma-dangle': ['error', { |
| arrays: 'always-multiline', |
| objects: 'always-multiline', |
| imports: 'always-multiline', |
| exports: 'always-multiline', |
| functions: 'never', |
| }], |
| // https://eslint.org/docs/rules/eol-last |
| 'eol-last': 'off', |
| 'guard-for-in': 'error', |
| // https://eslint.org/docs/rules/indent |
| 'indent': ['error', 2, { |
| MemberExpression: 2, |
| FunctionDeclaration: {body: 1, parameters: 2}, |
| FunctionExpression: {body: 1, parameters: 2}, |
| CallExpression: {arguments: 2}, |
| ArrayExpression: 1, |
| ObjectExpression: 1, |
| SwitchCase: 1, |
| }], |
| // https://eslint.org/docs/rules/keyword-spacing |
| 'keyword-spacing': ['error', {after: true, before: true}], |
| // https://eslint.org/docs/rules/lines-between-class-members |
| 'lines-between-class-members': ['error', 'always'], |
| // https://eslint.org/docs/rules/max-len |
| 'max-len': [ |
| 'error', |
| 80, |
| 2, |
| { |
| ignoreComments: true, |
| ignorePattern: '^import .*;$', |
| }, |
| ], |
| // https://eslint.org/docs/rules/new-cap |
| 'new-cap': ['error', { |
| capIsNewExceptions: ['Polymer'], |
| capIsNewExceptionPattern: '^.*Mixin$', |
| }], |
| // https://eslint.org/docs/rules/no-console |
| 'no-console': [ |
| 'error', |
| { |
| allow: [ |
| 'warn', 'error', 'info', 'debug', 'assert', 'group', 'groupEnd', |
| ], |
| }, |
| ], |
| // https://eslint.org/docs/rules/no-multiple-empty-lines |
| 'no-multiple-empty-lines': ['error', {max: 1}], |
| // https://eslint.org/docs/rules/no-prototype-builtins |
| 'no-prototype-builtins': 'off', |
| // https://eslint.org/docs/rules/no-redeclare |
| 'no-redeclare': 'off', |
| // https://eslint.org/docs/rules/no-trailing-spaces |
| 'no-trailing-spaces': 'error', |
| // https://eslint.org/docs/rules/no-irregular-whitespace |
| 'no-irregular-whitespace': 'error', |
| // https://eslint.org/docs/rules/array-callback-return |
| 'array-callback-return': ['error', {allowImplicit: true}], |
| // https://eslint.org/docs/rules/no-restricted-syntax |
| 'no-restricted-syntax': [ |
| 'error', |
| { |
| selector: 'ExpressionStatement > CallExpression > ' + |
| 'MemberExpression[object.name=\'test\'][property.name=\'only\']', |
| message: 'Remove test.only.', |
| }, |
| { |
| selector: 'ExpressionStatement > CallExpression > ' + |
| 'MemberExpression[object.name=\'suite\'][property.name=\'only\']', |
| message: 'Remove suite.only.', |
| }, |
| ], |
| // no-undef disables global variable. |
| // "globals" declares allowed global variables. |
| // https://eslint.org/docs/rules/no-undef |
| 'no-undef': ['error'], |
| // https://eslint.org/docs/rules/no-useless-escape |
| 'no-useless-escape': 'off', |
| // https://eslint.org/docs/rules/no-var |
| 'no-var': 'error', |
| // https://eslint.org/docs/rules/operator-linebreak |
| 'operator-linebreak': 'off', |
| // https://eslint.org/docs/rules/object-shorthand |
| 'object-shorthand': ['error', 'always'], |
| // https://eslint.org/docs/rules/padding-line-between-statements |
| 'padding-line-between-statements': [ |
| 'error', |
| { |
| blankLine: 'always', |
| prev: 'class', |
| next: '*', |
| }, |
| { |
| blankLine: 'always', |
| prev: '*', |
| next: 'class', |
| }, |
| ], |
| // https://eslint.org/docs/rules/prefer-arrow-callback |
| 'prefer-arrow-callback': 'error', |
| // https://eslint.org/docs/rules/prefer-const |
| 'prefer-const': 'error', |
| // https://eslint.org/docs/rules/prefer-promise-reject-errors |
| 'prefer-promise-reject-errors': 'error', |
| // https://eslint.org/docs/rules/prefer-spread |
| 'prefer-spread': 'error', |
| // https://eslint.org/docs/rules/prefer-object-spread |
| 'prefer-object-spread': 'error', |
| // https://eslint.org/docs/rules/quote-props |
| 'quote-props': ['error', 'consistent-as-needed'], |
| // https://eslint.org/docs/rules/semi |
| 'semi': ['error', 'always'], |
| // https://eslint.org/docs/rules/template-curly-spacing |
| 'template-curly-spacing': 'error', |
| |
| // https://eslint.org/docs/rules/require-jsdoc |
| 'require-jsdoc': 0, |
| // https://eslint.org/docs/rules/valid-jsdoc |
| 'valid-jsdoc': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-alignment |
| 'jsdoc/check-alignment': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-examples |
| 'jsdoc/check-examples': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-indentation |
| 'jsdoc/check-indentation': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-param-names |
| 'jsdoc/check-param-names': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-syntax |
| 'jsdoc/check-syntax': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-tag-names |
| 'jsdoc/check-tag-names': ['error', { |
| definedTags: ['attr', 'lit', 'mixinFunction', 'mixinClass', 'polymer'], |
| }], |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-types |
| 'jsdoc/check-types': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-implements-on-classes |
| 'jsdoc/implements-on-classes': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-match-description |
| 'jsdoc/match-description': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-newline-after-description |
| 'jsdoc/newline-after-description': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types |
| 'jsdoc/no-types': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-undefined-types |
| 'jsdoc/no-undefined-types': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description |
| 'jsdoc/require-description': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description-complete-sentence |
| 'jsdoc/require-description-complete-sentence': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-example |
| 'jsdoc/require-example': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-hyphen-before-param-description |
| 'jsdoc/require-hyphen-before-param-description': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc |
| 'jsdoc/require-jsdoc': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param |
| 'jsdoc/require-param': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description |
| 'jsdoc/require-param-description': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-name |
| 'jsdoc/require-param-name': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns |
| 'jsdoc/require-returns': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-check |
| 'jsdoc/require-returns-check': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-description |
| 'jsdoc/require-returns-description': 0, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-valid-types |
| 'jsdoc/valid-types': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-file-overview |
| 'jsdoc/require-file-overview': ['error', { |
| tags: { |
| license: { |
| mustExist: true, |
| preventDuplicates: true, |
| }, |
| }, |
| }], |
| // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-self-import.md |
| 'import/no-self-import': 2, |
| // The no-cycle rule is slow, because it doesn't cache dependencies. |
| // Disable it. |
| // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-cycle.md |
| 'import/no-cycle': 0, |
| // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-useless-path-segments.md |
| 'import/no-useless-path-segments': 2, |
| // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unused-modules.md |
| 'import/no-unused-modules': 2, |
| // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-default-export.md |
| 'import/no-default-export': 2, |
| 'regex/invalid': [ |
| 'error', [{ |
| // eslint-disable-next-line regex/invalid |
| regex: 'Licensed under', |
| message: 'Please use SPDX license headers.', |
| }], |
| ], |
| }, |
| |
| // List of allowed globals in all files |
| globals: { |
| // Polygerrit global variables. |
| // You must not add anything new in this list! |
| // Instead export variables from modules |
| // TODO(dmfilippov): Remove global variables from polygerrit |
| // Global variables from 3rd party libraries. |
| // You should not add anything in this list, always try to import |
| // If import is not possible - you can extend this list |
| ShadyCSS: 'readonly', |
| linkify: 'readonly', |
| security: 'readonly', |
| }, |
| overrides: [ |
| { |
| files: ['.eslintrc.js', '.eslintrc-bazel.js'], |
| env: { |
| browser: false, |
| es6: true, |
| node: true, |
| }, |
| }, |
| { |
| // .js-only rules |
| files: ['**/*.js'], |
| rules: { |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-type |
| 'jsdoc/require-param-type': 2, |
| // https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-type |
| 'jsdoc/require-returns-type': 2, |
| 'import/named': 2, |
| }, |
| globals: { |
| goog: 'readonly', |
| }, |
| }, |
| { |
| files: ['**/api/*.ts'], |
| rules: { |
| 'regex/invalid': [ |
| 'error', [{ |
| regex: 'export interface', |
| message: 'All interfaces in the api/ dir must have "declare"', |
| replacement: 'export declare interface', |
| }], |
| ], |
| }, |
| }, |
| { |
| files: ['**/*.ts'], |
| extends: [require.resolve('gts/.eslintrc.json')], |
| rules: { |
| 'regex/invalid': [ |
| 'error', [{ |
| regex: '\'lit/decorators\'', |
| message: 'use \'lit/decorators.js\' instead', |
| replacement: '\'lit/decorators.js\'', |
| }, { |
| regex: '\'lit/directives/([^.\']*)\'', |
| message: 'use \'lit/directives/foo.js\' instead', |
| replacement: { |
| function: 'return "\'lit/directives/" + $[1] + ".js\'"', |
| }, |
| }], |
| ], |
| 'no-restricted-imports': ['error', { |
| name: 'lit-html/static', |
| message: 'Use lit instead', |
| }, { |
| name: '@lit/reactive-element', |
| message: 'Use lit instead', |
| }, { |
| name: '@polymer/decorators/lib/decorators', |
| message: 'Use @polymer/decorators instead', |
| }], |
| '@typescript-eslint/no-explicit-any': 'error', |
| // See https://github.com/GoogleChromeLabs/shadow-selection-polyfill/issues/9 |
| '@typescript-eslint/ban-ts-comment': 'off', |
| // The following rules is required to match internal google rules |
| '@typescript-eslint/restrict-plus-operands': 'error', |
| '@typescript-eslint/no-unnecessary-type-assertion': 'error', |
| 'require-await': 'off', |
| '@typescript-eslint/require-await': 'error', |
| '@typescript-eslint/no-confusing-void-expression': [ |
| 'error', |
| {ignoreArrowShorthand: true}, |
| ], |
| '@typescript-eslint/no-unused-vars': [ |
| 'error', |
| {argsIgnorePattern: '^_'}, |
| ], |
| // https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-unsupported-features/es-builtins.md |
| 'node/no-unsupported-features/es-builtins': 'off', |
| // https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-unsupported-features/node-builtins.md |
| 'node/no-unsupported-features/node-builtins': 'off', |
| // Disable no-invalid-this for ts files, because it incorrectly reports |
| // errors in some cases (see https://github.com/typescript-eslint/typescript-eslint/issues/491) |
| // At the same tigit llme, we are using typescript in a strict mode and |
| // it catches almost all errors related to invalid usage of this. |
| 'no-invalid-this': 'off', |
| |
| 'node/no-extraneous-import': 'off', |
| |
| // Typescript already checks for undef |
| 'no-undef': 'off', |
| |
| 'jsdoc/no-types': 2, |
| }, |
| parserOptions: { |
| project: path.resolve(__dirname, './tsconfig_eslint.json'), |
| }, |
| }, |
| { |
| files: [ |
| '*_test.ts', |
| 'test-utils.ts', |
| ], |
| rules: { |
| '@typescript-eslint/no-explicit-any': 'off', |
| '@typescript-eslint/require-await': 'off', |
| }, |
| }, |
| { |
| files: ['*.html', 'test.js', 'test-infra.js'], |
| rules: { |
| 'jsdoc/require-file-overview': 'off', |
| }, |
| }, |
| { |
| files: [ |
| '*.html', |
| '*_test.js', |
| 'a11y-test-utils.js', |
| ], |
| // Additional global variables allowed in tests |
| globals: { |
| // Global variables from 3rd party test libraries/frameworks. |
| // You can extend this list if you want to use other global |
| // variables from these libraries and import is not possible |
| flush: 'readonly', |
| setup: 'readonly', |
| sinon: 'readonly', |
| stub: 'readonly', |
| suite: 'readonly', |
| suiteSetup: 'readonly', |
| suiteTeardown: 'readonly', |
| teardown: 'readonly', |
| test: 'readonly', |
| }, |
| }, |
| { |
| files: 'import-href.js', |
| globals: { |
| HTMLImports: 'readonly', |
| }, |
| }, |
| { |
| files: ['samples/**/*.js'], |
| globals: { |
| // Settings for samples. You can add globals here if you want to use it |
| Gerrit: 'readonly', |
| Polymer: 'readonly', |
| }, |
| }, |
| { |
| files: ['*_html.js', 'gr-icons.js', '*-theme.js', '*-styles.js'], |
| rules: { |
| 'max-len': 'off', |
| }, |
| }, |
| { |
| files: ['*_html.js'], |
| rules: { |
| 'prettier/prettier': ['error', { |
| bracketSpacing: false, |
| singleQuote: true, |
| }], |
| }, |
| }, |
| { |
| files: ['*.ts'], |
| excludedFiles: '*_html.ts', |
| rules: { |
| 'lit/attribute-value-entities': 'error', |
| 'lit/binding-positions': 'error', |
| 'lit/no-duplicate-template-bindings': 'error', |
| 'lit/no-invalid-escape-sequences': 'error', |
| 'lit/no-invalid-html': 'error', |
| 'lit/no-legacy-template-syntax': 'error', |
| 'lit/no-legacy-imports': 'error', |
| 'lit/no-private-properties': 'error', |
| 'lit/no-property-change-update': 'error', |
| 'lit/no-template-bind': 'error', |
| 'lit/no-useless-template-literals': 'error', |
| 'lit/no-value-attribute': 'error', |
| 'lit/prefer-static-styles': 'error', |
| 'lit/quoted-expressions': ['error', 'never'], |
| }, |
| }, |
| ], |
| plugins: [ |
| 'html', |
| 'jsdoc', |
| 'import', |
| 'lit', |
| 'prettier', |
| 'regex', |
| ], |
| settings: { |
| 'html/report-bad-indent': 'error', |
| 'import/resolver': { |
| node: {}, |
| [path.resolve(__dirname, './.eslint-ts-resolver.js')]: {}, |
| }, |
| 'jsdoc': { |
| tagNamePreference: { |
| returns: 'return', |
| file: 'fileoverview', |
| }, |
| }, |
| }, |
| }; |