@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +134 -0
  3. package/dist/configs/mobx.d.ts +3 -0
  4. package/dist/configs/mobx.js +13 -0
  5. package/dist/configs/next.d.ts +3 -0
  6. package/dist/configs/next.js +17 -0
  7. package/dist/configs/react.d.ts +3 -0
  8. package/dist/configs/react.js +78 -0
  9. package/dist/configs/recommended.d.ts +3 -0
  10. package/dist/configs/recommended.js +211 -0
  11. package/dist/configs/storybook.d.ts +3 -0
  12. package/dist/configs/storybook.js +20 -0
  13. package/dist/configs/vendor-rules/best-practices.d.ts +120 -0
  14. package/dist/configs/vendor-rules/best-practices.js +248 -0
  15. package/dist/configs/vendor-rules/errors.d.ts +40 -0
  16. package/dist/configs/vendor-rules/errors.js +92 -0
  17. package/dist/configs/vendor-rules/es6.d.ts +47 -0
  18. package/dist/configs/vendor-rules/es6.js +108 -0
  19. package/dist/configs/vendor-rules/imports.d.ts +41 -0
  20. package/dist/configs/vendor-rules/imports.js +119 -0
  21. package/dist/configs/vendor-rules/next-config.d.ts +16 -0
  22. package/dist/configs/vendor-rules/next-config.js +22 -0
  23. package/dist/configs/vendor-rules/react-hooks.d.ts +10 -0
  24. package/dist/configs/vendor-rules/react-hooks.js +17 -0
  25. package/dist/configs/vendor-rules/react.d.ts +228 -0
  26. package/dist/configs/vendor-rules/react.js +513 -0
  27. package/dist/configs/vendor-rules/strict.d.ts +4 -0
  28. package/dist/configs/vendor-rules/strict.js +9 -0
  29. package/dist/configs/vendor-rules/style.d.ts +34 -0
  30. package/dist/configs/vendor-rules/style.js +78 -0
  31. package/dist/configs/vendor-rules/typescript-disablings.d.ts +5 -0
  32. package/dist/configs/vendor-rules/typescript-disablings.js +13 -0
  33. package/dist/configs/vendor-rules/typescript.d.ts +40 -0
  34. package/dist/configs/vendor-rules/typescript.js +69 -0
  35. package/dist/configs/vendor-rules/variables.d.ts +28 -0
  36. package/dist/configs/vendor-rules/variables.js +39 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.js +25 -0
  39. package/dist/rules/jsx-text-as-child.d.ts +13 -0
  40. package/dist/rules/jsx-text-as-child.js +90 -0
  41. package/dist/rules/max-parent-import-depth.d.ts +3 -0
  42. package/dist/rules/max-parent-import-depth.js +50 -0
  43. package/dist/rules/prevent-mixing-external-and-internal-classes.d.ts +13 -0
  44. package/dist/rules/prevent-mixing-external-and-internal-classes.js +72 -0
  45. package/dist/rules/require-observer.d.ts +3 -0
  46. package/dist/rules/require-observer.js +138 -0
  47. package/dist/rules/stories-export-meta.d.ts +3 -0
  48. package/dist/rules/stories-export-meta.js +37 -0
  49. package/dist/rules/stories-export-typed.d.ts +3 -0
  50. package/dist/rules/stories-export-typed.js +51 -0
  51. package/dist/rules/strict-observable-components-declaration.d.ts +14 -0
  52. package/dist/rules/strict-observable-components-declaration.js +118 -0
  53. package/dist/utils/index.d.ts +1 -0
  54. package/dist/utils/index.js +1 -0
  55. package/dist/utils/parse-git-ignore.d.ts +2 -0
  56. package/dist/utils/parse-git-ignore.js +7 -0
  57. package/docs/rules/jsx-text-as-child.md +101 -0
  58. package/docs/rules/max-parent-import-depth.md +31 -0
  59. package/docs/rules/prevent-mixing-external-and-internal-classes.md +42 -0
  60. package/docs/rules/require-observer.md +43 -0
  61. package/docs/rules/stories-export-meta.md +37 -0
  62. package/docs/rules/stories-export-typed.md +42 -0
  63. package/docs/rules/strict-observable-components-declaration.md +57 -0
  64. package/package.json +91 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ [//]: # (https://keepachangelog.com/en/1.1.0/)
4
+
5
+ ## [0.0.1] - 2025-12-16
6
+
7
+ - initial version
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,3 @@
1
+ import type { Linter } from 'eslint';
2
+ declare const config: Array<Linter.Config>;
3
+ export default config;
@@ -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,3 @@
1
+ import type { Linter } from 'eslint';
2
+ declare const config: Array<Linter.Config>;
3
+ 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,3 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const config: TSESLint.FlatConfig.ConfigArray;
3
+ 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,3 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const config: TSESLint.FlatConfig.ConfigArray;
3
+ 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,3 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const config: Array<TSESLint.FlatConfig.Config>;
3
+ 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;