@rotki/eslint-plugin 0.7.0 → 1.0.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/README.md +35 -5
- package/dist/index.mjs +190 -190
- package/package.json +19 -20
- package/dist/index.cjs +0 -707
- package/dist/index.d.cts +0 -108
package/README.md
CHANGED
|
@@ -1,15 +1,45 @@
|
|
|
1
1
|
# @rotki/eslint-plugin
|
|
2
2
|
|
|
3
|
-
rotki
|
|
3
|
+
[](https://www.npmjs.com/package/@rotki/eslint-plugin)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
and [vuetifyjs/eslint-plugin-vuetify](https://github.com/vuetifyjs/eslint-plugin-vuetify).
|
|
5
|
+
An ESLint plugin for rotki projects that provides custom rules and configurations to maintain consistent code quality.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
This ESLint plugin is designed specifically for rotki projects, drawing inspiration from established plugins like:
|
|
10
|
+
|
|
11
|
+
- [intlify/eslint-plugin-vue-i18n](https://github.com/intlify/eslint-plugin-vue-i18n)
|
|
12
|
+
- [vuetifyjs/eslint-plugin-vuetify](https://github.com/vuetifyjs/eslint-plugin-vuetify)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Using pnpm (recommended)
|
|
18
|
+
pnpm add -D @rotki/eslint-plugin
|
|
19
|
+
|
|
20
|
+
# Using npm
|
|
21
|
+
npm install --save-dev @rotki/eslint-plugin
|
|
22
|
+
|
|
23
|
+
# Using yarn
|
|
24
|
+
yarn add -D @rotki/eslint-plugin
|
|
25
|
+
```
|
|
9
26
|
|
|
10
27
|
## Documentation
|
|
11
28
|
|
|
12
|
-
|
|
29
|
+
For detailed usage instructions, available rules, and configuration options,
|
|
30
|
+
please visit our [documentation](https://rotki.github.io/eslint-plugin).
|
|
31
|
+
|
|
32
|
+
## Contributing
|
|
33
|
+
|
|
34
|
+
Contributions are welcome!
|
|
35
|
+
Please read our [Contributing Guide](./CONTRIBUTING.md) before submitting a Pull Request.
|
|
36
|
+
The guide includes detailed information about:
|
|
37
|
+
|
|
38
|
+
- Project prerequisites
|
|
39
|
+
- Development setup
|
|
40
|
+
- Commit message conventions
|
|
41
|
+
- Code style and linting
|
|
42
|
+
- Pull request process
|
|
13
43
|
|
|
14
44
|
## License
|
|
15
45
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
1
2
|
import createDebug from 'debug';
|
|
2
|
-
import { extname } from 'node:path';
|
|
3
3
|
import * as compat from 'eslint-compat-utils';
|
|
4
|
+
import { extname } from 'node:path';
|
|
4
5
|
import { pascalCase, kebabCase } from 'scule';
|
|
5
|
-
import { TSESTree } from '@typescript-eslint/utils';
|
|
6
6
|
|
|
7
|
-
const version = "0.
|
|
7
|
+
const version = "1.0.0";
|
|
8
8
|
const pkg = {
|
|
9
9
|
version: version};
|
|
10
10
|
|
|
@@ -15,6 +15,63 @@ function getSourceCode(context) {
|
|
|
15
15
|
return compat.getSourceCode(context);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function createRecommended(plugin, name, flat) {
|
|
19
|
+
const rules = Object.fromEntries(Object.entries(plugin.rules).filter(([_key, rule]) => rule.meta.recommended === "recommended" && !rule.meta.deprecated).map(([key]) => [`${name}/${key}`, 2]));
|
|
20
|
+
if (flat) {
|
|
21
|
+
return {
|
|
22
|
+
plugins: {
|
|
23
|
+
[name]: plugin
|
|
24
|
+
},
|
|
25
|
+
rules
|
|
26
|
+
};
|
|
27
|
+
} else {
|
|
28
|
+
return {
|
|
29
|
+
plugins: [name],
|
|
30
|
+
rules
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getStringLiteralValue(node, stringOnly = false) {
|
|
36
|
+
if (node.type === "Literal") {
|
|
37
|
+
if (node.value == null) {
|
|
38
|
+
if (!stringOnly && node.bigint != null)
|
|
39
|
+
return node.bigint;
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (typeof node.value === "string")
|
|
43
|
+
return node.value;
|
|
44
|
+
if (!stringOnly)
|
|
45
|
+
return String(node.value);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1) {
|
|
49
|
+
return node.quasis[0].value.cooked;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
function getStaticPropertyName(node) {
|
|
54
|
+
if (node.type === "Property" || node.type === "MethodDefinition") {
|
|
55
|
+
if (!node.computed) {
|
|
56
|
+
const key2 = node.key;
|
|
57
|
+
if (key2.type === "Identifier")
|
|
58
|
+
return key2.name;
|
|
59
|
+
}
|
|
60
|
+
const key = node.key;
|
|
61
|
+
return getStringLiteralValue(key);
|
|
62
|
+
} else if (node.type === "MemberExpression") {
|
|
63
|
+
if (!node.computed) {
|
|
64
|
+
const property2 = node.property;
|
|
65
|
+
if (property2.type === "Identifier")
|
|
66
|
+
return property2.name;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const property = node.property;
|
|
70
|
+
return getStringLiteralValue(property);
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
18
75
|
const blobUrl = "https://rotki.github.io/eslint-plugin/rules/";
|
|
19
76
|
function RuleCreator(urlCreator) {
|
|
20
77
|
return function createNamedRule({
|
|
@@ -77,65 +134,107 @@ function defineTemplateBodyVisitor(context, templateBodyVisitor, scriptVisitor,
|
|
|
77
134
|
);
|
|
78
135
|
}
|
|
79
136
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
return
|
|
137
|
+
const debug$3 = createDebug("@rotki/eslint-plugin:consistent-ref-type-annotation");
|
|
138
|
+
const RULE_NAME$5 = "consistent-ref-type-annotation";
|
|
139
|
+
const FIXABLE_METHODS = ["ref", "computed"];
|
|
140
|
+
function checkAssignmentDeclaration(context, node, declaration, options) {
|
|
141
|
+
const source = getSourceCode(context);
|
|
142
|
+
const { allowInference } = options;
|
|
143
|
+
let declarationTypeArguments;
|
|
144
|
+
const init = declaration.init;
|
|
145
|
+
if (!(init && init.type === TSESTree.AST_NODE_TYPES.CallExpression))
|
|
146
|
+
return;
|
|
147
|
+
const callee = init.callee;
|
|
148
|
+
if (!(callee && callee.type === TSESTree.AST_NODE_TYPES.Identifier))
|
|
149
|
+
return;
|
|
150
|
+
if (!Array.prototype.includes.call(FIXABLE_METHODS, callee.name))
|
|
151
|
+
return;
|
|
152
|
+
const name = callee.name;
|
|
153
|
+
debug$3(`found ${name}, checking type arguments`);
|
|
154
|
+
const initializationTypeArguments = init.typeArguments;
|
|
155
|
+
const typeAnnotation = declaration.id.typeAnnotation;
|
|
156
|
+
if (typeAnnotation) {
|
|
157
|
+
const typeNode = typeAnnotation.typeAnnotation;
|
|
158
|
+
if (typeNode && typeNode.type === TSESTree.AST_NODE_TYPES.TSTypeReference)
|
|
159
|
+
declarationTypeArguments = typeNode.typeArguments;
|
|
95
160
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (property2.type === "Identifier")
|
|
111
|
-
return property2.name;
|
|
112
|
-
return null;
|
|
161
|
+
if (initializationTypeArguments && !declarationTypeArguments)
|
|
162
|
+
return;
|
|
163
|
+
debug$3(`generating report for ${name}`);
|
|
164
|
+
if (!initializationTypeArguments && !declarationTypeArguments) {
|
|
165
|
+
if (allowInference) {
|
|
166
|
+
debug$3("type inference is allowed");
|
|
167
|
+
} else {
|
|
168
|
+
context.report({
|
|
169
|
+
data: {
|
|
170
|
+
name
|
|
171
|
+
},
|
|
172
|
+
messageId: "missingType",
|
|
173
|
+
node
|
|
174
|
+
});
|
|
113
175
|
}
|
|
114
|
-
|
|
115
|
-
return getStringLiteralValue(property);
|
|
176
|
+
return;
|
|
116
177
|
}
|
|
117
|
-
|
|
178
|
+
context.report({
|
|
179
|
+
data: {
|
|
180
|
+
name
|
|
181
|
+
},
|
|
182
|
+
fix(fixer) {
|
|
183
|
+
const fixes = [];
|
|
184
|
+
if (!initializationTypeArguments && callee)
|
|
185
|
+
fixes.push(fixer.insertTextAfter(callee, source.getText(declarationTypeArguments)));
|
|
186
|
+
if (typeAnnotation)
|
|
187
|
+
fixes.push(fixer.remove(typeAnnotation));
|
|
188
|
+
return fixes;
|
|
189
|
+
},
|
|
190
|
+
messageId: "inconsistent",
|
|
191
|
+
node
|
|
192
|
+
});
|
|
118
193
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
plugins: {
|
|
125
|
-
[name]: plugin
|
|
126
|
-
},
|
|
127
|
-
rules
|
|
128
|
-
};
|
|
129
|
-
} else {
|
|
194
|
+
const consistentRefTypeAnnotation = createEslintRule({
|
|
195
|
+
create(context, optionsWithDefault) {
|
|
196
|
+
const options = optionsWithDefault[0] || {};
|
|
197
|
+
const allowInference = options.allowInference;
|
|
130
198
|
return {
|
|
131
|
-
|
|
132
|
-
|
|
199
|
+
VariableDeclaration: (node) => {
|
|
200
|
+
const declarations = node.declarations;
|
|
201
|
+
for (const declaration of declarations) {
|
|
202
|
+
if (declaration.type !== TSESTree.AST_NODE_TYPES.VariableDeclarator)
|
|
203
|
+
continue;
|
|
204
|
+
checkAssignmentDeclaration(context, node, declaration, { allowInference });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
133
207
|
};
|
|
134
|
-
}
|
|
135
|
-
}
|
|
208
|
+
},
|
|
209
|
+
defaultOptions: [{ allowInference: false }],
|
|
210
|
+
meta: {
|
|
211
|
+
docs: {
|
|
212
|
+
description: "Ensures consistent type annotation position for ref, computed assignments",
|
|
213
|
+
recommendation: "recommended"
|
|
214
|
+
},
|
|
215
|
+
fixable: "code",
|
|
216
|
+
messages: {
|
|
217
|
+
inconsistent: `Generic type annotation for the {{ name }} call was not on the right side`,
|
|
218
|
+
missingType: `variable assignment for {{ name }} is missing the type annotation`
|
|
219
|
+
},
|
|
220
|
+
schema: [
|
|
221
|
+
{
|
|
222
|
+
additionalProperties: false,
|
|
223
|
+
properties: {
|
|
224
|
+
allowInference: {
|
|
225
|
+
type: "boolean"
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
type: "object"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
type: "problem"
|
|
232
|
+
},
|
|
233
|
+
name: RULE_NAME$5
|
|
234
|
+
});
|
|
136
235
|
|
|
137
|
-
const RULE_NAME$
|
|
138
|
-
const debug$
|
|
236
|
+
const RULE_NAME$4 = "no-deprecated-classes";
|
|
237
|
+
const debug$2 = createDebug("@rotki/eslint-plugin:no-deprecated-classes");
|
|
139
238
|
const replacements$2 = [
|
|
140
239
|
["d-block", "block"],
|
|
141
240
|
["d-flex", "flex"],
|
|
@@ -187,7 +286,7 @@ function findReplacement(className) {
|
|
|
187
286
|
return replace(matches);
|
|
188
287
|
}
|
|
189
288
|
}
|
|
190
|
-
return
|
|
289
|
+
return void 0;
|
|
191
290
|
}
|
|
192
291
|
function getRange(node) {
|
|
193
292
|
if (node.type === "VAttribute" && node.value && node.value.range)
|
|
@@ -195,7 +294,7 @@ function getRange(node) {
|
|
|
195
294
|
return node.range;
|
|
196
295
|
}
|
|
197
296
|
function reportReplacement(className, replacement, node, context, position = 1) {
|
|
198
|
-
debug$
|
|
297
|
+
debug$2(`found replacement ${replacement} for ${className}`);
|
|
199
298
|
const source = getSourceCode(context);
|
|
200
299
|
const initialRange = getRange(node);
|
|
201
300
|
const range = [
|
|
@@ -308,11 +407,11 @@ const noDeprecatedClasses = createEslintRule({
|
|
|
308
407
|
schema: [],
|
|
309
408
|
type: "problem"
|
|
310
409
|
},
|
|
311
|
-
name: RULE_NAME$
|
|
410
|
+
name: RULE_NAME$4
|
|
312
411
|
});
|
|
313
412
|
|
|
314
|
-
const debug$
|
|
315
|
-
const RULE_NAME$
|
|
413
|
+
const debug$1 = createDebug("@rotki/eslint-plugin:no-deprecated-components");
|
|
414
|
+
const RULE_NAME$3 = "no-deprecated-components";
|
|
316
415
|
const vuetify = {
|
|
317
416
|
VApp: true,
|
|
318
417
|
VAppBar: true,
|
|
@@ -365,7 +464,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
365
464
|
return;
|
|
366
465
|
const replacement = replacements$1[tag];
|
|
367
466
|
if (replacement || legacy && skipInLegacy.includes(tag)) {
|
|
368
|
-
debug$
|
|
467
|
+
debug$1(`${tag} has been deprecated`);
|
|
369
468
|
context.report({
|
|
370
469
|
data: {
|
|
371
470
|
name: tag
|
|
@@ -374,7 +473,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
374
473
|
node: element
|
|
375
474
|
});
|
|
376
475
|
} else {
|
|
377
|
-
debug$
|
|
476
|
+
debug$1(`${tag} has will be removed`);
|
|
378
477
|
context.report({
|
|
379
478
|
data: {
|
|
380
479
|
name: tag
|
|
@@ -417,11 +516,11 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
417
516
|
],
|
|
418
517
|
type: "problem"
|
|
419
518
|
},
|
|
420
|
-
name: RULE_NAME$
|
|
519
|
+
name: RULE_NAME$3
|
|
421
520
|
});
|
|
422
521
|
|
|
423
|
-
const debug
|
|
424
|
-
const RULE_NAME$
|
|
522
|
+
const debug = createDebug("@rotki/eslint-plugin:no-deprecated-props");
|
|
523
|
+
const RULE_NAME$2 = "no-deprecated-props";
|
|
425
524
|
const replacements = {
|
|
426
525
|
RuiRadio: {
|
|
427
526
|
internalValue: "value"
|
|
@@ -433,7 +532,7 @@ function hasReplacement(tag) {
|
|
|
433
532
|
function getPropName(node) {
|
|
434
533
|
if (node.directive) {
|
|
435
534
|
if (node.key.argument?.type !== "VIdentifier")
|
|
436
|
-
return
|
|
535
|
+
return void 0;
|
|
437
536
|
return kebabCase(node.key.argument.rawName);
|
|
438
537
|
}
|
|
439
538
|
return kebabCase(node.key.rawName);
|
|
@@ -447,16 +546,16 @@ const noDeprecatedProps = createEslintRule({
|
|
|
447
546
|
const tag = pascalCase(node.parent.parent.rawName);
|
|
448
547
|
if (!hasReplacement(tag))
|
|
449
548
|
return;
|
|
450
|
-
debug
|
|
549
|
+
debug(`${tag} has replacement properties`);
|
|
451
550
|
const propName = getPropName(node);
|
|
452
551
|
const propNameNode = node.directive ? node.key.argument : node.key;
|
|
453
552
|
if (!propName || !propNameNode) {
|
|
454
|
-
debug
|
|
553
|
+
debug("could not get prop name and/or node");
|
|
455
554
|
return;
|
|
456
555
|
}
|
|
457
556
|
Object.entries(replacements[tag]).forEach(([prop, replacement]) => {
|
|
458
557
|
if (kebabCase(prop) === propName) {
|
|
459
|
-
debug
|
|
558
|
+
debug(`preparing a replacement for ${tag}:${propName} -> ${replacement}`);
|
|
460
559
|
context.report({
|
|
461
560
|
data: {
|
|
462
561
|
prop,
|
|
@@ -486,24 +585,27 @@ const noDeprecatedProps = createEslintRule({
|
|
|
486
585
|
schema: [],
|
|
487
586
|
type: "problem"
|
|
488
587
|
},
|
|
489
|
-
name: RULE_NAME$
|
|
588
|
+
name: RULE_NAME$2
|
|
490
589
|
});
|
|
491
590
|
|
|
492
|
-
const RULE_NAME$
|
|
493
|
-
const
|
|
494
|
-
const newLibrary = "@rotki/ui-library";
|
|
495
|
-
const noLegacyLibraryImport = createEslintRule({
|
|
591
|
+
const RULE_NAME$1 = "no-dot-ts-imports";
|
|
592
|
+
const noDotTsImport = createEslintRule({
|
|
496
593
|
create(context) {
|
|
497
594
|
return {
|
|
498
595
|
ImportDeclaration(node) {
|
|
499
|
-
|
|
596
|
+
const importDeclaration = node.source.value;
|
|
597
|
+
if (!importDeclaration.endsWith(".ts"))
|
|
500
598
|
return;
|
|
501
|
-
const
|
|
599
|
+
const lastIndexOfExtension = importDeclaration.lastIndexOf(".ts");
|
|
600
|
+
const replacement = importDeclaration.substring(0, lastIndexOfExtension);
|
|
502
601
|
context.report({
|
|
602
|
+
data: {
|
|
603
|
+
import: importDeclaration
|
|
604
|
+
},
|
|
503
605
|
fix(fixer) {
|
|
504
606
|
return fixer.replaceText(node.source, `'${replacement}'`);
|
|
505
607
|
},
|
|
506
|
-
messageId: "
|
|
608
|
+
messageId: "invalidTSExtension",
|
|
507
609
|
node: node.source
|
|
508
610
|
});
|
|
509
611
|
}
|
|
@@ -512,136 +614,34 @@ const noLegacyLibraryImport = createEslintRule({
|
|
|
512
614
|
defaultOptions: [],
|
|
513
615
|
meta: {
|
|
514
616
|
docs: {
|
|
515
|
-
description:
|
|
617
|
+
description: "Checks and replaces .ts extension in import statements.",
|
|
516
618
|
recommendation: "recommended"
|
|
517
619
|
},
|
|
518
620
|
fixable: "code",
|
|
519
621
|
messages: {
|
|
520
|
-
|
|
622
|
+
invalidTSExtension: `'{{ import }}' has a .ts extension, please remove it'`
|
|
521
623
|
},
|
|
522
624
|
schema: [],
|
|
523
625
|
type: "problem"
|
|
524
626
|
},
|
|
525
|
-
name: RULE_NAME$2
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
const debug = createDebug("@rotki/eslint-plugin:consistent-ref-type-annotation");
|
|
529
|
-
const RULE_NAME$1 = "consistent-ref-type-annotation";
|
|
530
|
-
const FIXABLE_METHODS = ["ref", "computed"];
|
|
531
|
-
function checkAssignmentDeclaration(context, node, declaration, options) {
|
|
532
|
-
const source = getSourceCode(context);
|
|
533
|
-
const { allowInference } = options;
|
|
534
|
-
let declarationTypeArguments;
|
|
535
|
-
const init = declaration.init;
|
|
536
|
-
if (!(init && init.type === TSESTree.AST_NODE_TYPES.CallExpression))
|
|
537
|
-
return;
|
|
538
|
-
const callee = init.callee;
|
|
539
|
-
if (!(callee && callee.type === TSESTree.AST_NODE_TYPES.Identifier))
|
|
540
|
-
return;
|
|
541
|
-
if (!Array.prototype.includes.call(FIXABLE_METHODS, callee.name))
|
|
542
|
-
return;
|
|
543
|
-
const name = callee.name;
|
|
544
|
-
debug(`found ${name}, checking type arguments`);
|
|
545
|
-
const initializationTypeArguments = init.typeArguments;
|
|
546
|
-
const typeAnnotation = declaration.id.typeAnnotation;
|
|
547
|
-
if (typeAnnotation) {
|
|
548
|
-
const typeNode = typeAnnotation.typeAnnotation;
|
|
549
|
-
if (typeNode && typeNode.type === TSESTree.AST_NODE_TYPES.TSTypeReference)
|
|
550
|
-
declarationTypeArguments = typeNode.typeArguments;
|
|
551
|
-
}
|
|
552
|
-
if (initializationTypeArguments && !declarationTypeArguments)
|
|
553
|
-
return;
|
|
554
|
-
debug(`generating report for ${name}`);
|
|
555
|
-
if (!initializationTypeArguments && !declarationTypeArguments) {
|
|
556
|
-
if (allowInference) {
|
|
557
|
-
debug("type inference is allowed");
|
|
558
|
-
} else {
|
|
559
|
-
context.report({
|
|
560
|
-
data: {
|
|
561
|
-
name
|
|
562
|
-
},
|
|
563
|
-
messageId: "missingType",
|
|
564
|
-
node
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
return;
|
|
568
|
-
}
|
|
569
|
-
context.report({
|
|
570
|
-
data: {
|
|
571
|
-
name
|
|
572
|
-
},
|
|
573
|
-
fix(fixer) {
|
|
574
|
-
const fixes = [];
|
|
575
|
-
if (!initializationTypeArguments && callee)
|
|
576
|
-
fixes.push(fixer.insertTextAfter(callee, source.getText(declarationTypeArguments)));
|
|
577
|
-
if (typeAnnotation)
|
|
578
|
-
fixes.push(fixer.remove(typeAnnotation));
|
|
579
|
-
return fixes;
|
|
580
|
-
},
|
|
581
|
-
messageId: "inconsistent",
|
|
582
|
-
node
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
const consistentRefTypeAnnotation = createEslintRule({
|
|
586
|
-
create(context, optionsWithDefault) {
|
|
587
|
-
const options = optionsWithDefault[0] || {};
|
|
588
|
-
const allowInference = options.allowInference;
|
|
589
|
-
return {
|
|
590
|
-
VariableDeclaration: (node) => {
|
|
591
|
-
const declarations = node.declarations;
|
|
592
|
-
for (const declaration of declarations) {
|
|
593
|
-
if (declaration.type !== TSESTree.AST_NODE_TYPES.VariableDeclarator)
|
|
594
|
-
continue;
|
|
595
|
-
checkAssignmentDeclaration(context, node, declaration, { allowInference });
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
|
-
},
|
|
600
|
-
defaultOptions: [{ allowInference: false }],
|
|
601
|
-
meta: {
|
|
602
|
-
docs: {
|
|
603
|
-
description: "Ensures consistent type annotation position for ref, computed assignments",
|
|
604
|
-
recommendation: "recommended"
|
|
605
|
-
},
|
|
606
|
-
fixable: "code",
|
|
607
|
-
messages: {
|
|
608
|
-
inconsistent: `Generic type annotation for the {{ name }} call was not on the right side`,
|
|
609
|
-
missingType: `variable assignment for {{ name }} is missing the type annotation`
|
|
610
|
-
},
|
|
611
|
-
schema: [
|
|
612
|
-
{
|
|
613
|
-
additionalProperties: false,
|
|
614
|
-
properties: {
|
|
615
|
-
allowInference: {
|
|
616
|
-
type: "boolean"
|
|
617
|
-
}
|
|
618
|
-
},
|
|
619
|
-
type: "object"
|
|
620
|
-
}
|
|
621
|
-
],
|
|
622
|
-
type: "problem"
|
|
623
|
-
},
|
|
624
627
|
name: RULE_NAME$1
|
|
625
628
|
});
|
|
626
629
|
|
|
627
|
-
const RULE_NAME = "no-
|
|
628
|
-
const
|
|
630
|
+
const RULE_NAME = "no-legacy-library-import";
|
|
631
|
+
const legacyLibrary = "@rotki/ui-library-compat";
|
|
632
|
+
const newLibrary = "@rotki/ui-library";
|
|
633
|
+
const noLegacyLibraryImport = createEslintRule({
|
|
629
634
|
create(context) {
|
|
630
635
|
return {
|
|
631
636
|
ImportDeclaration(node) {
|
|
632
|
-
|
|
633
|
-
if (!importDeclaration.endsWith(".ts"))
|
|
637
|
+
if (!node.source.value.startsWith(legacyLibrary))
|
|
634
638
|
return;
|
|
635
|
-
const
|
|
636
|
-
const replacement = importDeclaration.substring(0, lastIndexOfExtension);
|
|
639
|
+
const replacement = node.source.value.replace(legacyLibrary, newLibrary);
|
|
637
640
|
context.report({
|
|
638
|
-
data: {
|
|
639
|
-
import: importDeclaration
|
|
640
|
-
},
|
|
641
641
|
fix(fixer) {
|
|
642
642
|
return fixer.replaceText(node.source, `'${replacement}'`);
|
|
643
643
|
},
|
|
644
|
-
messageId: "
|
|
644
|
+
messageId: "replacedWith",
|
|
645
645
|
node: node.source
|
|
646
646
|
});
|
|
647
647
|
}
|
|
@@ -650,12 +650,12 @@ const noDotTsImport = createEslintRule({
|
|
|
650
650
|
defaultOptions: [],
|
|
651
651
|
meta: {
|
|
652
652
|
docs: {
|
|
653
|
-
description:
|
|
653
|
+
description: `Reports and replaces imports of ${legacyLibrary} with ${newLibrary}`,
|
|
654
654
|
recommendation: "recommended"
|
|
655
655
|
},
|
|
656
656
|
fixable: "code",
|
|
657
657
|
messages: {
|
|
658
|
-
|
|
658
|
+
replacedWith: `${legacyLibrary} has been replaced by ${newLibrary}`
|
|
659
659
|
},
|
|
660
660
|
schema: [],
|
|
661
661
|
type: "problem"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotki/eslint-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"bugs": {
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
|
-
"require": "./dist/index.cjs",
|
|
24
23
|
"import": "./dist/index.mjs"
|
|
25
24
|
}
|
|
26
25
|
},
|
|
@@ -29,39 +28,39 @@
|
|
|
29
28
|
"eslint": "^9.0.0"
|
|
30
29
|
},
|
|
31
30
|
"dependencies": {
|
|
32
|
-
"@typescript-eslint/utils": "8.
|
|
31
|
+
"@typescript-eslint/utils": "8.26.0",
|
|
33
32
|
"debug": "4.4.0",
|
|
34
33
|
"eslint-compat-utils": "0.6.4",
|
|
35
34
|
"jsonc-eslint-parser": "2.4.0",
|
|
36
35
|
"scule": "1.3.0",
|
|
37
|
-
"vue-eslint-parser": "
|
|
38
|
-
"yaml-eslint-parser": "1.
|
|
36
|
+
"vue-eslint-parser": "10.1.1",
|
|
37
|
+
"yaml-eslint-parser": "1.3.0"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
40
|
"@commitlint/cli": "19.7.1",
|
|
42
41
|
"@commitlint/config-conventional": "19.7.1",
|
|
43
|
-
"@rotki/eslint-config": "
|
|
42
|
+
"@rotki/eslint-config": "4.0.1",
|
|
44
43
|
"@types/debug": "4.1.12",
|
|
45
44
|
"@types/node": "20",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
47
|
-
"@typescript-eslint/parser": "8.
|
|
48
|
-
"@typescript-eslint/rule-tester": "8.
|
|
49
|
-
"@vitest/coverage-v8": "3.0.
|
|
50
|
-
"bumpp": "10.0.
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "8.26.0",
|
|
46
|
+
"@typescript-eslint/parser": "8.26.0",
|
|
47
|
+
"@typescript-eslint/rule-tester": "8.26.0",
|
|
48
|
+
"@vitest/coverage-v8": "3.0.8",
|
|
49
|
+
"bumpp": "10.0.3",
|
|
51
50
|
"debug": "4.4.0",
|
|
52
|
-
"eslint": "9.
|
|
51
|
+
"eslint": "9.21.0",
|
|
53
52
|
"husky": "9.1.7",
|
|
54
53
|
"lint-staged": "15.4.3",
|
|
55
54
|
"rimraf": "6.0.1",
|
|
56
|
-
"
|
|
57
|
-
"typescript": "5.
|
|
58
|
-
"unbuild": "3.
|
|
55
|
+
"tsx": "4.19.3",
|
|
56
|
+
"typescript": "5.8.2",
|
|
57
|
+
"unbuild": "3.5.0",
|
|
59
58
|
"vitepress": "1.6.3",
|
|
60
|
-
"vitest": "3.0.
|
|
59
|
+
"vitest": "3.0.8"
|
|
61
60
|
},
|
|
62
61
|
"engines": {
|
|
63
62
|
"node": ">=20",
|
|
64
|
-
"pnpm": ">=
|
|
63
|
+
"pnpm": ">=10 <11"
|
|
65
64
|
},
|
|
66
65
|
"lint-staged": {
|
|
67
66
|
"*.{js,cjs,ts,vue,yml,json,md}": "eslint"
|
|
@@ -69,15 +68,15 @@
|
|
|
69
68
|
"scripts": {
|
|
70
69
|
"clean": "rimraf .nyc_output coverage dist docs/.vitepress/dist",
|
|
71
70
|
"coverage": "nyc report --reporter lcov && opener coverage/lcov-report/index.html",
|
|
72
|
-
"generate": "
|
|
73
|
-
"generate:index": "
|
|
71
|
+
"generate": "tsx scripts/update-rule-docs.ts",
|
|
72
|
+
"generate:index": "tsx scripts/update-docs-index.ts",
|
|
74
73
|
"lint": "eslint .",
|
|
75
74
|
"lint:fix": "eslint . --fix",
|
|
76
75
|
"build": "unbuild",
|
|
77
76
|
"dev": "unbuild --stub",
|
|
78
77
|
"test": "vitest",
|
|
79
78
|
"test:coverage": "vitest run --coverage",
|
|
80
|
-
"new": "
|
|
79
|
+
"new": "tsx ./scripts/new-rule.ts",
|
|
81
80
|
"docs": "vitepress dev docs",
|
|
82
81
|
"docs:build": "pnpm run generate && pnpm run generate:index && vitepress build docs",
|
|
83
82
|
"typecheck": "tsc --noEmit",
|