The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/.betterer.eslint.config.js

140 lines
4.1 KiB

// @ts-check
const emotionPlugin = require('@emotion/eslint-plugin');
const importPlugin = require('eslint-plugin-import');
const jestPlugin = require('eslint-plugin-jest');
const jsxA11yPlugin = require('eslint-plugin-jsx-a11y');
const lodashPlugin = require('eslint-plugin-lodash');
const barrelPlugin = require('eslint-plugin-no-barrel-files');
const reactPlugin = require('eslint-plugin-react');
const testingLibraryPlugin = require('eslint-plugin-testing-library');
const grafanaConfig = require('@grafana/eslint-config/flat');
const grafanaPlugin = require('@grafana/eslint-plugin');
// Include the Grafana config and remove the rules,
// as we just want to pull in all of the necessary configuration but not run the rules
// (this should only be concerned with checking rules that we want to improve,
// so there's no need to try and run the rules that will be linted properly anyway)
const { rules, ...baseConfig } = grafanaConfig;
/**
* @type {Array<import('eslint').Linter.Config>}
*/
module.exports = [
{
name: 'grafana/betterer-ignores',
ignores: [
'.github',
'.yarn',
'**/.*',
'**/*.gen.ts',
'**/build/',
'**/compiled/',
'**/dist/',
'data/',
'deployment_tools_config.json',
'devenv',
'e2e/test-plugins',
'e2e/tmp',
'packages/grafana-ui/src/components/Icon/iconBundle.ts',
'pkg',
'playwright-report',
'public/lib/monaco/',
'public/locales/_build',
'public/locales/**/*.js',
'public/vendor/',
'scripts/grafana-server/tmp',
'!.betterer.eslint.config.js',
],
},
{
name: 'react/jsx-runtime',
// @ts-ignore - not sure why but flat config is typed as a maybe?
...reactPlugin.configs.flat['jsx-runtime'],
},
{
files: ['**/*.{ts,tsx,js}'],
...baseConfig,
plugins: {
...baseConfig.plugins,
'@emotion': emotionPlugin,
lodash: lodashPlugin,
jest: jestPlugin,
import: importPlugin,
'jsx-a11y': jsxA11yPlugin,
'no-barrel-files': barrelPlugin,
'@grafana': grafanaPlugin,
'testing-library': testingLibraryPlugin,
},
linterOptions: {
// This reports unused disable directives that we can clean up but
// it also conflicts with the betterer eslint rules so disabled
reportUnusedDisableDirectives: false,
},
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@grafana/no-aria-label-selectors': 'error',
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@grafana/ui*', '*/Layout/*'],
importNames: ['Layout', 'HorizontalGroup', 'VerticalGroup'],
message: 'Use Stack component instead.',
},
{
group: ['@grafana/ui/src/*', '@grafana/runtime/src/*', '@grafana/data/src/*'],
message: 'Import from the public export instead.',
},
],
},
],
},
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
ignores: [
'**/*.{test,spec}.{ts,tsx}',
'**/__mocks__/**',
'**/public/test/**',
'**/mocks.{ts,tsx}',
'**/spec/**/*.{ts,tsx}',
],
rules: {
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
},
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
ignores: [
'**/*.{test,spec}.{ts,tsx}',
'**/__mocks__/**',
'**/public/test/**',
'**/mocks.{ts,tsx}',
'**/spec/**/*.{ts,tsx}',
],
rules: {
'no-restricted-syntax': [
'error',
{
selector: 'Identifier[name=localStorage]',
message: 'Direct usage of localStorage is not allowed. Use `Store` from @grafana/data instead.',
},
{
selector: 'MemberExpression[object.name=localStorage]',
message: 'Direct usage of localStorage is not allowed. Use `Store` from @grafana/data instead.',
},
],
},
},
{
files: ['public/app/**/*.{ts,tsx}'],
rules: {
'no-barrel-files/no-barrel-files': 'error',
},
},
];