@dartess/eslint-plugin 0.1.0 → 0.2.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 CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  [//]: # (https://keepachangelog.com/en/1.1.0/)
4
4
 
5
+ ## [0.2.1] - 2026-01-10
6
+
7
+ - add `recommended-post-format` config for using after formatting tools
8
+
9
+ ## [0.2.0] - 2026-01-05
10
+
11
+ - improve `import-x/no-extraneous-dependencies` options
12
+ - add rule `@dartess/ts-named-tuple-elements`
13
+ - add `@dartess/ts-named-tuple-elements` to `recommended` config
14
+
5
15
  ## [0.1.0] - 2026-01-02
6
16
 
7
17
  - add `eslint-plugin-de-morgan` to `recommended` config
package/README.md CHANGED
@@ -30,10 +30,18 @@ All of it pinched with extra configs, setups and extra rules. Just take it and u
30
30
 
31
31
  ## Installation
32
32
 
33
- You'll first need to install [ESLint](https://eslint.org/) and peer deps:
33
+ Install [ESLint](https://eslint.org/), required peer deps and the plugin itself:
34
34
 
35
35
  ```sh
36
- npm i -D eslint eslint-plugin-import-x eslint-import-resolver-typescript @eslint-community/eslint-plugin-eslint-comments typescript-eslint eslint-plugin-unicorn eslint-plugin-decorator-position eslint-plugin-de-morgan
36
+ npm i -D eslint \
37
+ eslint-plugin-import-x \
38
+ eslint-import-resolver-typescript \
39
+ eslint-plugin-unicorn \
40
+ eslint-plugin-decorator-position \
41
+ eslint-plugin-de-morgan \
42
+ typescript-eslint \
43
+ @eslint-community/eslint-plugin-eslint-comments \
44
+ @dartess/eslint-plugin
37
45
  ```
38
46
 
39
47
  Next, also install the packages that suit your needs.
@@ -51,12 +59,6 @@ npm i -D eslint-plugin-mobx
51
59
  npm i -D eslint-plugin-storybook
52
60
  ```
53
61
 
54
- Next, install `@dartess/eslint-plugin` itself.
55
-
56
- ```sh
57
- npm i -D @dartess/eslint-plugin
58
- ```
59
-
60
62
  ## Usage configs
61
63
 
62
64
  Shared config based on `eslint-config-airbnb`, `eslint-config-airbnb-typescript`, `eslint-plugin-react/recommended`, `eslint-plugin-react/jsx-runtime`.
@@ -65,6 +67,7 @@ Edit or create `eslint.config.ts` (or `eslint.config.mts`). You probably have to
65
67
 
66
68
  ```ts
67
69
  import dartessEslintPluginRecommended from '@dartess/eslint-plugin/recommended';
70
+ import dartessEslintPluginRecommendedPostFormat from '@dartess/eslint-plugin/recommended-post-format';
68
71
 
69
72
  // if `react` is used
70
73
  import dartessEslintPluginReact from '@dartess/eslint-plugin/react';
@@ -89,6 +92,7 @@ export default [
89
92
  },
90
93
 
91
94
  ...dartessEslintPluginRecommended,
95
+
92
96
  // if `react` is used
93
97
  ...dartessEslintPluginReact,
94
98
  // if `next.js` is used
@@ -97,21 +101,26 @@ export default [
97
101
  ...dartessEslintPluginMobx,
98
102
  // if `storybook` is used
99
103
  ...dartessEslintPluginStorybook,
104
+
105
+ // <-- Put here your formatters congifs -->
106
+ // @see `Fine Tuning` -> `Formatters` section below
107
+
108
+ ...dartessEslintPluginRecommendedPostFormat,
100
109
  ]
101
110
 
102
111
  ```
103
112
 
104
- ## Next steps
113
+ ## Fine Tuning
105
114
 
106
- If you're using React, you also probably will want to add
107
- [eslint-plugin-react-refresh](https://www.npmjs.com/package/eslint-plugin-react-refresh).
108
- This plugin requires manual setup for you build tools.
115
+ ### Formatting tools
109
116
 
110
- If you're using Mobx with legacy decorators, you have to enable rule `mobx/missing-make-observable` manually.
117
+ If you're want to (and you should to) use formatting tools, you need to additionally install and setup something else.
111
118
 
112
- ### Formatters
119
+ Replace the `<-- Put here your formatters congifs -->` comment with the required code, beacuse we have a special config
120
+ that fine-tunes formatter behavior and should be applied afterward.
113
121
 
114
- If you're want to (and you should to) use formatting tools, you need to additionally install and setup something else.
122
+ In case you for some reason don't want to use any formatting tools, you still have to put
123
+ `...dartessEslintPluginRecommendedPostFormat` in any place of your config.
115
124
 
116
125
  #### dprint
117
126
 
@@ -131,6 +140,16 @@ Use `eslint-plugin-oxlint` for disabling unnecessary rules.
131
140
  * Or use `eslint-plugin-prettier` for running `prettier` as eslint rule.
132
141
  * Or use `eslint-plugin-format` with rule `format/prettier` for running `prettier` as eslint rule (you probably will want to add `eslint-config-prettier` for disabling unnecessary rules).
133
142
 
143
+ ### (for React users)
144
+
145
+ If you're using React, you also probably will want to add
146
+ [eslint-plugin-react-refresh](https://www.npmjs.com/package/eslint-plugin-react-refresh).
147
+ This plugin requires manual setup for you build tools.
148
+
149
+ ### (for Mobx users)
150
+
151
+ If you're using Mobx with legacy decorators, you have to enable rule `mobx/missing-make-observable` manually.
152
+
134
153
  ## Supported Rules
135
154
 
136
155
  Each rule has emojis denoting:
@@ -148,6 +167,7 @@ Each rule has emojis denoting:
148
167
  | [stories-export-meta](docs/rules/stories-export-meta.md) | Storybook's Meta should be typed | ✅ | | |
149
168
  | [stories-export-typed](docs/rules/stories-export-typed.md) | Storybook's Stories should be typed | ✅ | | |
150
169
  | [max-parent-import-depth](docs/rules/max-parent-import-depth.md) | Limit relative imports to a maximum parent depth. | ✅ | | |
170
+ | [ts-named-tuple-elements](docs/rules/ts-named-tuple-elements.md) | Enforce (or forbid) named tuple elements | ✅ | | |
151
171
 
152
172
  ## Code Reuse Policy
153
173
 
@@ -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,9 @@
1
+ const config = [
2
+ {
3
+ name: '@dartess/recommended-post-format',
4
+ rules: {
5
+ curly: ['error', 'all'],
6
+ },
7
+ },
8
+ ];
9
+ export default config;
@@ -85,7 +85,6 @@ const config = [
85
85
  'unicorn/no-useless-undefined': 'error',
86
86
  'unicorn/prefer-node-protocol': 'error',
87
87
  '@dartess/max-parent-import-depth': 'error',
88
- curly: ['error', 'all'],
89
88
  'import-x/order': [
90
89
  'error',
91
90
  {
@@ -222,6 +221,8 @@ const config = [
222
221
  disallowTypeAnnotations: false,
223
222
  },
224
223
  ],
224
+ // require names for tuple elements
225
+ '@dartess/ts-named-tuple-elements': 'error',
225
226
  },
226
227
  },
227
228
  {
@@ -26,25 +26,20 @@ const rules = {
26
26
  'test/**', // tape, common npm pattern
27
27
  'tests/**', // also common npm pattern
28
28
  'spec/**', // mocha, rspec-like pattern
29
+ 'scripts/**', // custom infra scripts
29
30
  '**/__tests__/**', // jest pattern
30
31
  '**/__mocks__/**', // jest pattern
31
32
  'test.{js,jsx}', // repos with a single test file
32
33
  'test-*.{js,jsx}', // repos with multiple top-level test files
33
34
  '**/*{.,_}{test,spec}.{js,jsx}', // tests where the extension or filename suffix denotes that it is a test
34
- '**/jest.config.js', // jest config
35
35
  '**/jest.setup.js', // jest setup
36
- '**/vue.config.js', // vue-cli config
37
- '**/webpack.config.js', // webpack config
38
- '**/webpack.config.*.js', // webpack config
39
- '**/rollup.config.js', // rollup config
40
- '**/rollup.config.*.js', // rollup config
41
36
  '**/gulpfile.js', // gulp config
42
37
  '**/gulpfile.*.js', // gulp config
43
38
  '**/Gruntfile{,.js}', // grunt config
44
- '**/protractor.conf.js', // protractor config
45
- '**/protractor.conf.*.js', // protractor config
46
- '**/karma.conf.js', // karma config
47
39
  '**/.eslintrc.js', // eslint config
40
+ '**/*.conf{,ig}.js', // any configs
41
+ '**/*.conf{,ig}.*.js', // any configs
42
+ '**/*.stories.jsx', // storybook stories
48
43
  ],
49
44
  optionalDependencies: false,
50
45
  },
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import ruleStoriesExportTyped from "./rules/stories-export-typed.js";
6
6
  import ruleStrictObservableComponentsDeclaration from "./rules/strict-observable-components-declaration.js";
7
7
  import ruleRequireObserver from "./rules/require-observer.js";
8
8
  import ruleMaxParentImportDepth from "./rules/max-parent-import-depth.js";
9
+ import ruleTsNamedTupleElements from "./rules/ts-named-tuple-elements.js";
9
10
  const plugin = {
10
11
  meta: {
11
12
  name: packageJson.name,
@@ -20,6 +21,7 @@ const plugin = {
20
21
  'strict-observable-components-declaration': ruleStrictObservableComponentsDeclaration,
21
22
  'require-observer': ruleRequireObserver,
22
23
  'max-parent-import-depth': ruleMaxParentImportDepth,
24
+ 'ts-named-tuple-elements': ruleTsNamedTupleElements,
23
25
  },
24
26
  };
25
27
  export default plugin;
@@ -1,6 +1,6 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
2
  type Options = [
3
- {
3
+ mainOptions: {
4
4
  allowDigits?: boolean;
5
5
  allowEmoji?: boolean;
6
6
  allowSpecialSymbols?: boolean;
@@ -4,7 +4,7 @@ import { ESLintUtils } from '@typescript-eslint/utils';
4
4
  * @author Sergey Kozlov
5
5
  */
6
6
  type Options = [
7
- {
7
+ mainOptions: {
8
8
  libName?: string;
9
9
  }
10
10
  ];
@@ -4,7 +4,7 @@ import { ESLintUtils } from '@typescript-eslint/utils';
4
4
  * @author Sergey Kozlov
5
5
  */
6
6
  type Options = [
7
- {
7
+ mainOptions: {
8
8
  ignoreObserverArg?: Array<string>;
9
9
  allowedHocs?: Array<string>;
10
10
  }
@@ -0,0 +1,13 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ /**
3
+ * @fileoverview Enforce (or forbid) named tuple elements
4
+ * @author Sergey Kozlov
5
+ */
6
+ type Options = [
7
+ mainOptions: {
8
+ mode?: 'always' | 'never';
9
+ }
10
+ ];
11
+ type MessageIds = 'requireNames' | 'forbidNames';
12
+ declare const _default: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
13
+ export default _default;
@@ -0,0 +1,47 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export default ESLintUtils.RuleCreator(() => '')({
3
+ name: 'ts-named-tuple-elements',
4
+ defaultOptions: [{ mode: 'always' }],
5
+ meta: {
6
+ type: 'suggestion',
7
+ docs: {
8
+ description: 'Enforces consistent usage of named elements in TypeScript tuple types.',
9
+ },
10
+ messages: {
11
+ requireNames: 'Tuple elements must have names.',
12
+ forbidNames: 'Tuple elements must not have names.',
13
+ },
14
+ schema: [
15
+ {
16
+ type: 'object',
17
+ properties: {
18
+ mode: {
19
+ type: 'string',
20
+ enum: ['always', 'never'],
21
+ default: 'always',
22
+ },
23
+ },
24
+ },
25
+ ],
26
+ },
27
+ create(context) {
28
+ const [options] = context.options;
29
+ const { mode = 'always' } = options ?? {};
30
+ switch (mode) {
31
+ case 'always':
32
+ return {
33
+ 'TSTupleType > :not(TSNamedTupleMember)': node => {
34
+ context.report({ node, messageId: 'requireNames' });
35
+ },
36
+ };
37
+ case 'never':
38
+ return {
39
+ 'TSTupleType > TSNamedTupleMember': node => {
40
+ context.report({ node, messageId: 'forbidNames' });
41
+ },
42
+ };
43
+ default:
44
+ throw new Error(`Invalig mode value: ${String(mode)}`);
45
+ }
46
+ },
47
+ });
@@ -0,0 +1,36 @@
1
+ # Enforce (or forbid) named tuple elements (ts-named-tuple-elements)
2
+
3
+ Enforces consistent usage of named elements in TypeScript tuple types.
4
+ This rule helps improve readability, self-documentation, and maintainability of tuple types
5
+ by explicitly naming their elements instead of relying on positional meaning.
6
+
7
+ ## Rule Details
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```ts
12
+ type Location = [number, number]
13
+ ```
14
+
15
+ Examples of **correct** code for this rule:
16
+
17
+ ```ts
18
+ type Location = [lat: number, long: number]
19
+ ```
20
+
21
+ ## Options
22
+
23
+ `mode`: `always` (by default) or `never`
24
+
25
+ ```json
26
+ {
27
+ "@dartess/ts-named-tuple-elements": [
28
+ "error",
29
+ {
30
+ "mode": "never"
31
+ }
32
+ ]
33
+ }
34
+ ```
35
+
36
+ When mode is "never", tuple elements should not have names.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dartess/eslint-plugin",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "A set of rules and configs for various TypeScript projects",
6
6
  "keywords": [
7
7
  "eslint",
@@ -16,6 +16,7 @@
16
16
  "exports": {
17
17
  ".": "./dist/index.js",
18
18
  "./recommended": "./dist/configs/recommended.js",
19
+ "./recommended-post-format": "./dist/configs/post-format.js",
19
20
  "./react": "./dist/configs/react.js",
20
21
  "./next": "./dist/configs/next.js",
21
22
  "./mobx": "./dist/configs/mobx.js",