2021-12-23 03:18:04 +00:00
|
|
|
|
module.exports = {
|
2022-02-04 11:57:55 +00:00
|
|
|
|
extends: [
|
|
|
|
|
'@wagtail/eslint-config-wagtail',
|
|
|
|
|
'plugin:@typescript-eslint/recommended',
|
2023-12-12 10:54:41 +00:00
|
|
|
|
'plugin:storybook/recommended',
|
2021-12-23 03:18:04 +00:00
|
|
|
|
],
|
2022-02-04 11:57:55 +00:00
|
|
|
|
parser: '@typescript-eslint/parser',
|
|
|
|
|
plugins: ['@typescript-eslint'],
|
|
|
|
|
env: {
|
|
|
|
|
jest: true,
|
|
|
|
|
browser: true,
|
2019-04-23 14:02:53 +00:00
|
|
|
|
},
|
2022-02-04 11:57:55 +00:00
|
|
|
|
rules: {
|
|
|
|
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
'@typescript-eslint/explicit-member-accessibility': 'off',
|
|
|
|
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
2022-02-04 11:57:55 +00:00
|
|
|
|
'@typescript-eslint/no-explicit-any': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
'@typescript-eslint/no-use-before-define': ['error'],
|
2022-12-09 07:33:28 +00:00
|
|
|
|
// it is often helpful to pull out logic to class methods that may not use `this`
|
|
|
|
|
'class-methods-use-this': 'off',
|
2021-12-23 03:18:04 +00:00
|
|
|
|
'import/extensions': [
|
2022-02-04 11:57:55 +00:00
|
|
|
|
'error',
|
2021-12-23 03:18:04 +00:00
|
|
|
|
'always',
|
|
|
|
|
{
|
|
|
|
|
ignorePackages: true,
|
|
|
|
|
pattern: {
|
|
|
|
|
js: 'never',
|
|
|
|
|
jsx: 'never',
|
|
|
|
|
ts: 'never',
|
|
|
|
|
tsx: 'never',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-05-31 21:47:50 +00:00
|
|
|
|
// does not align with the majority of legacy and newer code, some use named others use default exports
|
|
|
|
|
'import/prefer-default-export': 'off',
|
2022-06-23 10:58:56 +00:00
|
|
|
|
// allow no lines between single line members (e.g. static declarations)
|
|
|
|
|
'lines-between-class-members': [
|
|
|
|
|
'error',
|
|
|
|
|
'always',
|
|
|
|
|
{ exceptAfterSingleLine: true },
|
|
|
|
|
],
|
2022-12-09 07:14:49 +00:00
|
|
|
|
'max-classes-per-file': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
// note you must disable the base rule as it can report incorrect errors
|
|
|
|
|
'no-use-before-define': 'off',
|
|
|
|
|
'react/jsx-filename-extension': ['error', { extensions: ['.js', '.tsx'] }],
|
|
|
|
|
'no-underscore-dangle': [
|
|
|
|
|
'error',
|
2023-06-23 13:22:07 +00:00
|
|
|
|
{ allow: ['__REDUX_DEVTOOLS_EXTENSION__', '_tippy'] },
|
2022-05-20 15:08:13 +00:00
|
|
|
|
],
|
2022-09-20 10:32:33 +00:00
|
|
|
|
// this rule can be confusing as it forces some non-intuitive code for variable assignment
|
|
|
|
|
'prefer-destructuring': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
},
|
|
|
|
|
settings: {
|
2022-06-01 06:51:35 +00:00
|
|
|
|
'import/core-modules': ['jquery'],
|
|
|
|
|
'import/resolver': { node: { extensions: ['.js', '.ts', '.tsx'] } },
|
2020-10-20 23:51:09 +00:00
|
|
|
|
},
|
2022-02-04 11:57:55 +00:00
|
|
|
|
overrides: [
|
2024-01-23 14:08:49 +00:00
|
|
|
|
// Rules that needs to be adjusted for TypeScript only files
|
|
|
|
|
{
|
|
|
|
|
files: ['*.ts'],
|
|
|
|
|
rules: {
|
|
|
|
|
'@typescript-eslint/no-shadow': 'error',
|
|
|
|
|
'no-shadow': 'off',
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-06-23 12:14:04 +00:00
|
|
|
|
// Rules that we are ignoring currently due to legacy code in React components only
|
|
|
|
|
{
|
|
|
|
|
files: ['client/src/components/**'],
|
|
|
|
|
rules: {
|
|
|
|
|
'jsx-a11y/click-events-have-key-events': 'off',
|
|
|
|
|
'jsx-a11y/interactive-supports-focus': 'off',
|
|
|
|
|
'jsx-a11y/no-noninteractive-element-interactions': 'off',
|
2022-12-17 14:32:55 +00:00
|
|
|
|
'no-restricted-syntax': 'off',
|
2022-06-23 12:14:04 +00:00
|
|
|
|
'react-hooks/exhaustive-deps': 'off',
|
|
|
|
|
'react-hooks/rules-of-hooks': 'off',
|
|
|
|
|
'react/button-has-type': 'off',
|
|
|
|
|
'react/destructuring-assignment': 'off',
|
|
|
|
|
'react/forbid-prop-types': 'off',
|
|
|
|
|
'react/function-component-definition': 'off',
|
|
|
|
|
'react/jsx-props-no-spreading': 'off',
|
|
|
|
|
'react/no-danger': 'off',
|
|
|
|
|
'react/no-deprecated': 'off',
|
|
|
|
|
'react/require-default-props': 'off',
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-08-23 10:43:35 +00:00
|
|
|
|
// Rules we want to enforce or change for Stimulus Controllers
|
|
|
|
|
{
|
|
|
|
|
files: ['*Controller.ts'],
|
|
|
|
|
rules: {
|
|
|
|
|
'@typescript-eslint/member-ordering': [
|
|
|
|
|
'error',
|
|
|
|
|
{
|
|
|
|
|
classes: {
|
|
|
|
|
memberTypes: ['signature', 'field', 'method'],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
'@typescript-eslint/naming-convention': [
|
|
|
|
|
'error',
|
|
|
|
|
{
|
|
|
|
|
selector: 'method',
|
|
|
|
|
format: ['camelCase'],
|
|
|
|
|
custom: {
|
|
|
|
|
// Use connect or initialize instead of constructor, avoid generic 'render' or 'update' methods and instead be more specific.
|
|
|
|
|
regex: '^(constructor|render|update)$',
|
|
|
|
|
match: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
2023-08-02 08:46:32 +00:00
|
|
|
|
selector: 'classProperty',
|
2022-08-23 10:43:35 +00:00
|
|
|
|
format: ['camelCase'],
|
|
|
|
|
custom: {
|
|
|
|
|
// Use Stimulus values where possible for internal state, avoid a generic state object as these are not reactive.
|
|
|
|
|
regex: '^(state)$',
|
|
|
|
|
match: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
'no-restricted-properties': [
|
|
|
|
|
'error',
|
|
|
|
|
{
|
|
|
|
|
object: 'window',
|
|
|
|
|
property: 'Stimulus',
|
|
|
|
|
message:
|
|
|
|
|
"Please import the base Controller or only access the Stimulus instance via the controller's `this.application` attribute.",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-06-01 06:51:35 +00:00
|
|
|
|
// Rules we don’t want to enforce for test and tooling code.
|
2020-10-20 23:51:09 +00:00
|
|
|
|
{
|
2022-02-18 16:07:09 +00:00
|
|
|
|
files: [
|
2022-05-20 15:08:13 +00:00
|
|
|
|
'client/extract-translatable-strings.js',
|
|
|
|
|
'client/tests/**',
|
|
|
|
|
'webpack.config.js',
|
|
|
|
|
'tailwind.config.js',
|
|
|
|
|
'storybook/**/*',
|
2022-02-18 16:07:09 +00:00
|
|
|
|
'*.test.ts',
|
|
|
|
|
'*.test.tsx',
|
|
|
|
|
'*.test.js',
|
|
|
|
|
'*.stories.js',
|
|
|
|
|
'*.stories.tsx',
|
|
|
|
|
],
|
2022-02-04 11:57:55 +00:00
|
|
|
|
rules: {
|
|
|
|
|
'@typescript-eslint/no-empty-function': 'off',
|
2023-08-02 08:46:32 +00:00
|
|
|
|
'@typescript-eslint/no-this-alias': 'off',
|
2022-06-01 08:53:05 +00:00
|
|
|
|
'@typescript-eslint/no-unused-vars': 'off',
|
2022-02-04 11:57:55 +00:00
|
|
|
|
'@typescript-eslint/no-var-requires': 'off',
|
2022-06-01 08:53:05 +00:00
|
|
|
|
'global-require': 'off',
|
2022-06-23 11:21:33 +00:00
|
|
|
|
'import/first': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
'import/no-extraneous-dependencies': 'off',
|
2023-08-02 08:46:32 +00:00
|
|
|
|
'jsx-a11y/control-has-associated-label': 'off',
|
2023-10-06 07:03:17 +00:00
|
|
|
|
'no-new': 'off',
|
2022-06-01 08:53:05 +00:00
|
|
|
|
'no-unused-expressions': 'off',
|
2022-05-20 15:08:13 +00:00
|
|
|
|
'react/function-component-definition': 'off',
|
|
|
|
|
'react/jsx-props-no-spreading': 'off',
|
2022-02-04 11:57:55 +00:00
|
|
|
|
},
|
2021-09-23 12:39:38 +00:00
|
|
|
|
},
|
2022-06-01 06:51:35 +00:00
|
|
|
|
// Files that use jquery via a global
|
2021-09-23 12:39:38 +00:00
|
|
|
|
{
|
2022-06-01 06:51:35 +00:00
|
|
|
|
files: [
|
2023-09-27 21:35:01 +00:00
|
|
|
|
'wagtail/contrib/search_promotions/static_src/wagtailsearchpromotions/js/query-chooser-modal.js',
|
2022-10-27 22:26:12 +00:00
|
|
|
|
'wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js',
|
2023-09-27 21:35:01 +00:00
|
|
|
|
'wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/queries/chooser_field.js',
|
2022-06-01 06:51:35 +00:00
|
|
|
|
'wagtail/documents/static_src/wagtaildocs/js/add-multiple.js',
|
|
|
|
|
'wagtail/embeds/static_src/wagtailembeds/js/embed-chooser-modal.js',
|
|
|
|
|
'wagtail/images/static_src/wagtailimages/js/add-multiple.js',
|
|
|
|
|
'wagtail/images/static_src/wagtailimages/js/focal-point-chooser.js',
|
|
|
|
|
'wagtail/images/static_src/wagtailimages/js/image-url-generator.js',
|
|
|
|
|
'wagtail/users/static_src/wagtailusers/js/group-form.js',
|
|
|
|
|
],
|
|
|
|
|
globals: { $: 'readonly', jQuery: 'readonly' },
|
2021-09-23 12:39:38 +00:00
|
|
|
|
},
|
2022-06-01 06:51:35 +00:00
|
|
|
|
// Files that use other globals or legacy/vendor code that is unable to be easily linted
|
2021-09-23 12:39:38 +00:00
|
|
|
|
{
|
2022-05-12 13:10:59 +00:00
|
|
|
|
files: ['wagtail/**/**'],
|
2022-02-04 11:57:55 +00:00
|
|
|
|
globals: {
|
|
|
|
|
buildExpandingFormset: 'readonly',
|
|
|
|
|
escapeHtml: 'readonly',
|
|
|
|
|
ModalWorkflow: 'readonly',
|
|
|
|
|
DOCUMENT_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
|
|
|
|
|
EMBED_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
|
|
|
|
|
IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
|
|
|
|
|
QUERY_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
|
|
|
|
|
SNIPPET_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
|
2021-09-23 12:39:38 +00:00
|
|
|
|
},
|
2022-02-04 11:57:55 +00:00
|
|
|
|
rules: {
|
|
|
|
|
'@typescript-eslint/no-unused-vars': 'off',
|
|
|
|
|
'@typescript-eslint/no-use-before-define': 'off',
|
|
|
|
|
'camelcase': [
|
|
|
|
|
'error',
|
2021-09-23 12:39:38 +00:00
|
|
|
|
{
|
2022-02-04 11:57:55 +00:00
|
|
|
|
allow: [
|
|
|
|
|
'__unused_webpack_module',
|
|
|
|
|
'__webpack_modules__',
|
|
|
|
|
'__webpack_require__',
|
2021-09-23 12:39:38 +00:00
|
|
|
|
],
|
2022-02-04 11:57:55 +00:00
|
|
|
|
properties: 'never',
|
|
|
|
|
},
|
2021-09-23 12:39:38 +00:00
|
|
|
|
],
|
2022-02-04 11:57:55 +00:00
|
|
|
|
'consistent-return': 'off',
|
|
|
|
|
'func-names': 'off',
|
|
|
|
|
'id-length': 'off',
|
|
|
|
|
'no-param-reassign': 'off',
|
|
|
|
|
'no-underscore-dangle': 'off',
|
|
|
|
|
'object-shorthand': 'off',
|
|
|
|
|
'prefer-arrow-callback': 'off',
|
|
|
|
|
'vars-on-top': 'off',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|