@dartess/eslint-plugin 0.8.0 → 0.9.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 +9 -0
- package/README.md +3 -1
- package/dist/configs/recommended.js +8 -0
- package/dist/configs/vendor-rules/best-practices.d.ts +0 -4
- package/dist/configs/vendor-rules/best-practices.js +0 -6
- package/dist/configs/vendor-rules/errors.d.ts +0 -1
- package/dist/configs/vendor-rules/errors.js +0 -3
- package/dist/configs/vendor-rules/es6.d.ts +0 -4
- package/dist/configs/vendor-rules/es6.js +0 -8
- package/dist/configs/vendor-rules/style.d.ts +0 -1
- package/dist/configs/vendor-rules/style.js +0 -3
- package/dist/rules/mobx-require-observer.js +31 -4
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
[//]: # (https://keepachangelog.com/en/1.1.0/)
|
|
4
4
|
|
|
5
|
+
## [0.9.0] - 2026-02-03
|
|
6
|
+
|
|
7
|
+
- add `eslint-plugin-complete` to `recommended` config
|
|
8
|
+
|
|
9
|
+
## [0.8.1] - 2026-01-24
|
|
10
|
+
|
|
11
|
+
- fix `mobx-require-observer`: now it doesn't lose generics
|
|
12
|
+
- fix `mobx-require-observer`: now it respects directives like `'use client'`
|
|
13
|
+
|
|
5
14
|
## [0.8.0] - 2026-01-22
|
|
6
15
|
|
|
7
16
|
- All recommended warnings are converted to errors because warnings are useless.
|
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ Also extends
|
|
|
8
8
|
* `eslint-plugin-import-x` — `recommended` & `typescript`
|
|
9
9
|
* `@eslint-community/eslint-plugin-eslint-comments` — `recommended`
|
|
10
10
|
* `eslint-plugin-de-morgan` — `recommended`
|
|
11
|
+
* `eslint-plugin-complete` — `recommended`
|
|
11
12
|
|
|
12
13
|
Also can extends (if it is applicable)
|
|
13
14
|
* `@eslint-react/eslint-plugin` — `strict-type-checked`
|
|
@@ -23,7 +24,7 @@ All of it pinched with extra configs, setups and extra rules. Just take it and u
|
|
|
23
24
|
|
|
24
25
|
### Notes
|
|
25
26
|
|
|
26
|
-
1. The package is intended for use with TypeScript (it'll be useful for plain JS, but it hasn't been
|
|
27
|
+
1. The package is intended for use with TypeScript (it'll be useful for plain JS, but it hasn't been well-tested).
|
|
27
28
|
|
|
28
29
|
2. The package is intended for use only with the `flat` eslint config.
|
|
29
30
|
|
|
@@ -38,6 +39,7 @@ npm i -D eslint \
|
|
|
38
39
|
eslint-plugin-import-x \
|
|
39
40
|
eslint-import-resolver-typescript \
|
|
40
41
|
eslint-plugin-unicorn \
|
|
42
|
+
eslint-plugin-complete \
|
|
41
43
|
eslint-plugin-decorator-position \
|
|
42
44
|
eslint-plugin-de-morgan \
|
|
43
45
|
typescript-eslint \
|
|
@@ -10,6 +10,7 @@ import eslintCommentsPlugin from '@eslint-community/eslint-plugin-eslint-comment
|
|
|
10
10
|
// @ts-ignore: https://github.com/NullVoxPopuli/eslint-plugin-decorator-position/issues/778
|
|
11
11
|
import eslintPluginDecoratorPosition from 'eslint-plugin-decorator-position';
|
|
12
12
|
import eslintPluginDeMorgan from 'eslint-plugin-de-morgan';
|
|
13
|
+
import esLintPluginComplete from 'eslint-plugin-complete';
|
|
13
14
|
import dartessPlugin from "../index.js";
|
|
14
15
|
import vendorRulesBestPractices from "./vendor-rules/best-practices.js";
|
|
15
16
|
import vendorRulesErrors from "./vendor-rules/errors.js";
|
|
@@ -47,6 +48,7 @@ const config = [
|
|
|
47
48
|
convertWarnsToErrorsIfNeeded(eslintPluginImportX.flatConfigs.typescript),
|
|
48
49
|
convertWarnsToErrorsIfNeeded(eslintCommentsPlugin.recommended),
|
|
49
50
|
convertWarnsToErrorsIfNeeded(eslintPluginDeMorgan.configs.recommended),
|
|
51
|
+
...convertWarnsToErrorsIfNeeded(esLintPluginComplete.configs.recommended),
|
|
50
52
|
{
|
|
51
53
|
name: '@dartess/recommended',
|
|
52
54
|
plugins: {
|
|
@@ -224,6 +226,12 @@ const config = [
|
|
|
224
226
|
],
|
|
225
227
|
// require names for tuple elements
|
|
226
228
|
'@dartess/ts-named-tuple-elements': 'error',
|
|
229
|
+
// disable some recommended rules
|
|
230
|
+
'complete/prefer-readonly-parameter-types': 'off', // can be flase-positive for Built-in methods
|
|
231
|
+
'complete/no-mutable-return': 'off', // can be hamful
|
|
232
|
+
'complete/strict-undefined-functions': 'off', // prefer unicorn/no-useless-undefined
|
|
233
|
+
'complete/require-break': 'off', // can be false-positive with TS7027
|
|
234
|
+
'complete/no-void-return-type': 'off', // conflict with @typescript-eslint/explicit-module-boundary-types
|
|
227
235
|
},
|
|
228
236
|
},
|
|
229
237
|
{
|
|
@@ -8,9 +8,6 @@ declare const rules: {
|
|
|
8
8
|
}];
|
|
9
9
|
'default-case-last': "error";
|
|
10
10
|
'default-param-last': "error";
|
|
11
|
-
eqeqeq: ["error", string, {
|
|
12
|
-
null: string;
|
|
13
|
-
}];
|
|
14
11
|
'grouped-accessor-pairs': "error";
|
|
15
12
|
'guard-for-in': "error";
|
|
16
13
|
'max-classes-per-file': ["error", number];
|
|
@@ -88,7 +85,6 @@ declare const rules: {
|
|
|
88
85
|
'no-self-compare': "error";
|
|
89
86
|
'no-sequences': "error";
|
|
90
87
|
'no-useless-concat': "error";
|
|
91
|
-
'no-useless-return': "error";
|
|
92
88
|
'no-void': "error";
|
|
93
89
|
'prefer-promise-reject-errors': ["error", {
|
|
94
90
|
allowEmptyReject: boolean;
|
|
@@ -17,9 +17,6 @@ const rules = {
|
|
|
17
17
|
'default-case-last': 'error',
|
|
18
18
|
// https://eslint.org/docs/rules/default-param-last
|
|
19
19
|
'default-param-last': 'error',
|
|
20
|
-
// require the use of === and !==
|
|
21
|
-
// https://eslint.org/docs/rules/eqeqeq
|
|
22
|
-
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
|
23
20
|
// Require grouped accessor pairs in object literals and classes
|
|
24
21
|
// https://eslint.org/docs/rules/grouped-accessor-pairs
|
|
25
22
|
'grouped-accessor-pairs': 'error',
|
|
@@ -174,9 +171,6 @@ const rules = {
|
|
|
174
171
|
// disallow useless string concatenation
|
|
175
172
|
// https://eslint.org/docs/rules/no-useless-concat
|
|
176
173
|
'no-useless-concat': 'error',
|
|
177
|
-
// disallow redundant return; keywords
|
|
178
|
-
// https://eslint.org/docs/rules/no-useless-return
|
|
179
|
-
'no-useless-return': 'error',
|
|
180
174
|
// disallow use of void operator
|
|
181
175
|
// https://eslint.org/docs/rules/no-void
|
|
182
176
|
'no-void': 'error',
|
|
@@ -13,9 +13,6 @@ const rules = {
|
|
|
13
13
|
// Disallow returning values from Promise executor functions
|
|
14
14
|
// https://eslint.org/docs/rules/no-promise-executor-return
|
|
15
15
|
'no-promise-executor-return': 'error',
|
|
16
|
-
// Disallow template literal placeholder syntax in regular strings
|
|
17
|
-
// https://eslint.org/docs/rules/no-template-curly-in-string
|
|
18
|
-
'no-template-curly-in-string': 'error',
|
|
19
16
|
// Disallow loops with a body that allows only one iteration
|
|
20
17
|
// https://eslint.org/docs/rules/no-unreachable-loop
|
|
21
18
|
'no-unreachable-loop': [
|
|
@@ -12,10 +12,6 @@ declare const rules: {
|
|
|
12
12
|
ignoreConstructors: boolean;
|
|
13
13
|
avoidQuotes: boolean;
|
|
14
14
|
}];
|
|
15
|
-
'prefer-const': ["error", {
|
|
16
|
-
destructuring: string;
|
|
17
|
-
ignoreReadBeforeAssign: boolean;
|
|
18
|
-
}];
|
|
19
15
|
'prefer-destructuring': ["error", {
|
|
20
16
|
VariableDeclarator: {
|
|
21
17
|
array: boolean;
|
|
@@ -37,14 +37,6 @@ const rules = {
|
|
|
37
37
|
avoidQuotes: true,
|
|
38
38
|
},
|
|
39
39
|
],
|
|
40
|
-
// suggest using of const declaration for variables that are never modified after declared
|
|
41
|
-
'prefer-const': [
|
|
42
|
-
'error',
|
|
43
|
-
{
|
|
44
|
-
destructuring: 'any',
|
|
45
|
-
ignoreReadBeforeAssign: true,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
40
|
// Prefer destructuring from arrays and objects
|
|
49
41
|
// https://eslint.org/docs/rules/prefer-destructuring
|
|
50
42
|
'prefer-destructuring': [
|
|
@@ -39,9 +39,6 @@ const rules = {
|
|
|
39
39
|
'no-multi-assign': ['error'],
|
|
40
40
|
// disallow nested ternary expressions
|
|
41
41
|
'no-nested-ternary': 'error',
|
|
42
|
-
// disallow use of unary operators, ++ and --
|
|
43
|
-
// https://eslint.org/docs/rules/no-plusplus
|
|
44
|
-
'no-plusplus': 'error',
|
|
45
42
|
// disallow dangling underscores in identifiers
|
|
46
43
|
// https://eslint.org/docs/rules/no-underscore-dangle
|
|
47
44
|
'no-underscore-dangle': [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
1
|
+
import { ESLintUtils, AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
2
|
function isCustomHook(fn) {
|
|
3
3
|
if (fn.type === AST_NODE_TYPES.FunctionDeclaration && fn.id?.name.startsWith('use')) {
|
|
4
4
|
return true;
|
|
@@ -13,6 +13,29 @@ function isCustomHook(fn) {
|
|
|
13
13
|
}
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
|
+
function getTypeParamsText(fn, sourceCode) {
|
|
17
|
+
return fn.typeParameters ? sourceCode.getText(fn.typeParameters) : '';
|
|
18
|
+
}
|
|
19
|
+
function getObserverImportAnchor(program) {
|
|
20
|
+
const firstImport = program.body.find(n => n.type === AST_NODE_TYPES.ImportDeclaration);
|
|
21
|
+
if (firstImport) {
|
|
22
|
+
return { anchor: firstImport, method: 'insertTextBefore' };
|
|
23
|
+
}
|
|
24
|
+
let lastPrologue = null;
|
|
25
|
+
for (const node of program.body) {
|
|
26
|
+
if (node.type === AST_NODE_TYPES.ExpressionStatement &&
|
|
27
|
+
node.expression.type === AST_NODE_TYPES.Literal &&
|
|
28
|
+
typeof node.expression.value === 'string') {
|
|
29
|
+
lastPrologue = node;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
if (lastPrologue) {
|
|
35
|
+
return { anchor: lastPrologue, method: 'insertTextAfter' };
|
|
36
|
+
}
|
|
37
|
+
return { anchor: program.body[0], method: 'insertTextBefore' };
|
|
38
|
+
}
|
|
16
39
|
export default ESLintUtils.RuleCreator(() => '')({
|
|
17
40
|
name: 'mobx-require-observer',
|
|
18
41
|
meta: {
|
|
@@ -97,7 +120,10 @@ export default ESLintUtils.RuleCreator(() => '')({
|
|
|
97
120
|
fix(fixer) {
|
|
98
121
|
const fixes = [];
|
|
99
122
|
if (!hasObserverImport) {
|
|
100
|
-
|
|
123
|
+
const { anchor, method } = getObserverImportAnchor(program);
|
|
124
|
+
const nBefore = method === 'insertTextAfter' ? '\n' : '';
|
|
125
|
+
const nAfter = method === 'insertTextBefore' ? '\n' : '';
|
|
126
|
+
fixes.push(fixer[method](anchor, `${nBefore}import { observer } from 'mobx-react-lite';${nAfter}`));
|
|
101
127
|
}
|
|
102
128
|
const paramsText = fn.params.map(p => sourceCode.getText(p)).join(', ');
|
|
103
129
|
const bodyText = sourceCode.getText(fn.body);
|
|
@@ -112,12 +138,13 @@ export default ESLintUtils.RuleCreator(() => '')({
|
|
|
112
138
|
const replacement = `const ${name} = observer(${original});`;
|
|
113
139
|
fixes.push(fixer.replaceText(fn, replacement));
|
|
114
140
|
}
|
|
115
|
-
else if (varDecl
|
|
141
|
+
else if (varDecl?.type === AST_NODE_TYPES.VariableDeclaration) {
|
|
116
142
|
// const Name = () => {} or function expression
|
|
117
143
|
const id = fn.parent.id;
|
|
118
144
|
const { name } = id;
|
|
119
145
|
const isExport = exportDecl?.type === AST_NODE_TYPES.ExportNamedDeclaration;
|
|
120
|
-
const
|
|
146
|
+
const typeParamsText = getTypeParamsText(fn, sourceCode);
|
|
147
|
+
const funcExpression = `function ${name}${typeParamsText}(${paramsText}) ${bodyText}`;
|
|
121
148
|
const replacementNodeText = `${isExport ? 'export ' : ''}const ${name} = observer(${funcExpression});`;
|
|
122
149
|
fixes.push(fixer.replaceText(exportDecl || varDecl, replacementNodeText));
|
|
123
150
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dartess/eslint-plugin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"description": "A set of rules and configs for various TypeScript projects",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"eslint",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@stylistic/eslint-plugin": "^5.7.0",
|
|
54
54
|
"eslint": "^9.0.0",
|
|
55
55
|
"eslint-import-resolver-typescript": "^4.0.0",
|
|
56
|
+
"eslint-plugin-complete": "^1.2.0",
|
|
56
57
|
"eslint-plugin-de-morgan": "^2.0.0",
|
|
57
58
|
"eslint-plugin-decorator-position": "^6.0.0",
|
|
58
59
|
"eslint-plugin-import-x": "^4.1.0",
|