@dartess/eslint-plugin 0.0.9 → 0.2.0
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 +11 -1
- package/README.md +5 -3
- package/dist/configs/recommended.js +4 -0
- package/dist/configs/vendor-rules/imports.js +4 -9
- package/dist/index.js +2 -0
- package/dist/rules/jsx-text-as-child.d.ts +1 -1
- package/dist/rules/prevent-mixing-external-and-internal-classes.d.ts +1 -1
- package/dist/rules/strict-observable-components-declaration.d.ts +1 -1
- package/dist/rules/ts-named-tuple-elements.d.ts +13 -0
- package/dist/rules/ts-named-tuple-elements.js +47 -0
- package/docs/rules/ts-named-tuple-elements.md +36 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
[//]: # (https://keepachangelog.com/en/1.1.0/)
|
|
4
4
|
|
|
5
|
+
## [0.2.0] - 2026-01-05
|
|
6
|
+
|
|
7
|
+
- improve `import-x/no-extraneous-dependencies` options
|
|
8
|
+
- add rule `@dartess/ts-named-tuple-elements`
|
|
9
|
+
- add `@dartess/ts-named-tuple-elements` to `recommended` config
|
|
10
|
+
|
|
11
|
+
## [0.1.0] - 2026-01-02
|
|
12
|
+
|
|
13
|
+
- add `eslint-plugin-de-morgan` to `recommended` config
|
|
14
|
+
|
|
5
15
|
## [0.0.9] - 2026-01-02
|
|
6
16
|
|
|
7
17
|
- remove overriding `@typescript-eslint/return-await` rule
|
|
8
18
|
- cleanup disabled rules
|
|
9
|
-
- add `prefer-object-has-own` to `
|
|
19
|
+
- add `prefer-object-has-own` to `recommended`: previously was disabled because of old browsers support
|
|
10
20
|
- apply `no-throw-literal` only for `js`-files (for `ts` files already enabled `@typescript-eslint/only-throw-error`)
|
|
11
21
|
|
|
12
22
|
## [0.0.8] - 2025-12-28
|
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ Also extends
|
|
|
7
7
|
* `typescript-eslint` — `strictTypeChecked` & `stylisticTypeChecked`
|
|
8
8
|
* `eslint-plugin-import-x` — `recommended` & `typescript`
|
|
9
9
|
* `@eslint-community/eslint-plugin-eslint-comments` — `recommended`
|
|
10
|
+
* `eslint-plugin-de-morgan` — `recommended`
|
|
10
11
|
|
|
11
12
|
Also can extends (if it is applicable)
|
|
12
13
|
* `eslint-plugin-react` — `recommended` & `jsx-runtime`
|
|
@@ -32,7 +33,7 @@ All of it pinched with extra configs, setups and extra rules. Just take it and u
|
|
|
32
33
|
You'll first need to install [ESLint](https://eslint.org/) and peer deps:
|
|
33
34
|
|
|
34
35
|
```sh
|
|
35
|
-
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
|
|
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
37
|
```
|
|
37
38
|
|
|
38
39
|
Next, also install the packages that suit your needs.
|
|
@@ -127,8 +128,8 @@ Use `eslint-plugin-oxlint` for disabling unnecessary rules.
|
|
|
127
128
|
#### Prettier (Old School)
|
|
128
129
|
|
|
129
130
|
* Use `eslint-config-prettier` for disabling unnecessary rules.
|
|
130
|
-
*
|
|
131
|
-
*
|
|
131
|
+
* Or use `eslint-plugin-prettier` for running `prettier` as eslint rule.
|
|
132
|
+
* 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).
|
|
132
133
|
|
|
133
134
|
## Supported Rules
|
|
134
135
|
|
|
@@ -147,6 +148,7 @@ Each rule has emojis denoting:
|
|
|
147
148
|
| [stories-export-meta](docs/rules/stories-export-meta.md) | Storybook's Meta should be typed | ✅ | | |
|
|
148
149
|
| [stories-export-typed](docs/rules/stories-export-typed.md) | Storybook's Stories should be typed | ✅ | | |
|
|
149
150
|
| [max-parent-import-depth](docs/rules/max-parent-import-depth.md) | Limit relative imports to a maximum parent depth. | ✅ | | |
|
|
151
|
+
| [ts-named-tuple-elements](docs/rules/ts-named-tuple-elements.md) | Enforce (or forbid) named tuple elements | ✅ | | |
|
|
150
152
|
|
|
151
153
|
## Code Reuse Policy
|
|
152
154
|
|
|
@@ -9,6 +9,7 @@ import pluginJs from '@eslint/js';
|
|
|
9
9
|
import eslintCommentsPlugin from '@eslint-community/eslint-plugin-eslint-comments/configs';
|
|
10
10
|
// @ts-ignore: https://github.com/NullVoxPopuli/eslint-plugin-decorator-position/issues/778
|
|
11
11
|
import eslintPluginDecoratorPosition from 'eslint-plugin-decorator-position';
|
|
12
|
+
import eslintPluginDeMorgan from 'eslint-plugin-de-morgan';
|
|
12
13
|
import dartessPlugin from "../index.js";
|
|
13
14
|
import vendorRulesBestPractices from "./vendor-rules/best-practices.js";
|
|
14
15
|
import vendorRulesErrors from "./vendor-rules/errors.js";
|
|
@@ -44,6 +45,7 @@ const config = [
|
|
|
44
45
|
eslintPluginImportX.flatConfigs.recommended,
|
|
45
46
|
eslintPluginImportX.flatConfigs.typescript,
|
|
46
47
|
eslintCommentsPlugin.recommended,
|
|
48
|
+
eslintPluginDeMorgan.configs.recommended,
|
|
47
49
|
{
|
|
48
50
|
name: '@dartess/recommended',
|
|
49
51
|
plugins: {
|
|
@@ -220,6 +222,8 @@ const config = [
|
|
|
220
222
|
disallowTypeAnnotations: false,
|
|
221
223
|
},
|
|
222
224
|
],
|
|
225
|
+
// require names for tuple elements
|
|
226
|
+
'@dartess/ts-named-tuple-elements': 'error',
|
|
223
227
|
},
|
|
224
228
|
},
|
|
225
229
|
{
|
|
@@ -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;
|
|
@@ -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.0
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"description": "A set of rules and configs for various TypeScript projects",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"eslint",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@next/eslint-plugin-next": "^16.0.0",
|
|
51
51
|
"eslint": "^9.0.0",
|
|
52
52
|
"eslint-import-resolver-typescript": "^4.0.0",
|
|
53
|
+
"eslint-plugin-de-morgan": "^2.0.0",
|
|
53
54
|
"eslint-plugin-decorator-position": "^6.0.0",
|
|
54
55
|
"eslint-plugin-import-x": "^4.1.0",
|
|
55
56
|
"eslint-plugin-jsx-a11y": "^6.10.0",
|