@rotki/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/dist/index.cjs +298 -81
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +298 -81
- package/package.json +9 -8
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const createDebug = require('debug');
|
|
3
4
|
const node_path = require('node:path');
|
|
4
5
|
const compat = require('eslint-compat-utils');
|
|
5
|
-
const createDebug = require('debug');
|
|
6
6
|
const scule = require('scule');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -19,12 +19,12 @@ function _interopNamespaceCompat(e) {
|
|
|
19
19
|
return n;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const compat__namespace = /*#__PURE__*/_interopNamespaceCompat(compat);
|
|
23
22
|
const createDebug__default = /*#__PURE__*/_interopDefaultCompat(createDebug);
|
|
23
|
+
const compat__namespace = /*#__PURE__*/_interopNamespaceCompat(compat);
|
|
24
24
|
|
|
25
25
|
const name = "@rotki/eslint-plugin";
|
|
26
|
-
const version = "0.1
|
|
27
|
-
const packageManager = "pnpm@8.14.
|
|
26
|
+
const version = "0.2.1";
|
|
27
|
+
const packageManager = "pnpm@8.14.3";
|
|
28
28
|
const type = "module";
|
|
29
29
|
const license = "AGPL-3.0";
|
|
30
30
|
const bugs = {
|
|
@@ -70,25 +70,26 @@ const peerDependencies = {
|
|
|
70
70
|
eslint: "^8.0.0 || ^9.0.0"
|
|
71
71
|
};
|
|
72
72
|
const dependencies = {
|
|
73
|
-
"@typescript-eslint/utils": "6.19.
|
|
73
|
+
"@typescript-eslint/utils": "6.19.1",
|
|
74
74
|
debug: "4.3.4",
|
|
75
75
|
"eslint-compat-utils": "0.4.1",
|
|
76
76
|
"jsonc-eslint-parser": "2.4.0",
|
|
77
77
|
scule: "1.2.0",
|
|
78
|
-
"vue-eslint-parser": "9.4.
|
|
78
|
+
"vue-eslint-parser": "9.4.2",
|
|
79
79
|
"yaml-eslint-parser": "1.2.2"
|
|
80
80
|
};
|
|
81
81
|
const devDependencies = {
|
|
82
82
|
"@commitlint/cli": "18.5.0",
|
|
83
83
|
"@commitlint/config-conventional": "18.5.0",
|
|
84
|
-
"@rotki/eslint-config": "2.
|
|
84
|
+
"@rotki/eslint-config": "2.4.1",
|
|
85
85
|
"@types/debug": "4.1.12",
|
|
86
86
|
"@types/eslint": "8.56.2",
|
|
87
87
|
"@types/node": "20",
|
|
88
|
-
"@typescript-eslint/eslint-plugin": "6.19.
|
|
89
|
-
"@typescript-eslint/parser": "6.19.
|
|
90
|
-
"@typescript-eslint/rule-tester": "6.19.
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "6.19.1",
|
|
89
|
+
"@typescript-eslint/parser": "6.19.1",
|
|
90
|
+
"@typescript-eslint/rule-tester": "6.19.1",
|
|
91
91
|
bumpp: "9.3.0",
|
|
92
|
+
debug: "4.3.4",
|
|
92
93
|
eslint: "8.56.0",
|
|
93
94
|
husky: "8.0.3",
|
|
94
95
|
"lint-staged": "15.2.0",
|
|
@@ -195,8 +196,65 @@ function defineTemplateBodyVisitor(context, templateBodyVisitor, scriptVisitor,
|
|
|
195
196
|
);
|
|
196
197
|
}
|
|
197
198
|
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
function getStringLiteralValue(node, stringOnly = false) {
|
|
200
|
+
if (node.type === "Literal") {
|
|
201
|
+
if (node.value == null) {
|
|
202
|
+
if (!stringOnly && node.bigint != null)
|
|
203
|
+
return node.bigint;
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
if (typeof node.value === "string")
|
|
207
|
+
return node.value;
|
|
208
|
+
if (!stringOnly)
|
|
209
|
+
return String(node.value);
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1)
|
|
213
|
+
return node.quasis[0].value.cooked;
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
function getStaticPropertyName(node) {
|
|
217
|
+
if (node.type === "Property" || node.type === "MethodDefinition") {
|
|
218
|
+
if (!node.computed) {
|
|
219
|
+
const key2 = node.key;
|
|
220
|
+
if (key2.type === "Identifier")
|
|
221
|
+
return key2.name;
|
|
222
|
+
}
|
|
223
|
+
const key = node.key;
|
|
224
|
+
return getStringLiteralValue(key);
|
|
225
|
+
} else if (node.type === "MemberExpression") {
|
|
226
|
+
if (!node.computed) {
|
|
227
|
+
const property2 = node.property;
|
|
228
|
+
if (property2.type === "Identifier")
|
|
229
|
+
return property2.name;
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
const property = node.property;
|
|
233
|
+
return getStringLiteralValue(property);
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function createRecommended(plugin, name, flat) {
|
|
239
|
+
const rules = Object.fromEntries(Object.entries(plugin.rules).filter(([_key, rule]) => rule.meta.recommended === "recommended" && !rule.meta.deprecated).map(([key]) => [`${name}/${key}`, 2]));
|
|
240
|
+
if (flat) {
|
|
241
|
+
return {
|
|
242
|
+
plugins: {
|
|
243
|
+
[name]: plugin
|
|
244
|
+
},
|
|
245
|
+
rules
|
|
246
|
+
};
|
|
247
|
+
} else {
|
|
248
|
+
return {
|
|
249
|
+
plugins: [name],
|
|
250
|
+
rules
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const RULE_NAME$3 = "no-deprecated-classes";
|
|
256
|
+
const debug$2 = createDebug__default("@rotki/eslint-plugin:no-deprecated-classes");
|
|
257
|
+
const replacements$2 = [
|
|
200
258
|
["d-block", "block"],
|
|
201
259
|
["d-flex", "flex"],
|
|
202
260
|
["flex-column", "flex-col"],
|
|
@@ -225,51 +283,122 @@ function isString(replacement) {
|
|
|
225
283
|
function isRegex(replacement) {
|
|
226
284
|
return replacement[0] instanceof RegExp;
|
|
227
285
|
}
|
|
286
|
+
function findReplacement(className) {
|
|
287
|
+
for (const replacement of replacements$2) {
|
|
288
|
+
if (isString(replacement) && replacement[0] === className)
|
|
289
|
+
return replacement[1];
|
|
290
|
+
if (isRegex(replacement)) {
|
|
291
|
+
const matches = (replacement[0].exec(className) || []).slice(1);
|
|
292
|
+
const replace = replacement[1];
|
|
293
|
+
if (matches.length > 0 && typeof replace === "function")
|
|
294
|
+
return replace(matches);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return void 0;
|
|
298
|
+
}
|
|
299
|
+
function getRange(node) {
|
|
300
|
+
if (node.type === "VAttribute" && node.value && node.value.range)
|
|
301
|
+
return node.value.range;
|
|
302
|
+
return node.range;
|
|
303
|
+
}
|
|
304
|
+
function reportReplacement(className, replacement, node, context, position = 1) {
|
|
305
|
+
debug$2(`found replacement ${replacement} for ${className}`);
|
|
306
|
+
const source = getSourceCode(context);
|
|
307
|
+
const initialRange = getRange(node);
|
|
308
|
+
const range = [
|
|
309
|
+
initialRange[0] + position,
|
|
310
|
+
initialRange[0] + position + className.length
|
|
311
|
+
];
|
|
312
|
+
const loc = {
|
|
313
|
+
end: source.getLocFromIndex(range[1]),
|
|
314
|
+
start: source.getLocFromIndex(range[0])
|
|
315
|
+
};
|
|
316
|
+
context.report({
|
|
317
|
+
data: {
|
|
318
|
+
className,
|
|
319
|
+
replacement
|
|
320
|
+
},
|
|
321
|
+
fix(fixer) {
|
|
322
|
+
return fixer.replaceTextRange(range, replacement);
|
|
323
|
+
},
|
|
324
|
+
loc,
|
|
325
|
+
messageId: "replacedWith"
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
function* extractClassNames(node, textOnly = false) {
|
|
329
|
+
if (node.type === "Literal") {
|
|
330
|
+
const classNames = `${node.value}`;
|
|
331
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: node }));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
if (node.type === "TemplateLiteral") {
|
|
335
|
+
for (const templateElement of node.quasis) {
|
|
336
|
+
const classNames = templateElement.value.cooked;
|
|
337
|
+
if (classNames === null)
|
|
338
|
+
continue;
|
|
339
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: templateElement }));
|
|
340
|
+
}
|
|
341
|
+
for (const expr of node.expressions)
|
|
342
|
+
yield* extractClassNames(expr, true);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (node.type === "BinaryExpression") {
|
|
346
|
+
if (node.operator !== "+")
|
|
347
|
+
return;
|
|
348
|
+
yield* extractClassNames(node.left, true);
|
|
349
|
+
yield* extractClassNames(node.right, true);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (textOnly)
|
|
353
|
+
return;
|
|
354
|
+
if (node.type === "ObjectExpression") {
|
|
355
|
+
for (const prop of node.properties) {
|
|
356
|
+
if (prop.type !== "Property")
|
|
357
|
+
continue;
|
|
358
|
+
const classNames = getStaticPropertyName(prop);
|
|
359
|
+
if (!classNames)
|
|
360
|
+
continue;
|
|
361
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: prop.key }));
|
|
362
|
+
}
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (node.type === "ArrayExpression") {
|
|
366
|
+
for (const element of node.elements) {
|
|
367
|
+
if (element == null)
|
|
368
|
+
continue;
|
|
369
|
+
if (element.type === "SpreadElement")
|
|
370
|
+
continue;
|
|
371
|
+
yield* extractClassNames(element);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (node.type === "ConditionalExpression") {
|
|
375
|
+
yield* extractClassNames(node.consequent);
|
|
376
|
+
yield* extractClassNames(node.alternate);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
228
379
|
const noDeprecatedClasses = createEslintRule({
|
|
229
380
|
create(context) {
|
|
230
381
|
return defineTemplateBodyVisitor(context, {
|
|
231
|
-
'VAttribute[key.name="class"]': function(node) {
|
|
382
|
+
'VAttribute[directive=false][key.name="class"]': function(node) {
|
|
232
383
|
if (!node.value || !node.value.value)
|
|
233
384
|
return;
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return;
|
|
252
|
-
const idx = node.value.value.indexOf(replacement[0]) + 1;
|
|
253
|
-
const range = [
|
|
254
|
-
node.value.range[0] + idx,
|
|
255
|
-
node.value.range[0] + idx + replacement[0].length
|
|
256
|
-
];
|
|
257
|
-
const loc = {
|
|
258
|
-
end: source.getLocFromIndex(range[1]),
|
|
259
|
-
start: source.getLocFromIndex(range[0])
|
|
260
|
-
};
|
|
261
|
-
context.report({
|
|
262
|
-
data: {
|
|
263
|
-
a: replacement[0],
|
|
264
|
-
b: replacement[1]
|
|
265
|
-
},
|
|
266
|
-
fix(fixer) {
|
|
267
|
-
return fixer.replaceTextRange(range, replacement[1]);
|
|
268
|
-
},
|
|
269
|
-
loc,
|
|
270
|
-
messageId: "replacedWith"
|
|
271
|
-
});
|
|
272
|
-
});
|
|
385
|
+
for (const className of node.value.value.split(/\s+/).filter((s) => !!s)) {
|
|
386
|
+
const replacement = findReplacement(className);
|
|
387
|
+
const position = node.value.value.indexOf(className) + 1;
|
|
388
|
+
if (!replacement)
|
|
389
|
+
continue;
|
|
390
|
+
reportReplacement(className, replacement, node, context, position);
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
"VAttribute[directive=true][key.name.name='bind'][key.argument.name='class'] > VExpressionContainer.value": function(node) {
|
|
394
|
+
if (!node.expression)
|
|
395
|
+
return;
|
|
396
|
+
for (const { className, position, reportNode } of extractClassNames(node.expression)) {
|
|
397
|
+
const replacement = findReplacement(className);
|
|
398
|
+
if (!replacement)
|
|
399
|
+
continue;
|
|
400
|
+
reportReplacement(className, replacement, reportNode, context, position);
|
|
401
|
+
}
|
|
273
402
|
}
|
|
274
403
|
});
|
|
275
404
|
},
|
|
@@ -281,25 +410,25 @@ const noDeprecatedClasses = createEslintRule({
|
|
|
281
410
|
},
|
|
282
411
|
fixable: "code",
|
|
283
412
|
messages: {
|
|
284
|
-
replacedWith: `'{{
|
|
413
|
+
replacedWith: `'{{ className }}' has been replaced with '{{ replacement }}'`
|
|
285
414
|
},
|
|
286
415
|
schema: [],
|
|
287
416
|
type: "problem"
|
|
288
417
|
},
|
|
289
|
-
name: RULE_NAME$
|
|
418
|
+
name: RULE_NAME$3
|
|
290
419
|
});
|
|
291
420
|
|
|
292
|
-
const debug = createDebug__default("@rotki/eslint-plugin:no-deprecated-components");
|
|
293
|
-
const RULE_NAME = "no-deprecated-components";
|
|
294
|
-
const replacements = {
|
|
421
|
+
const debug$1 = createDebug__default("@rotki/eslint-plugin:no-deprecated-components");
|
|
422
|
+
const RULE_NAME$2 = "no-deprecated-components";
|
|
423
|
+
const replacements$1 = {
|
|
295
424
|
DataTable: true,
|
|
296
425
|
Fragment: false
|
|
297
426
|
};
|
|
298
427
|
const skipInLegacy = [
|
|
299
428
|
"Fragment"
|
|
300
429
|
];
|
|
301
|
-
function hasReplacement(tag) {
|
|
302
|
-
return Object.prototype.hasOwnProperty.call(replacements, tag);
|
|
430
|
+
function hasReplacement$1(tag) {
|
|
431
|
+
return Object.prototype.hasOwnProperty.call(replacements$1, tag);
|
|
303
432
|
}
|
|
304
433
|
const noDeprecatedComponents = createEslintRule({
|
|
305
434
|
create(context, optionsWithDefault) {
|
|
@@ -311,11 +440,11 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
311
440
|
const sourceCode = getSourceCode(context);
|
|
312
441
|
if (!("getTemplateBodyTokenStore" in sourceCode.parserServices))
|
|
313
442
|
throw new Error("cannot find getTemplateBodyTokenStore in parserServices");
|
|
314
|
-
if (!hasReplacement(tag))
|
|
443
|
+
if (!hasReplacement$1(tag))
|
|
315
444
|
return;
|
|
316
|
-
const replacement = replacements[tag];
|
|
445
|
+
const replacement = replacements$1[tag];
|
|
317
446
|
if (replacement || legacy && skipInLegacy.includes(tag)) {
|
|
318
|
-
debug(`${tag} has been deprecated`);
|
|
447
|
+
debug$1(`${tag} has been deprecated`);
|
|
319
448
|
context.report({
|
|
320
449
|
data: {
|
|
321
450
|
name: scule.snakeCase(tag)
|
|
@@ -324,7 +453,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
324
453
|
node: element
|
|
325
454
|
});
|
|
326
455
|
} else {
|
|
327
|
-
debug(`${tag} has will be removed`);
|
|
456
|
+
debug$1(`${tag} has will be removed`);
|
|
328
457
|
context.report({
|
|
329
458
|
data: {
|
|
330
459
|
name: scule.snakeCase(tag)
|
|
@@ -367,6 +496,109 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
367
496
|
],
|
|
368
497
|
type: "problem"
|
|
369
498
|
},
|
|
499
|
+
name: RULE_NAME$2
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
const debug = createDebug__default("@rotki/eslint-plugin:no-deprecated-props");
|
|
503
|
+
const RULE_NAME$1 = "no-deprecated-props";
|
|
504
|
+
const replacements = {
|
|
505
|
+
RuiRadio: {
|
|
506
|
+
internalValue: "value"
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
function hasReplacement(tag) {
|
|
510
|
+
return Object.prototype.hasOwnProperty.call(replacements, tag);
|
|
511
|
+
}
|
|
512
|
+
function getPropName(node) {
|
|
513
|
+
if (node.directive) {
|
|
514
|
+
if (node.key.argument?.type !== "VIdentifier")
|
|
515
|
+
return void 0;
|
|
516
|
+
return scule.kebabCase(node.key.argument.rawName);
|
|
517
|
+
}
|
|
518
|
+
return scule.kebabCase(node.key.rawName);
|
|
519
|
+
}
|
|
520
|
+
const noDeprecatedProps = createEslintRule({
|
|
521
|
+
create(context) {
|
|
522
|
+
return defineTemplateBodyVisitor(context, {
|
|
523
|
+
VAttribute(node) {
|
|
524
|
+
if (node.directive && (node.value?.type === "VExpressionContainer" && (node.key.name.name !== "bind" || !node.key.argument)))
|
|
525
|
+
return;
|
|
526
|
+
const tag = scule.pascalCase(node.parent.parent.rawName);
|
|
527
|
+
if (!hasReplacement(tag))
|
|
528
|
+
return;
|
|
529
|
+
debug(`${tag} has replacement properties`);
|
|
530
|
+
const propName = getPropName(node);
|
|
531
|
+
const propNameNode = node.directive ? node.key.argument : node.key;
|
|
532
|
+
if (!propName || !propNameNode) {
|
|
533
|
+
debug("could not get prop name and/or node");
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
Object.entries(replacements[tag]).forEach(([prop, replacement]) => {
|
|
537
|
+
if (scule.kebabCase(prop) === propName) {
|
|
538
|
+
debug(`preparing a replacement for ${tag}:${propName} -> ${replacement}`);
|
|
539
|
+
context.report({
|
|
540
|
+
data: {
|
|
541
|
+
prop,
|
|
542
|
+
replacement
|
|
543
|
+
},
|
|
544
|
+
fix(fixer) {
|
|
545
|
+
return fixer.replaceText(propNameNode, replacement);
|
|
546
|
+
},
|
|
547
|
+
messageId: "replacedWith",
|
|
548
|
+
node: propNameNode
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
},
|
|
555
|
+
defaultOptions: [],
|
|
556
|
+
meta: {
|
|
557
|
+
docs: {
|
|
558
|
+
description: "..."
|
|
559
|
+
},
|
|
560
|
+
fixable: "code",
|
|
561
|
+
messages: {
|
|
562
|
+
replacedWith: `'{{ prop }}' has been replaced with '{{ replacement }}'`
|
|
563
|
+
},
|
|
564
|
+
schema: [],
|
|
565
|
+
type: "problem"
|
|
566
|
+
},
|
|
567
|
+
name: RULE_NAME$1
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
const RULE_NAME = "no-legacy-library-import";
|
|
571
|
+
const legacyLibrary = "@rotki/ui-library-compat";
|
|
572
|
+
const newLibrary = "@rotki/ui-library";
|
|
573
|
+
const noLegacyLibraryImport = createEslintRule({
|
|
574
|
+
create(context) {
|
|
575
|
+
return {
|
|
576
|
+
ImportDeclaration(node) {
|
|
577
|
+
if (!node.source.value.startsWith(legacyLibrary))
|
|
578
|
+
return;
|
|
579
|
+
const replacement = node.source.value.replace(legacyLibrary, newLibrary);
|
|
580
|
+
context.report({
|
|
581
|
+
fix(fixer) {
|
|
582
|
+
return fixer.replaceText(node.source, `'${replacement}'`);
|
|
583
|
+
},
|
|
584
|
+
messageId: "replacedWith",
|
|
585
|
+
node: node.source
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
},
|
|
590
|
+
defaultOptions: [],
|
|
591
|
+
meta: {
|
|
592
|
+
docs: {
|
|
593
|
+
description: `Reports and replaces imports of ${legacyLibrary} with ${newLibrary}`
|
|
594
|
+
},
|
|
595
|
+
fixable: "code",
|
|
596
|
+
messages: {
|
|
597
|
+
replacedWith: `${legacyLibrary} has been replaced by ${newLibrary}`
|
|
598
|
+
},
|
|
599
|
+
schema: [],
|
|
600
|
+
type: "problem"
|
|
601
|
+
},
|
|
370
602
|
name: RULE_NAME
|
|
371
603
|
});
|
|
372
604
|
|
|
@@ -377,28 +609,13 @@ const plugin = {
|
|
|
377
609
|
},
|
|
378
610
|
rules: {
|
|
379
611
|
"no-deprecated-classes": noDeprecatedClasses,
|
|
380
|
-
"no-deprecated-components": noDeprecatedComponents
|
|
612
|
+
"no-deprecated-components": noDeprecatedComponents,
|
|
613
|
+
"no-deprecated-props": noDeprecatedProps,
|
|
614
|
+
"no-legacy-library-import": noLegacyLibraryImport
|
|
381
615
|
}
|
|
382
616
|
};
|
|
383
617
|
const plugin$1 = plugin;
|
|
384
618
|
|
|
385
|
-
function createRecommended(plugin, name, flat) {
|
|
386
|
-
const rules = Object.fromEntries(Object.entries(plugin.rules).filter(([_key, rule]) => rule.meta.recommended === "recommended" && !rule.meta.deprecated).map(([key]) => [`${name}/${key}`, 2]));
|
|
387
|
-
if (flat) {
|
|
388
|
-
return {
|
|
389
|
-
plugins: {
|
|
390
|
-
[name]: plugin
|
|
391
|
-
},
|
|
392
|
-
rules
|
|
393
|
-
};
|
|
394
|
-
} else {
|
|
395
|
-
return {
|
|
396
|
-
plugins: [name],
|
|
397
|
-
rules
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
619
|
const configs = {
|
|
403
620
|
"recommended": createRecommended(plugin$1, "@rotki", false),
|
|
404
621
|
"recommended-flat": createRecommended(plugin$1, "@rotki", true)
|
package/dist/index.d.cts
CHANGED
|
@@ -16,6 +16,8 @@ declare const plugin: {
|
|
|
16
16
|
rules: {
|
|
17
17
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
18
18
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
19
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
20
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
19
21
|
};
|
|
20
22
|
};
|
|
21
23
|
|
|
@@ -27,6 +29,8 @@ declare const _default: {
|
|
|
27
29
|
rules: {
|
|
28
30
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
29
31
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
32
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
33
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
30
34
|
};
|
|
31
35
|
} & {
|
|
32
36
|
configs: {
|
|
@@ -40,6 +44,8 @@ declare const _default: {
|
|
|
40
44
|
rules: {
|
|
41
45
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
42
46
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
47
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
48
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
43
49
|
};
|
|
44
50
|
};
|
|
45
51
|
};
|
|
@@ -62,6 +68,8 @@ declare const _default: {
|
|
|
62
68
|
rules: {
|
|
63
69
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
64
70
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
71
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
72
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
65
73
|
};
|
|
66
74
|
};
|
|
67
75
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -16,6 +16,8 @@ declare const plugin: {
|
|
|
16
16
|
rules: {
|
|
17
17
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
18
18
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
19
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
20
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
19
21
|
};
|
|
20
22
|
};
|
|
21
23
|
|
|
@@ -27,6 +29,8 @@ declare const _default: {
|
|
|
27
29
|
rules: {
|
|
28
30
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
29
31
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
32
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
33
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
30
34
|
};
|
|
31
35
|
} & {
|
|
32
36
|
configs: {
|
|
@@ -40,6 +44,8 @@ declare const _default: {
|
|
|
40
44
|
rules: {
|
|
41
45
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
42
46
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
47
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
48
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
43
49
|
};
|
|
44
50
|
};
|
|
45
51
|
};
|
|
@@ -62,6 +68,8 @@ declare const _default: {
|
|
|
62
68
|
rules: {
|
|
63
69
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
64
70
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
71
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
72
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
65
73
|
};
|
|
66
74
|
};
|
|
67
75
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ declare const plugin: {
|
|
|
16
16
|
rules: {
|
|
17
17
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
18
18
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
19
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
20
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
19
21
|
};
|
|
20
22
|
};
|
|
21
23
|
|
|
@@ -27,6 +29,8 @@ declare const _default: {
|
|
|
27
29
|
rules: {
|
|
28
30
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
29
31
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
32
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
33
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
30
34
|
};
|
|
31
35
|
} & {
|
|
32
36
|
configs: {
|
|
@@ -40,6 +44,8 @@ declare const _default: {
|
|
|
40
44
|
rules: {
|
|
41
45
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
42
46
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
47
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
48
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
43
49
|
};
|
|
44
50
|
};
|
|
45
51
|
};
|
|
@@ -62,6 +68,8 @@ declare const _default: {
|
|
|
62
68
|
rules: {
|
|
63
69
|
'no-deprecated-classes': PluginRuleModule<[]>;
|
|
64
70
|
'no-deprecated-components': PluginRuleModule<Options>;
|
|
71
|
+
'no-deprecated-props': PluginRuleModule<[]>;
|
|
72
|
+
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
65
73
|
};
|
|
66
74
|
};
|
|
67
75
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import createDebug from 'debug';
|
|
1
2
|
import { extname } from 'node:path';
|
|
2
3
|
import * as compat from 'eslint-compat-utils';
|
|
3
|
-
import
|
|
4
|
-
import { pascalCase, snakeCase } from 'scule';
|
|
4
|
+
import { pascalCase, snakeCase, kebabCase } from 'scule';
|
|
5
5
|
|
|
6
6
|
const name = "@rotki/eslint-plugin";
|
|
7
|
-
const version = "0.1
|
|
8
|
-
const packageManager = "pnpm@8.14.
|
|
7
|
+
const version = "0.2.1";
|
|
8
|
+
const packageManager = "pnpm@8.14.3";
|
|
9
9
|
const type = "module";
|
|
10
10
|
const license = "AGPL-3.0";
|
|
11
11
|
const bugs = {
|
|
@@ -51,25 +51,26 @@ const peerDependencies = {
|
|
|
51
51
|
eslint: "^8.0.0 || ^9.0.0"
|
|
52
52
|
};
|
|
53
53
|
const dependencies = {
|
|
54
|
-
"@typescript-eslint/utils": "6.19.
|
|
54
|
+
"@typescript-eslint/utils": "6.19.1",
|
|
55
55
|
debug: "4.3.4",
|
|
56
56
|
"eslint-compat-utils": "0.4.1",
|
|
57
57
|
"jsonc-eslint-parser": "2.4.0",
|
|
58
58
|
scule: "1.2.0",
|
|
59
|
-
"vue-eslint-parser": "9.4.
|
|
59
|
+
"vue-eslint-parser": "9.4.2",
|
|
60
60
|
"yaml-eslint-parser": "1.2.2"
|
|
61
61
|
};
|
|
62
62
|
const devDependencies = {
|
|
63
63
|
"@commitlint/cli": "18.5.0",
|
|
64
64
|
"@commitlint/config-conventional": "18.5.0",
|
|
65
|
-
"@rotki/eslint-config": "2.
|
|
65
|
+
"@rotki/eslint-config": "2.4.1",
|
|
66
66
|
"@types/debug": "4.1.12",
|
|
67
67
|
"@types/eslint": "8.56.2",
|
|
68
68
|
"@types/node": "20",
|
|
69
|
-
"@typescript-eslint/eslint-plugin": "6.19.
|
|
70
|
-
"@typescript-eslint/parser": "6.19.
|
|
71
|
-
"@typescript-eslint/rule-tester": "6.19.
|
|
69
|
+
"@typescript-eslint/eslint-plugin": "6.19.1",
|
|
70
|
+
"@typescript-eslint/parser": "6.19.1",
|
|
71
|
+
"@typescript-eslint/rule-tester": "6.19.1",
|
|
72
72
|
bumpp: "9.3.0",
|
|
73
|
+
debug: "4.3.4",
|
|
73
74
|
eslint: "8.56.0",
|
|
74
75
|
husky: "8.0.3",
|
|
75
76
|
"lint-staged": "15.2.0",
|
|
@@ -176,8 +177,65 @@ function defineTemplateBodyVisitor(context, templateBodyVisitor, scriptVisitor,
|
|
|
176
177
|
);
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
function getStringLiteralValue(node, stringOnly = false) {
|
|
181
|
+
if (node.type === "Literal") {
|
|
182
|
+
if (node.value == null) {
|
|
183
|
+
if (!stringOnly && node.bigint != null)
|
|
184
|
+
return node.bigint;
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
if (typeof node.value === "string")
|
|
188
|
+
return node.value;
|
|
189
|
+
if (!stringOnly)
|
|
190
|
+
return String(node.value);
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if (node.type === "TemplateLiteral" && node.expressions.length === 0 && node.quasis.length === 1)
|
|
194
|
+
return node.quasis[0].value.cooked;
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
function getStaticPropertyName(node) {
|
|
198
|
+
if (node.type === "Property" || node.type === "MethodDefinition") {
|
|
199
|
+
if (!node.computed) {
|
|
200
|
+
const key2 = node.key;
|
|
201
|
+
if (key2.type === "Identifier")
|
|
202
|
+
return key2.name;
|
|
203
|
+
}
|
|
204
|
+
const key = node.key;
|
|
205
|
+
return getStringLiteralValue(key);
|
|
206
|
+
} else if (node.type === "MemberExpression") {
|
|
207
|
+
if (!node.computed) {
|
|
208
|
+
const property2 = node.property;
|
|
209
|
+
if (property2.type === "Identifier")
|
|
210
|
+
return property2.name;
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
const property = node.property;
|
|
214
|
+
return getStringLiteralValue(property);
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function createRecommended(plugin, name, flat) {
|
|
220
|
+
const rules = Object.fromEntries(Object.entries(plugin.rules).filter(([_key, rule]) => rule.meta.recommended === "recommended" && !rule.meta.deprecated).map(([key]) => [`${name}/${key}`, 2]));
|
|
221
|
+
if (flat) {
|
|
222
|
+
return {
|
|
223
|
+
plugins: {
|
|
224
|
+
[name]: plugin
|
|
225
|
+
},
|
|
226
|
+
rules
|
|
227
|
+
};
|
|
228
|
+
} else {
|
|
229
|
+
return {
|
|
230
|
+
plugins: [name],
|
|
231
|
+
rules
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const RULE_NAME$3 = "no-deprecated-classes";
|
|
237
|
+
const debug$2 = createDebug("@rotki/eslint-plugin:no-deprecated-classes");
|
|
238
|
+
const replacements$2 = [
|
|
181
239
|
["d-block", "block"],
|
|
182
240
|
["d-flex", "flex"],
|
|
183
241
|
["flex-column", "flex-col"],
|
|
@@ -206,51 +264,122 @@ function isString(replacement) {
|
|
|
206
264
|
function isRegex(replacement) {
|
|
207
265
|
return replacement[0] instanceof RegExp;
|
|
208
266
|
}
|
|
267
|
+
function findReplacement(className) {
|
|
268
|
+
for (const replacement of replacements$2) {
|
|
269
|
+
if (isString(replacement) && replacement[0] === className)
|
|
270
|
+
return replacement[1];
|
|
271
|
+
if (isRegex(replacement)) {
|
|
272
|
+
const matches = (replacement[0].exec(className) || []).slice(1);
|
|
273
|
+
const replace = replacement[1];
|
|
274
|
+
if (matches.length > 0 && typeof replace === "function")
|
|
275
|
+
return replace(matches);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return void 0;
|
|
279
|
+
}
|
|
280
|
+
function getRange(node) {
|
|
281
|
+
if (node.type === "VAttribute" && node.value && node.value.range)
|
|
282
|
+
return node.value.range;
|
|
283
|
+
return node.range;
|
|
284
|
+
}
|
|
285
|
+
function reportReplacement(className, replacement, node, context, position = 1) {
|
|
286
|
+
debug$2(`found replacement ${replacement} for ${className}`);
|
|
287
|
+
const source = getSourceCode(context);
|
|
288
|
+
const initialRange = getRange(node);
|
|
289
|
+
const range = [
|
|
290
|
+
initialRange[0] + position,
|
|
291
|
+
initialRange[0] + position + className.length
|
|
292
|
+
];
|
|
293
|
+
const loc = {
|
|
294
|
+
end: source.getLocFromIndex(range[1]),
|
|
295
|
+
start: source.getLocFromIndex(range[0])
|
|
296
|
+
};
|
|
297
|
+
context.report({
|
|
298
|
+
data: {
|
|
299
|
+
className,
|
|
300
|
+
replacement
|
|
301
|
+
},
|
|
302
|
+
fix(fixer) {
|
|
303
|
+
return fixer.replaceTextRange(range, replacement);
|
|
304
|
+
},
|
|
305
|
+
loc,
|
|
306
|
+
messageId: "replacedWith"
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
function* extractClassNames(node, textOnly = false) {
|
|
310
|
+
if (node.type === "Literal") {
|
|
311
|
+
const classNames = `${node.value}`;
|
|
312
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: node }));
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (node.type === "TemplateLiteral") {
|
|
316
|
+
for (const templateElement of node.quasis) {
|
|
317
|
+
const classNames = templateElement.value.cooked;
|
|
318
|
+
if (classNames === null)
|
|
319
|
+
continue;
|
|
320
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: templateElement }));
|
|
321
|
+
}
|
|
322
|
+
for (const expr of node.expressions)
|
|
323
|
+
yield* extractClassNames(expr, true);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (node.type === "BinaryExpression") {
|
|
327
|
+
if (node.operator !== "+")
|
|
328
|
+
return;
|
|
329
|
+
yield* extractClassNames(node.left, true);
|
|
330
|
+
yield* extractClassNames(node.right, true);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (textOnly)
|
|
334
|
+
return;
|
|
335
|
+
if (node.type === "ObjectExpression") {
|
|
336
|
+
for (const prop of node.properties) {
|
|
337
|
+
if (prop.type !== "Property")
|
|
338
|
+
continue;
|
|
339
|
+
const classNames = getStaticPropertyName(prop);
|
|
340
|
+
if (!classNames)
|
|
341
|
+
continue;
|
|
342
|
+
yield* classNames.split(/\s+/).map((className) => ({ className, position: classNames.indexOf(className) + 1, reportNode: prop.key }));
|
|
343
|
+
}
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (node.type === "ArrayExpression") {
|
|
347
|
+
for (const element of node.elements) {
|
|
348
|
+
if (element == null)
|
|
349
|
+
continue;
|
|
350
|
+
if (element.type === "SpreadElement")
|
|
351
|
+
continue;
|
|
352
|
+
yield* extractClassNames(element);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (node.type === "ConditionalExpression") {
|
|
356
|
+
yield* extractClassNames(node.consequent);
|
|
357
|
+
yield* extractClassNames(node.alternate);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
209
360
|
const noDeprecatedClasses = createEslintRule({
|
|
210
361
|
create(context) {
|
|
211
362
|
return defineTemplateBodyVisitor(context, {
|
|
212
|
-
'VAttribute[key.name="class"]': function(node) {
|
|
363
|
+
'VAttribute[directive=false][key.name="class"]': function(node) {
|
|
213
364
|
if (!node.value || !node.value.value)
|
|
214
365
|
return;
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return;
|
|
233
|
-
const idx = node.value.value.indexOf(replacement[0]) + 1;
|
|
234
|
-
const range = [
|
|
235
|
-
node.value.range[0] + idx,
|
|
236
|
-
node.value.range[0] + idx + replacement[0].length
|
|
237
|
-
];
|
|
238
|
-
const loc = {
|
|
239
|
-
end: source.getLocFromIndex(range[1]),
|
|
240
|
-
start: source.getLocFromIndex(range[0])
|
|
241
|
-
};
|
|
242
|
-
context.report({
|
|
243
|
-
data: {
|
|
244
|
-
a: replacement[0],
|
|
245
|
-
b: replacement[1]
|
|
246
|
-
},
|
|
247
|
-
fix(fixer) {
|
|
248
|
-
return fixer.replaceTextRange(range, replacement[1]);
|
|
249
|
-
},
|
|
250
|
-
loc,
|
|
251
|
-
messageId: "replacedWith"
|
|
252
|
-
});
|
|
253
|
-
});
|
|
366
|
+
for (const className of node.value.value.split(/\s+/).filter((s) => !!s)) {
|
|
367
|
+
const replacement = findReplacement(className);
|
|
368
|
+
const position = node.value.value.indexOf(className) + 1;
|
|
369
|
+
if (!replacement)
|
|
370
|
+
continue;
|
|
371
|
+
reportReplacement(className, replacement, node, context, position);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
"VAttribute[directive=true][key.name.name='bind'][key.argument.name='class'] > VExpressionContainer.value": function(node) {
|
|
375
|
+
if (!node.expression)
|
|
376
|
+
return;
|
|
377
|
+
for (const { className, position, reportNode } of extractClassNames(node.expression)) {
|
|
378
|
+
const replacement = findReplacement(className);
|
|
379
|
+
if (!replacement)
|
|
380
|
+
continue;
|
|
381
|
+
reportReplacement(className, replacement, reportNode, context, position);
|
|
382
|
+
}
|
|
254
383
|
}
|
|
255
384
|
});
|
|
256
385
|
},
|
|
@@ -262,25 +391,25 @@ const noDeprecatedClasses = createEslintRule({
|
|
|
262
391
|
},
|
|
263
392
|
fixable: "code",
|
|
264
393
|
messages: {
|
|
265
|
-
replacedWith: `'{{
|
|
394
|
+
replacedWith: `'{{ className }}' has been replaced with '{{ replacement }}'`
|
|
266
395
|
},
|
|
267
396
|
schema: [],
|
|
268
397
|
type: "problem"
|
|
269
398
|
},
|
|
270
|
-
name: RULE_NAME$
|
|
399
|
+
name: RULE_NAME$3
|
|
271
400
|
});
|
|
272
401
|
|
|
273
|
-
const debug = createDebug("@rotki/eslint-plugin:no-deprecated-components");
|
|
274
|
-
const RULE_NAME = "no-deprecated-components";
|
|
275
|
-
const replacements = {
|
|
402
|
+
const debug$1 = createDebug("@rotki/eslint-plugin:no-deprecated-components");
|
|
403
|
+
const RULE_NAME$2 = "no-deprecated-components";
|
|
404
|
+
const replacements$1 = {
|
|
276
405
|
DataTable: true,
|
|
277
406
|
Fragment: false
|
|
278
407
|
};
|
|
279
408
|
const skipInLegacy = [
|
|
280
409
|
"Fragment"
|
|
281
410
|
];
|
|
282
|
-
function hasReplacement(tag) {
|
|
283
|
-
return Object.prototype.hasOwnProperty.call(replacements, tag);
|
|
411
|
+
function hasReplacement$1(tag) {
|
|
412
|
+
return Object.prototype.hasOwnProperty.call(replacements$1, tag);
|
|
284
413
|
}
|
|
285
414
|
const noDeprecatedComponents = createEslintRule({
|
|
286
415
|
create(context, optionsWithDefault) {
|
|
@@ -292,11 +421,11 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
292
421
|
const sourceCode = getSourceCode(context);
|
|
293
422
|
if (!("getTemplateBodyTokenStore" in sourceCode.parserServices))
|
|
294
423
|
throw new Error("cannot find getTemplateBodyTokenStore in parserServices");
|
|
295
|
-
if (!hasReplacement(tag))
|
|
424
|
+
if (!hasReplacement$1(tag))
|
|
296
425
|
return;
|
|
297
|
-
const replacement = replacements[tag];
|
|
426
|
+
const replacement = replacements$1[tag];
|
|
298
427
|
if (replacement || legacy && skipInLegacy.includes(tag)) {
|
|
299
|
-
debug(`${tag} has been deprecated`);
|
|
428
|
+
debug$1(`${tag} has been deprecated`);
|
|
300
429
|
context.report({
|
|
301
430
|
data: {
|
|
302
431
|
name: snakeCase(tag)
|
|
@@ -305,7 +434,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
305
434
|
node: element
|
|
306
435
|
});
|
|
307
436
|
} else {
|
|
308
|
-
debug(`${tag} has will be removed`);
|
|
437
|
+
debug$1(`${tag} has will be removed`);
|
|
309
438
|
context.report({
|
|
310
439
|
data: {
|
|
311
440
|
name: snakeCase(tag)
|
|
@@ -348,6 +477,109 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
348
477
|
],
|
|
349
478
|
type: "problem"
|
|
350
479
|
},
|
|
480
|
+
name: RULE_NAME$2
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
const debug = createDebug("@rotki/eslint-plugin:no-deprecated-props");
|
|
484
|
+
const RULE_NAME$1 = "no-deprecated-props";
|
|
485
|
+
const replacements = {
|
|
486
|
+
RuiRadio: {
|
|
487
|
+
internalValue: "value"
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
function hasReplacement(tag) {
|
|
491
|
+
return Object.prototype.hasOwnProperty.call(replacements, tag);
|
|
492
|
+
}
|
|
493
|
+
function getPropName(node) {
|
|
494
|
+
if (node.directive) {
|
|
495
|
+
if (node.key.argument?.type !== "VIdentifier")
|
|
496
|
+
return void 0;
|
|
497
|
+
return kebabCase(node.key.argument.rawName);
|
|
498
|
+
}
|
|
499
|
+
return kebabCase(node.key.rawName);
|
|
500
|
+
}
|
|
501
|
+
const noDeprecatedProps = createEslintRule({
|
|
502
|
+
create(context) {
|
|
503
|
+
return defineTemplateBodyVisitor(context, {
|
|
504
|
+
VAttribute(node) {
|
|
505
|
+
if (node.directive && (node.value?.type === "VExpressionContainer" && (node.key.name.name !== "bind" || !node.key.argument)))
|
|
506
|
+
return;
|
|
507
|
+
const tag = pascalCase(node.parent.parent.rawName);
|
|
508
|
+
if (!hasReplacement(tag))
|
|
509
|
+
return;
|
|
510
|
+
debug(`${tag} has replacement properties`);
|
|
511
|
+
const propName = getPropName(node);
|
|
512
|
+
const propNameNode = node.directive ? node.key.argument : node.key;
|
|
513
|
+
if (!propName || !propNameNode) {
|
|
514
|
+
debug("could not get prop name and/or node");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
Object.entries(replacements[tag]).forEach(([prop, replacement]) => {
|
|
518
|
+
if (kebabCase(prop) === propName) {
|
|
519
|
+
debug(`preparing a replacement for ${tag}:${propName} -> ${replacement}`);
|
|
520
|
+
context.report({
|
|
521
|
+
data: {
|
|
522
|
+
prop,
|
|
523
|
+
replacement
|
|
524
|
+
},
|
|
525
|
+
fix(fixer) {
|
|
526
|
+
return fixer.replaceText(propNameNode, replacement);
|
|
527
|
+
},
|
|
528
|
+
messageId: "replacedWith",
|
|
529
|
+
node: propNameNode
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
},
|
|
536
|
+
defaultOptions: [],
|
|
537
|
+
meta: {
|
|
538
|
+
docs: {
|
|
539
|
+
description: "..."
|
|
540
|
+
},
|
|
541
|
+
fixable: "code",
|
|
542
|
+
messages: {
|
|
543
|
+
replacedWith: `'{{ prop }}' has been replaced with '{{ replacement }}'`
|
|
544
|
+
},
|
|
545
|
+
schema: [],
|
|
546
|
+
type: "problem"
|
|
547
|
+
},
|
|
548
|
+
name: RULE_NAME$1
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
const RULE_NAME = "no-legacy-library-import";
|
|
552
|
+
const legacyLibrary = "@rotki/ui-library-compat";
|
|
553
|
+
const newLibrary = "@rotki/ui-library";
|
|
554
|
+
const noLegacyLibraryImport = createEslintRule({
|
|
555
|
+
create(context) {
|
|
556
|
+
return {
|
|
557
|
+
ImportDeclaration(node) {
|
|
558
|
+
if (!node.source.value.startsWith(legacyLibrary))
|
|
559
|
+
return;
|
|
560
|
+
const replacement = node.source.value.replace(legacyLibrary, newLibrary);
|
|
561
|
+
context.report({
|
|
562
|
+
fix(fixer) {
|
|
563
|
+
return fixer.replaceText(node.source, `'${replacement}'`);
|
|
564
|
+
},
|
|
565
|
+
messageId: "replacedWith",
|
|
566
|
+
node: node.source
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
},
|
|
571
|
+
defaultOptions: [],
|
|
572
|
+
meta: {
|
|
573
|
+
docs: {
|
|
574
|
+
description: `Reports and replaces imports of ${legacyLibrary} with ${newLibrary}`
|
|
575
|
+
},
|
|
576
|
+
fixable: "code",
|
|
577
|
+
messages: {
|
|
578
|
+
replacedWith: `${legacyLibrary} has been replaced by ${newLibrary}`
|
|
579
|
+
},
|
|
580
|
+
schema: [],
|
|
581
|
+
type: "problem"
|
|
582
|
+
},
|
|
351
583
|
name: RULE_NAME
|
|
352
584
|
});
|
|
353
585
|
|
|
@@ -358,28 +590,13 @@ const plugin = {
|
|
|
358
590
|
},
|
|
359
591
|
rules: {
|
|
360
592
|
"no-deprecated-classes": noDeprecatedClasses,
|
|
361
|
-
"no-deprecated-components": noDeprecatedComponents
|
|
593
|
+
"no-deprecated-components": noDeprecatedComponents,
|
|
594
|
+
"no-deprecated-props": noDeprecatedProps,
|
|
595
|
+
"no-legacy-library-import": noLegacyLibraryImport
|
|
362
596
|
}
|
|
363
597
|
};
|
|
364
598
|
const plugin$1 = plugin;
|
|
365
599
|
|
|
366
|
-
function createRecommended(plugin, name, flat) {
|
|
367
|
-
const rules = Object.fromEntries(Object.entries(plugin.rules).filter(([_key, rule]) => rule.meta.recommended === "recommended" && !rule.meta.deprecated).map(([key]) => [`${name}/${key}`, 2]));
|
|
368
|
-
if (flat) {
|
|
369
|
-
return {
|
|
370
|
-
plugins: {
|
|
371
|
-
[name]: plugin
|
|
372
|
-
},
|
|
373
|
-
rules
|
|
374
|
-
};
|
|
375
|
-
} else {
|
|
376
|
-
return {
|
|
377
|
-
plugins: [name],
|
|
378
|
-
rules
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
600
|
const configs = {
|
|
384
601
|
"recommended": createRecommended(plugin$1, "@rotki", false),
|
|
385
602
|
"recommended-flat": createRecommended(plugin$1, "@rotki", true)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotki/eslint-plugin",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"packageManager": "pnpm@8.14.
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"packageManager": "pnpm@8.14.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
7
7
|
"bugs": {
|
|
@@ -30,25 +30,26 @@
|
|
|
30
30
|
"eslint": "^8.0.0 || ^9.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@typescript-eslint/utils": "6.19.
|
|
33
|
+
"@typescript-eslint/utils": "6.19.1",
|
|
34
34
|
"debug": "4.3.4",
|
|
35
35
|
"eslint-compat-utils": "0.4.1",
|
|
36
36
|
"jsonc-eslint-parser": "2.4.0",
|
|
37
37
|
"scule": "1.2.0",
|
|
38
|
-
"vue-eslint-parser": "9.4.
|
|
38
|
+
"vue-eslint-parser": "9.4.2",
|
|
39
39
|
"yaml-eslint-parser": "1.2.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@commitlint/cli": "18.5.0",
|
|
43
43
|
"@commitlint/config-conventional": "18.5.0",
|
|
44
|
-
"@rotki/eslint-config": "2.
|
|
44
|
+
"@rotki/eslint-config": "2.4.1",
|
|
45
45
|
"@types/debug": "4.1.12",
|
|
46
46
|
"@types/eslint": "8.56.2",
|
|
47
47
|
"@types/node": "20",
|
|
48
|
-
"@typescript-eslint/eslint-plugin": "6.19.
|
|
49
|
-
"@typescript-eslint/parser": "6.19.
|
|
50
|
-
"@typescript-eslint/rule-tester": "6.19.
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "6.19.1",
|
|
49
|
+
"@typescript-eslint/parser": "6.19.1",
|
|
50
|
+
"@typescript-eslint/rule-tester": "6.19.1",
|
|
51
51
|
"bumpp": "9.3.0",
|
|
52
|
+
"debug": "4.3.4",
|
|
52
53
|
"eslint": "8.56.0",
|
|
53
54
|
"husky": "8.0.3",
|
|
54
55
|
"lint-staged": "15.2.0",
|