notebooks/workspaces/frontend/.eslintrc.js

329 lines
8.8 KiB
JavaScript

module.exports = {
parser: '@typescript-eslint/parser',
env: {
browser: true,
node: true,
},
// tell the TypeScript parser that we want to use JSX syntax
parserOptions: {
tsx: true,
jsx: true,
js: true,
useJSXTextNode: true,
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
// includes the typescript specific rules found here: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#supported-rules
plugins: [
'@typescript-eslint',
'react-hooks',
'eslint-plugin-react-hooks',
'import',
'no-only-tests',
'no-relative-import-paths',
'prettier',
'local-rules',
'@cspell',
],
extends: [
'eslint:recommended',
'plugin:jsx-a11y/recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'prettier',
],
globals: {
window: 'readonly',
describe: 'readonly',
test: 'readonly',
expect: 'readonly',
it: 'readonly',
process: 'readonly',
document: 'readonly',
},
settings: {
react: {
version: 'detect',
},
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
typescript: {
project: '.',
},
},
},
rules: {
'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
'jsx-a11y/anchor-is-valid': [
'error',
{
components: ['Link'],
specialLink: ['to'],
aspects: ['noHref', 'invalidHref', 'preferButton'],
},
],
'react/jsx-boolean-value': 'error',
'react/jsx-fragments': 'error',
'react/jsx-no-constructed-context-values': 'error',
'react/no-unused-prop-types': 'error',
'arrow-body-style': 'error',
curly: 'error',
'no-only-tests/no-only-tests': 'error',
'@typescript-eslint/default-param-last': 'error',
'@typescript-eslint/dot-notation': ['error', { allowKeywords: true }],
'@typescript-eslint/method-signature-style': 'error',
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
},
{
selector: 'function',
format: ['camelCase', 'PascalCase'],
},
{
selector: 'typeLike',
format: ['PascalCase'],
},
],
'@typescript-eslint/no-unused-expressions': [
'error',
{
allowShortCircuit: false,
allowTernary: false,
allowTaggedTemplates: false,
},
],
'@typescript-eslint/no-redeclare': 'error',
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
camelcase: 'warn',
'no-else-return': ['error', { allowElseIf: false }],
eqeqeq: ['error', 'always', { null: 'ignore' }],
'react/jsx-curly-brace-presence': [2, { props: 'never', children: 'never' }],
'object-shorthand': ['error', 'always'],
'no-param-reassign': [
'error',
{
props: true,
ignorePropertyModificationsFor: ['acc', 'e'],
ignorePropertyModificationsForRegex: ['^assignable[A-Z]'],
},
],
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'error',
'react/self-closing-comp': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'react-hooks/exhaustive-deps': 'error',
'prefer-destructuring': [
'error',
{
VariableDeclarator: {
array: false,
object: true,
},
AssignmentExpression: {
array: true,
object: false,
},
},
{
enforceForRenamedProperties: false,
},
],
'react-hooks/rules-of-hooks': 'error',
'import/extensions': 'off',
'import/no-unresolved': 'off',
'import/order': [
'error',
{
pathGroups: [
{
pattern: '~/**',
group: 'external',
position: 'after',
},
],
pathGroupsExcludedImportTypes: ['builtin'],
groups: [
'builtin',
'external',
'internal',
'index',
'sibling',
'parent',
'object',
'unknown',
],
},
],
'import/newline-after-import': 'error',
'import/no-duplicates': 'error',
'import/no-named-as-default': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: true,
optionalDependencies: true,
},
],
'no-relative-import-paths/no-relative-import-paths': [
'warn',
{
allowSameFolder: true,
rootDir: 'src',
prefix: '~',
},
],
'prettier/prettier': [
'error',
{
arrowParens: 'always',
singleQuote: true,
trailingComma: 'all',
printWidth: 100,
},
],
'react/prop-types': 'off',
'array-callback-return': ['error', { allowImplicit: true }],
'prefer-template': 'error',
'no-lone-blocks': 'error',
'no-lonely-if': 'error',
'no-promise-executor-return': 'error',
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'react-router',
message: 'Use react-router-dom instead.',
},
{
name: '@patternfly/react-core',
message:
'Use specific component imports: @patternfly/react-core/dist/esm/components/ComponentName',
},
{
name: '@patternfly/react-table',
message:
'Use specific component imports: @patternfly/react-table/dist/esm/components/ComponentName',
},
{
name: '@patternfly/react-icons',
message: 'Use specific icon imports: @patternfly/react-icons/dist/esm/icons/IconName',
},
{
name: 'date-fns',
message: 'Use specific function imports: date-fns/functionName',
},
{
name: 'lodash',
message: 'Use specific function imports: lodash/functionName',
},
],
},
],
'no-restricted-globals': [
'error',
{
name: 'isFinite',
message:
'Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite',
},
{
name: 'isNaN',
message:
'Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan',
},
],
'no-sequences': 'error',
'no-undef-init': 'error',
'no-unneeded-ternary': ['error', { defaultAssignment: false }],
'no-useless-computed-key': 'error',
'no-useless-return': 'error',
'symbol-description': 'error',
yoda: 'error',
'func-names': 'warn',
'local-rules/no-react-hook-namespace': 'error',
'local-rules/no-raw-react-router-hook': 'error',
'@cspell/spellchecker': [
'error',
{ configFile: 'config/cspell.json', customWordListFile: 'config/cspell-ignore-words.txt' },
],
},
overrides: [
{
files: ['./src/api/**'],
rules: {
'no-restricted-imports': [
'off',
{
patterns: ['~/api/**'],
},
],
},
},
{
files: ['./src/__tests__/cypress/**/*.ts'],
parserOptions: {
project: ['./src/__tests__/cypress/tsconfig.json'],
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'prettier',
'plugin:cypress/recommended',
],
},
{
files: ['src/__tests__/cypress/**'],
rules: {
'@typescript-eslint/consistent-type-imports': 'error',
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@patternfly/**'],
message:
'Cypress tests should only import mocks and types from outside the Cypress test directory.',
},
],
},
],
},
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
rules: {
'local-rules/no-react-hook-namespace': 'error',
'local-rules/no-raw-react-router-hook': 'error',
},
},
{
files: ['.eslintrc.js'],
parserOptions: {
project: null,
},
},
{
files: ['eslint-local-rules/**/*.js'],
rules: {
'@typescript-eslint/no-require-imports': 'off',
},
},
],
};