@dartess/eslint-plugin 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +134 -0
- package/dist/configs/mobx.d.ts +3 -0
- package/dist/configs/mobx.js +13 -0
- package/dist/configs/next.d.ts +3 -0
- package/dist/configs/next.js +17 -0
- package/dist/configs/react.d.ts +3 -0
- package/dist/configs/react.js +78 -0
- package/dist/configs/recommended.d.ts +3 -0
- package/dist/configs/recommended.js +211 -0
- package/dist/configs/storybook.d.ts +3 -0
- package/dist/configs/storybook.js +20 -0
- package/dist/configs/vendor-rules/best-practices.d.ts +120 -0
- package/dist/configs/vendor-rules/best-practices.js +248 -0
- package/dist/configs/vendor-rules/errors.d.ts +40 -0
- package/dist/configs/vendor-rules/errors.js +92 -0
- package/dist/configs/vendor-rules/es6.d.ts +47 -0
- package/dist/configs/vendor-rules/es6.js +108 -0
- package/dist/configs/vendor-rules/imports.d.ts +41 -0
- package/dist/configs/vendor-rules/imports.js +119 -0
- package/dist/configs/vendor-rules/next-config.d.ts +16 -0
- package/dist/configs/vendor-rules/next-config.js +22 -0
- package/dist/configs/vendor-rules/react-hooks.d.ts +10 -0
- package/dist/configs/vendor-rules/react-hooks.js +17 -0
- package/dist/configs/vendor-rules/react.d.ts +228 -0
- package/dist/configs/vendor-rules/react.js +513 -0
- package/dist/configs/vendor-rules/strict.d.ts +4 -0
- package/dist/configs/vendor-rules/strict.js +9 -0
- package/dist/configs/vendor-rules/style.d.ts +34 -0
- package/dist/configs/vendor-rules/style.js +78 -0
- package/dist/configs/vendor-rules/typescript-disablings.d.ts +5 -0
- package/dist/configs/vendor-rules/typescript-disablings.js +13 -0
- package/dist/configs/vendor-rules/typescript.d.ts +40 -0
- package/dist/configs/vendor-rules/typescript.js +69 -0
- package/dist/configs/vendor-rules/variables.d.ts +28 -0
- package/dist/configs/vendor-rules/variables.js +39 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +25 -0
- package/dist/rules/jsx-text-as-child.d.ts +13 -0
- package/dist/rules/jsx-text-as-child.js +90 -0
- package/dist/rules/max-parent-import-depth.d.ts +3 -0
- package/dist/rules/max-parent-import-depth.js +50 -0
- package/dist/rules/prevent-mixing-external-and-internal-classes.d.ts +13 -0
- package/dist/rules/prevent-mixing-external-and-internal-classes.js +72 -0
- package/dist/rules/require-observer.d.ts +3 -0
- package/dist/rules/require-observer.js +138 -0
- package/dist/rules/stories-export-meta.d.ts +3 -0
- package/dist/rules/stories-export-meta.js +37 -0
- package/dist/rules/stories-export-typed.d.ts +3 -0
- package/dist/rules/stories-export-typed.js +51 -0
- package/dist/rules/strict-observable-components-declaration.d.ts +14 -0
- package/dist/rules/strict-observable-components-declaration.js +118 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/parse-git-ignore.d.ts +2 -0
- package/dist/utils/parse-git-ignore.js +7 -0
- package/docs/rules/jsx-text-as-child.md +101 -0
- package/docs/rules/max-parent-import-depth.md +31 -0
- package/docs/rules/prevent-mixing-external-and-internal-classes.md +42 -0
- package/docs/rules/require-observer.md +43 -0
- package/docs/rules/stories-export-meta.md +37 -0
- package/docs/rules/stories-export-typed.md +42 -0
- package/docs/rules/strict-observable-components-declaration.md +57 -0
- package/package.json +91 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# @dartess/eslint-plugin
|
|
2
|
+
|
|
3
|
+
A set of rules for various react projects
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
You'll first need to install [ESLint](https://eslint.org/) and common peer deps:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i -D eslint eslint-plugin-import-x eslint-import-resolver-typescript @eslint-community/eslint-plugin-eslint-comments typescript-eslint eslint-plugin-unicorn
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Next, also install the packages that suit your needs.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm i -D eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
|
|
17
|
+
```
|
|
18
|
+
```sh
|
|
19
|
+
npm i -D @next/eslint-plugin-next
|
|
20
|
+
```
|
|
21
|
+
```sh
|
|
22
|
+
npm i -D eslint-plugin-mobx
|
|
23
|
+
```
|
|
24
|
+
```sh
|
|
25
|
+
npm i -D eslint-plugin-storybook
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Next, install `@dartess/eslint-plugin`
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm i -D @dartess/eslint-plugin
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage configs
|
|
35
|
+
|
|
36
|
+
Shared config based on `eslint-config-airbnb`, `eslint-config-airbnb-typescript`, `eslint-plugin-react/recommended`, `eslint-plugin-react/jsx-runtime`.
|
|
37
|
+
|
|
38
|
+
Edit or create `eslint.config.ts` (or `eslint.config.mts`). You probably have to install `jiti` for it.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import dartessEslintPluginRecommended from '@dartess/eslint-plugin/recommended';
|
|
42
|
+
|
|
43
|
+
// if `react` is used
|
|
44
|
+
import dartessEslintPluginReact from '@dartess/eslint-plugin/react';
|
|
45
|
+
// if `next.js` is used
|
|
46
|
+
import dartessEslintPluginNext from '@dartess/eslint-plugin/next';
|
|
47
|
+
// if `mobx` is used
|
|
48
|
+
import dartessEslintPluginMobx from '@dartess/eslint-plugin/mobx';
|
|
49
|
+
// if `storybook` is used
|
|
50
|
+
import dartessEslintPluginStorybook from '@dartess/eslint-plugin/storybook';
|
|
51
|
+
|
|
52
|
+
import { parseGitIgnore } from '@dartess/eslint-plugin/utils';
|
|
53
|
+
|
|
54
|
+
export default [
|
|
55
|
+
parseGitIgnore(), // the easiest way to ignore all `.gitignore` files
|
|
56
|
+
|
|
57
|
+
{
|
|
58
|
+
languageOptions: {
|
|
59
|
+
parserOptions: {
|
|
60
|
+
projectService: true,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
...dartessEslintPluginRecommended,
|
|
66
|
+
// if `react` is used
|
|
67
|
+
...dartessEslintPluginReact,
|
|
68
|
+
// if `next.js` is used
|
|
69
|
+
...dartessEslintPluginNext,
|
|
70
|
+
// if `mobx` is used
|
|
71
|
+
...dartessEslintPluginMobx,
|
|
72
|
+
// if `storybook` is used
|
|
73
|
+
...dartessEslintPluginStorybook,
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The package is intended for use with TypeScript.
|
|
79
|
+
|
|
80
|
+
The package is intended for use with [React New JSX Transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html).
|
|
81
|
+
|
|
82
|
+
The package is intended for use only with the `flat` eslint config.
|
|
83
|
+
|
|
84
|
+
## Next steps
|
|
85
|
+
|
|
86
|
+
If you'are using React, you also probably will want to add
|
|
87
|
+
[eslint-plugin-react-refresh](https://www.npmjs.com/package/eslint-plugin-react-refresh).
|
|
88
|
+
This plugin requires manual setup for you build tools.
|
|
89
|
+
|
|
90
|
+
## Usage rules
|
|
91
|
+
|
|
92
|
+
Copy example above into your `eslint.config.ts` and remove unnecesary parts.
|
|
93
|
+
|
|
94
|
+
Then configure the rules you want to use under the rules section.
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"rules": {
|
|
99
|
+
"@dartess/strict-observable-components-declaration": "error"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Supported Rules
|
|
105
|
+
|
|
106
|
+
Each rule has emojis denoting:
|
|
107
|
+
|
|
108
|
+
- ✅ if it belongs to the `recommended` configuration
|
|
109
|
+
- 🔧 if some problems reported by the rule are automatically fixable by the `--fix` [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) option
|
|
110
|
+
- 💡 if some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions)
|
|
111
|
+
|
|
112
|
+
| Name | Description | ✅ | 🔧 | 💡 |
|
|
113
|
+
|:-----------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------|:--|:---|:---|
|
|
114
|
+
| [strict-observable-components-declaration](docs/rules/strict-observable-components-declaration.md) | Wrapping components in `observer` must comply with the regulations. | | | |
|
|
115
|
+
| [require-observer](docs/rules/require-observer.md) | Components using the stores must be wrapped in an `observer` | ✅ | 🔧 | |
|
|
116
|
+
| [prevent-mixing-external-and-internal-classes](docs/rules/prevent-mixing-external-and-internal-classes.md) | Prevent mixing of outer and inner classes to avoid dependency on style order. | | | |
|
|
117
|
+
| [jsx-no-text-as-child](docs/rules/jsx-text-as-child.md) | JSX elements should not have text without translation | | | |
|
|
118
|
+
| [stories-export-meta](docs/rules/stories-export-meta.md) | Storybook's Meta should be typed | ✅ | | |
|
|
119
|
+
| [stories-export-typed](docs/rules/stories-export-typed.md) | Storybook's Stories should be typed | ✅ | | |
|
|
120
|
+
| [max-parent-import-depth](docs/rules/max-parent-import-depth.md) | Limit relative imports to a maximum parent depth. | ✅ | | |
|
|
121
|
+
|
|
122
|
+
## Code Reuse Policy
|
|
123
|
+
|
|
124
|
+
### `eslint-config-airbnb`
|
|
125
|
+
|
|
126
|
+
The package has a huge number of dependencies and will not be updated for a very long time; instead, all useful code has been copied. Configs are now considered "ours" (but remember the copyright) and can be edited.
|
|
127
|
+
|
|
128
|
+
### `eslint-config-airbnb-typescript`
|
|
129
|
+
|
|
130
|
+
Also as `eslint-config-airbnb` but also [deprecated](https://github.com/iamturns/eslint-config-airbnb-typescript?tab=readme-ov-file#this-repo-has-been-archived).
|
|
131
|
+
|
|
132
|
+
### `@next/eslint-plugin-next` and `eslint-config-next`
|
|
133
|
+
|
|
134
|
+
One of the packages does not support `flat config`. It may be removed from the repository if support appears (which is unlikely in the next many years, however).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import pluginMobx from 'eslint-plugin-mobx';
|
|
2
|
+
const config = [
|
|
3
|
+
pluginMobx.flatConfigs.recommended,
|
|
4
|
+
{
|
|
5
|
+
name: '@dartess/mobx',
|
|
6
|
+
rules: {
|
|
7
|
+
'mobx/missing-observer': 'off', // replaced by the neater "@dartess/require-observer"
|
|
8
|
+
'@dartess/strict-observable-components-declaration': 'error',
|
|
9
|
+
'@dartess/require-observer': 'error',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
];
|
|
13
|
+
export default config;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import nextPlugin from '@next/eslint-plugin-next';
|
|
2
|
+
import vendorRulesNextConfig from "./vendor-rules/next-config.js";
|
|
3
|
+
const config = [
|
|
4
|
+
{
|
|
5
|
+
name: '@dartess/nextjs',
|
|
6
|
+
files: ['**/*.{jsx,tsx}'],
|
|
7
|
+
plugins: {
|
|
8
|
+
'@next/next': nextPlugin,
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
...nextPlugin.configs.recommended.rules,
|
|
12
|
+
...nextPlugin.configs['core-web-vitals'].rules,
|
|
13
|
+
...vendorRulesNextConfig,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
export default config;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// This file contains code from the `eslint-config-airbnb` project
|
|
2
|
+
// Original author: Jake Teton-Landis (https://twitter.com/@jitl)
|
|
3
|
+
// License: MIT (see LICENSE-eslint-config-airbnb.md file)
|
|
4
|
+
import reactPlugin from 'eslint-plugin-react';
|
|
5
|
+
import reactHooksPlugin from 'eslint-plugin-react-hooks';
|
|
6
|
+
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
|
|
7
|
+
import vendorRulesReact from "./vendor-rules/react.js";
|
|
8
|
+
import vendorRulesReactHooks from "./vendor-rules/react-hooks.js";
|
|
9
|
+
const config = [
|
|
10
|
+
{
|
|
11
|
+
name: '@dartess/react-setup',
|
|
12
|
+
plugins: {
|
|
13
|
+
'react-hooks': reactHooksPlugin,
|
|
14
|
+
'jsx-a11y': jsxA11yPlugin,
|
|
15
|
+
},
|
|
16
|
+
settings: {
|
|
17
|
+
react: {
|
|
18
|
+
version: 'detect',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
reactPlugin.configs.flat.recommended,
|
|
23
|
+
{
|
|
24
|
+
name: '@dartess/eslint-plugin-react/jsx-runtime',
|
|
25
|
+
files: ['**/*.{jsx,tsx}'],
|
|
26
|
+
...reactPlugin.configs.flat['jsx-runtime'],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: '@dartess/react',
|
|
30
|
+
files: ['**/*.{jsx,tsx}'],
|
|
31
|
+
languageOptions: {
|
|
32
|
+
parserOptions: {
|
|
33
|
+
ecmaFeatures: {
|
|
34
|
+
jsx: true,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
settings: {
|
|
39
|
+
// Append 'ts' extensions to Airbnb 'import-x/resolver' setting
|
|
40
|
+
// Prepend 'mjs' to match shared config
|
|
41
|
+
// Original: ['.js', '.jsx', '.json']
|
|
42
|
+
'import-x/resolver': {
|
|
43
|
+
node: {
|
|
44
|
+
extensions: ['.mjs', '.js', '.jsx', '.json', '.ts', '.tsx', '.d.ts'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
rules: {
|
|
49
|
+
...vendorRulesReact,
|
|
50
|
+
// too hard for fixing, TODO maybe try later?
|
|
51
|
+
'react/jsx-props-no-spreading': 'off',
|
|
52
|
+
// TODO: try to enable this rules later (if needed)
|
|
53
|
+
'react/require-default-props': 'off',
|
|
54
|
+
'react/no-unstable-nested-components': 'off',
|
|
55
|
+
'jsx-a11y/click-events-have-key-events': 'off',
|
|
56
|
+
'jsx-a11y/anchor-is-valid': 'off',
|
|
57
|
+
'jsx-a11y/interactive-supports-focus': 'off',
|
|
58
|
+
// TODO END: try to enable this rules later (if needed)
|
|
59
|
+
'jsx-a11y/no-static-element-interactions': 'off', // TODO enable later
|
|
60
|
+
'jsx-a11y/no-noninteractive-tabindex': 'off', // TODO enable later
|
|
61
|
+
'jsx-a11y/no-noninteractive-element-interactions': 'off', // TODO enable later
|
|
62
|
+
'jsx-a11y/label-has-associated-control': 'off', // TODO enable later but with `assert`=`either`
|
|
63
|
+
// Append 'tsx' to Airbnb 'react/jsx-filename-extension' rule
|
|
64
|
+
// Original: ['.jsx']
|
|
65
|
+
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
|
|
66
|
+
// overrides
|
|
67
|
+
'react/jsx-no-duplicate-props': 'off', // checked by typescript
|
|
68
|
+
'react/jsx-no-undef': 'off', // checked by typescript
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: '@dartess/react-hooks',
|
|
73
|
+
rules: {
|
|
74
|
+
...vendorRulesReactHooks,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
export default config;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// This file contains code from the `eslint-config-airbnb` project
|
|
2
|
+
// Original author: Jake Teton-Landis (https://twitter.com/@jitl)
|
|
3
|
+
// License: MIT (see LICENSE-eslint-config-airbnb.md file)
|
|
4
|
+
import tsEslint from 'typescript-eslint';
|
|
5
|
+
import globals from 'globals';
|
|
6
|
+
import eslintPluginImportX from 'eslint-plugin-import-x';
|
|
7
|
+
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
|
8
|
+
import pluginJs from '@eslint/js';
|
|
9
|
+
import eslintCommentsPlugin from '@eslint-community/eslint-plugin-eslint-comments/configs';
|
|
10
|
+
import dartessPlugin from "../index.js";
|
|
11
|
+
import vendorRulesBestPractices from "./vendor-rules/best-practices.js";
|
|
12
|
+
import vendorRulesErrors from "./vendor-rules/errors.js";
|
|
13
|
+
import vendorRulesStyle from "./vendor-rules/style.js";
|
|
14
|
+
import vendorRulesVariables from "./vendor-rules/variables.js";
|
|
15
|
+
import vendorRulesEs6 from "./vendor-rules/es6.js";
|
|
16
|
+
import vendorRulesImports from "./vendor-rules/imports.js";
|
|
17
|
+
import vendorRulesStrict from "./vendor-rules/strict.js";
|
|
18
|
+
import vendorRulesTypescriptDisablings from "./vendor-rules/typescript-disablings.js";
|
|
19
|
+
import vendorRulesTypescript from "./vendor-rules/typescript.js";
|
|
20
|
+
const NO_MIDDLE_ABBRS = '(?!.*[A-Z]{3})';
|
|
21
|
+
const NO_END_ABBRS = '(?!.*[A-Z]{2}$)';
|
|
22
|
+
const NO_MIDDLE_UNDERSCORE = '(?!.*_{2})';
|
|
23
|
+
const EMPTY = `^$`;
|
|
24
|
+
const anyCamelCase = `^${NO_MIDDLE_ABBRS}${NO_END_ABBRS}[A-Za-z0-9]+$`;
|
|
25
|
+
const lowerCamelCase = `^${NO_MIDDLE_ABBRS}${NO_END_ABBRS}[a-z][A-Za-z0-9]+$`;
|
|
26
|
+
const UpperCamelCase = `^${NO_MIDDLE_ABBRS}${NO_END_ABBRS}[A-Z][A-Za-z0-9]+$`;
|
|
27
|
+
const snake_case = `^${NO_MIDDLE_UNDERSCORE}[a-z_]+$`;
|
|
28
|
+
const UPPER_CASE = `^${NO_MIDDLE_UNDERSCORE}[A-Z0-9_]+$`;
|
|
29
|
+
const config = [
|
|
30
|
+
{
|
|
31
|
+
name: '@dartess/recommended/enable-report-unused-disable-directives',
|
|
32
|
+
linterOptions: {
|
|
33
|
+
reportUnusedDisableDirectives: 'error',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: '@eslint/js/recommended',
|
|
38
|
+
...pluginJs.configs.recommended,
|
|
39
|
+
},
|
|
40
|
+
...tsEslint.configs.strictTypeChecked,
|
|
41
|
+
...tsEslint.configs.stylisticTypeChecked,
|
|
42
|
+
eslintPluginImportX.flatConfigs.recommended,
|
|
43
|
+
eslintPluginImportX.flatConfigs.typescript,
|
|
44
|
+
eslintCommentsPlugin.recommended,
|
|
45
|
+
{
|
|
46
|
+
name: '@dartess/recommended',
|
|
47
|
+
plugins: {
|
|
48
|
+
unicorn: eslintPluginUnicorn,
|
|
49
|
+
'@dartess': dartessPlugin,
|
|
50
|
+
},
|
|
51
|
+
languageOptions: {
|
|
52
|
+
parser: tsEslint.parser,
|
|
53
|
+
globals: {
|
|
54
|
+
...globals.browser,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
settings: {
|
|
58
|
+
'import-x/core-modules': [],
|
|
59
|
+
'import-x/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
|
|
60
|
+
},
|
|
61
|
+
rules: {
|
|
62
|
+
...vendorRulesBestPractices,
|
|
63
|
+
...vendorRulesErrors,
|
|
64
|
+
...vendorRulesStyle,
|
|
65
|
+
...vendorRulesVariables,
|
|
66
|
+
...vendorRulesEs6,
|
|
67
|
+
...vendorRulesImports,
|
|
68
|
+
...vendorRulesStrict,
|
|
69
|
+
/* restricts console outputs to essential log levels for cleaner logs */
|
|
70
|
+
'no-console': ['error', { allow: ['info', 'warn', 'error'] }],
|
|
71
|
+
/* permits file-wide rule control to streamline exceptional cases */
|
|
72
|
+
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
|
|
73
|
+
/* obliges to describe the reason for disconnection */
|
|
74
|
+
'@eslint-community/eslint-comments/require-description': [
|
|
75
|
+
'error',
|
|
76
|
+
{
|
|
77
|
+
ignore: [],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
'unicorn/no-useless-undefined': 'error',
|
|
81
|
+
'unicorn/prefer-node-protocol': 'error',
|
|
82
|
+
'@dartess/max-parent-import-depth': 'error',
|
|
83
|
+
curly: ['error', 'all'],
|
|
84
|
+
'import-x/order': [
|
|
85
|
+
'error',
|
|
86
|
+
{
|
|
87
|
+
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
|
|
88
|
+
'newlines-between': 'always',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
'prefer-arrow-callback': [
|
|
92
|
+
'error',
|
|
93
|
+
{
|
|
94
|
+
allowNamedFunctions: true,
|
|
95
|
+
allowUnboundThis: true,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: '@dartess/recommended-ts',
|
|
102
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
|
|
103
|
+
rules: {
|
|
104
|
+
...vendorRulesTypescriptDisablings,
|
|
105
|
+
...vendorRulesTypescript,
|
|
106
|
+
/* ensures ts-ignore is accompanied by a description for proper justification */
|
|
107
|
+
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }],
|
|
108
|
+
/* enforces consistent type alias declarations for improved clarity */
|
|
109
|
+
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
|
|
110
|
+
/* index signature can be more informative */
|
|
111
|
+
'@typescript-eslint/consistent-indexed-object-style': 'off',
|
|
112
|
+
/* can be false-positive */
|
|
113
|
+
'@typescript-eslint/no-unnecessary-type-parameters': 'off',
|
|
114
|
+
/* can be false-positive -- TODO can be enabled after `noUncheckedIndexedAccess` */
|
|
115
|
+
'@typescript-eslint/no-unnecessary-condition': 'off',
|
|
116
|
+
/* can be false-positive */
|
|
117
|
+
'@typescript-eslint/no-floating-promises': 'off',
|
|
118
|
+
/* can be false-positive */
|
|
119
|
+
'@typescript-eslint/no-misused-promises': 'off',
|
|
120
|
+
/* can be false-positive */
|
|
121
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
122
|
+
/* slow; not much use */
|
|
123
|
+
'@typescript-eslint/no-deprecated': 'off',
|
|
124
|
+
'@typescript-eslint/explicit-member-accessibility': [
|
|
125
|
+
'error',
|
|
126
|
+
{
|
|
127
|
+
overrides: {
|
|
128
|
+
constructors: 'off',
|
|
129
|
+
accessors: 'explicit',
|
|
130
|
+
methods: 'explicit',
|
|
131
|
+
properties: 'explicit',
|
|
132
|
+
parameterProperties: 'explicit',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
/* more strict rules then official options */
|
|
137
|
+
'@typescript-eslint/naming-convention': [
|
|
138
|
+
'error',
|
|
139
|
+
{
|
|
140
|
+
selector: 'variable',
|
|
141
|
+
format: null,
|
|
142
|
+
custom: {
|
|
143
|
+
regex: `${anyCamelCase}|${UPPER_CASE}`,
|
|
144
|
+
match: true,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
selector: 'function',
|
|
149
|
+
format: null,
|
|
150
|
+
custom: {
|
|
151
|
+
regex: anyCamelCase,
|
|
152
|
+
match: true,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
selector: 'parameter',
|
|
157
|
+
format: null,
|
|
158
|
+
custom: {
|
|
159
|
+
regex: `${anyCamelCase}|${snake_case}|${EMPTY}`,
|
|
160
|
+
match: true,
|
|
161
|
+
},
|
|
162
|
+
leadingUnderscore: 'allowSingleOrDouble',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
selector: 'method',
|
|
166
|
+
format: null,
|
|
167
|
+
custom: {
|
|
168
|
+
regex: lowerCamelCase,
|
|
169
|
+
match: true,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
selector: 'typeLike',
|
|
174
|
+
format: null,
|
|
175
|
+
custom: {
|
|
176
|
+
regex: UpperCamelCase,
|
|
177
|
+
match: true,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
selector: 'typeParameter',
|
|
182
|
+
format: null,
|
|
183
|
+
custom: {
|
|
184
|
+
regex: `${UpperCamelCase}|${EMPTY}`,
|
|
185
|
+
match: true,
|
|
186
|
+
},
|
|
187
|
+
prefix: ['T'],
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
'@typescript-eslint/restrict-template-expressions': [
|
|
191
|
+
'error',
|
|
192
|
+
{
|
|
193
|
+
allowNumber: true,
|
|
194
|
+
allowAny: false,
|
|
195
|
+
allowArray: false,
|
|
196
|
+
allowBoolean: false,
|
|
197
|
+
allowNullish: false,
|
|
198
|
+
allowRegExp: false,
|
|
199
|
+
allowNever: false,
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
'@typescript-eslint/no-import-type-side-effects': 'error', // TODO is enabled by default?
|
|
203
|
+
'@typescript-eslint/array-type': ['error', { default: 'generic' }],
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
files: ['**/*.js'],
|
|
208
|
+
...tsEslint.configs.disableTypeChecked,
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
export default config;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import pluginStorybook from 'eslint-plugin-storybook';
|
|
2
|
+
const config = [
|
|
3
|
+
{
|
|
4
|
+
ignores: ['!.storybook'],
|
|
5
|
+
},
|
|
6
|
+
...pluginStorybook.configs['flat/recommended'],
|
|
7
|
+
...pluginStorybook.configs['flat/csf-strict'],
|
|
8
|
+
{
|
|
9
|
+
name: '@dartess/storybook',
|
|
10
|
+
files: ['**/*.stories.tsx'],
|
|
11
|
+
rules: {
|
|
12
|
+
'storybook/no-title-property-in-meta': 'off', // generated names may be inappropriate
|
|
13
|
+
'@dartess/stories-export-meta': 'error', // TODO can be replaced with native storybook/meta-satisfies-type ?
|
|
14
|
+
'@dartess/stories-export-typed': 'error',
|
|
15
|
+
'@typescript-eslint/no-explicit-any': 'off', // can be hard for typing in stories
|
|
16
|
+
'@dartess/jsx-text-as-child': 'off', // not necessary in stories
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
export default config;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
declare const rules: {
|
|
2
|
+
'array-callback-return': ["error", {
|
|
3
|
+
allowImplicit: boolean;
|
|
4
|
+
}];
|
|
5
|
+
'block-scoped-var': "error";
|
|
6
|
+
'default-case': ["error", {
|
|
7
|
+
commentPattern: string;
|
|
8
|
+
}];
|
|
9
|
+
'default-case-last': "error";
|
|
10
|
+
'default-param-last': "error";
|
|
11
|
+
eqeqeq: ["error", string, {
|
|
12
|
+
null: string;
|
|
13
|
+
}];
|
|
14
|
+
'grouped-accessor-pairs': "error";
|
|
15
|
+
'guard-for-in': "error";
|
|
16
|
+
'max-classes-per-file': ["error", number];
|
|
17
|
+
'no-alert': "error";
|
|
18
|
+
'no-caller': "error";
|
|
19
|
+
'no-case-declarations': "error";
|
|
20
|
+
'no-constructor-return': "error";
|
|
21
|
+
'no-else-return': ["error", {
|
|
22
|
+
allowElseIf: boolean;
|
|
23
|
+
}];
|
|
24
|
+
'no-empty-function': ["error", {
|
|
25
|
+
allow: string[];
|
|
26
|
+
}];
|
|
27
|
+
'no-empty-pattern': "error";
|
|
28
|
+
'no-eval': "error";
|
|
29
|
+
'no-extend-native': "error";
|
|
30
|
+
'no-extra-bind': "error";
|
|
31
|
+
'no-extra-label': "error";
|
|
32
|
+
'no-fallthrough': "error";
|
|
33
|
+
'no-global-assign': ["error", {
|
|
34
|
+
exceptions: never[];
|
|
35
|
+
}];
|
|
36
|
+
'no-iterator': "error";
|
|
37
|
+
'no-labels': ["error", {
|
|
38
|
+
allowLoop: boolean;
|
|
39
|
+
allowSwitch: boolean;
|
|
40
|
+
}];
|
|
41
|
+
'no-lone-blocks': "error";
|
|
42
|
+
'no-loop-func': "error";
|
|
43
|
+
'no-multi-str': "error";
|
|
44
|
+
'no-new': "error";
|
|
45
|
+
'no-new-wrappers': "error";
|
|
46
|
+
'no-nonoctal-decimal-escape': "error";
|
|
47
|
+
'no-object-constructor': "error";
|
|
48
|
+
'no-octal': "error";
|
|
49
|
+
'no-octal-escape': "error";
|
|
50
|
+
'no-param-reassign': ["error", {
|
|
51
|
+
props: boolean;
|
|
52
|
+
ignorePropertyModificationsFor: string[];
|
|
53
|
+
}];
|
|
54
|
+
'no-proto': "error";
|
|
55
|
+
'no-restricted-properties': ["error", {
|
|
56
|
+
object: string;
|
|
57
|
+
property: string;
|
|
58
|
+
message: string;
|
|
59
|
+
}, {
|
|
60
|
+
object: string;
|
|
61
|
+
property: string;
|
|
62
|
+
message: string;
|
|
63
|
+
}, {
|
|
64
|
+
object: string;
|
|
65
|
+
property: string;
|
|
66
|
+
message: string;
|
|
67
|
+
}, {
|
|
68
|
+
object: string;
|
|
69
|
+
property: string;
|
|
70
|
+
message: string;
|
|
71
|
+
}, {
|
|
72
|
+
object: string;
|
|
73
|
+
property: string;
|
|
74
|
+
message: string;
|
|
75
|
+
}, {
|
|
76
|
+
object: string;
|
|
77
|
+
property: string;
|
|
78
|
+
message: string;
|
|
79
|
+
}, {
|
|
80
|
+
object: string;
|
|
81
|
+
property: string;
|
|
82
|
+
message: string;
|
|
83
|
+
}, {
|
|
84
|
+
property: string;
|
|
85
|
+
message: string;
|
|
86
|
+
}, {
|
|
87
|
+
property: string;
|
|
88
|
+
message: string;
|
|
89
|
+
}, {
|
|
90
|
+
object: string;
|
|
91
|
+
property: string;
|
|
92
|
+
message: string;
|
|
93
|
+
}];
|
|
94
|
+
'no-return-assign': ["error", string];
|
|
95
|
+
'no-script-url': "error";
|
|
96
|
+
'no-self-assign': ["error", {
|
|
97
|
+
props: boolean;
|
|
98
|
+
}];
|
|
99
|
+
'no-self-compare': "error";
|
|
100
|
+
'no-sequences': "error";
|
|
101
|
+
'no-throw-literal': "error";
|
|
102
|
+
'no-unused-labels': "error";
|
|
103
|
+
'no-useless-catch': "error";
|
|
104
|
+
'no-useless-concat': "error";
|
|
105
|
+
'no-useless-escape': "error";
|
|
106
|
+
'no-useless-return': "error";
|
|
107
|
+
'no-void': "error";
|
|
108
|
+
'prefer-promise-reject-errors': ["error", {
|
|
109
|
+
allowEmptyReject: boolean;
|
|
110
|
+
}];
|
|
111
|
+
'prefer-object-has-own': "off";
|
|
112
|
+
'prefer-regex-literals': ["error", {
|
|
113
|
+
disallowRedundantWrapping: boolean;
|
|
114
|
+
}];
|
|
115
|
+
radix: "error";
|
|
116
|
+
'require-await': "off";
|
|
117
|
+
'vars-on-top': "error";
|
|
118
|
+
yoda: "error";
|
|
119
|
+
};
|
|
120
|
+
export default rules;
|