@rotki/eslint-plugin 1.4.0 → 1.5.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/dist/index.d.mts +22 -9
- package/dist/index.d.ts +22 -9
- package/dist/index.mjs +234 -62
- package/package.json +19 -19
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ interface PluginRuleModule<TOptions extends readonly unknown[] = []> extends Rul
|
|
|
4
4
|
defaultOptions: TOptions;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
type Options$
|
|
7
|
+
type Options$7 = [
|
|
8
8
|
{
|
|
9
9
|
extensions: string[];
|
|
10
10
|
ignoreKeys: string[];
|
|
@@ -12,6 +12,11 @@ type Options$6 = [
|
|
|
12
12
|
}
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
+
interface Options$6 {
|
|
16
|
+
factories: string[];
|
|
17
|
+
testFilePattern: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
type Options$5 = [{
|
|
16
21
|
legacy: boolean;
|
|
17
22
|
}];
|
|
@@ -59,7 +64,8 @@ declare const plugin: {
|
|
|
59
64
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
60
65
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
61
66
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
62
|
-
'no-
|
|
67
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
68
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
63
69
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
64
70
|
};
|
|
65
71
|
};
|
|
@@ -85,7 +91,8 @@ declare const _default: {
|
|
|
85
91
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
86
92
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
87
93
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
88
|
-
'no-
|
|
94
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
95
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
89
96
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
90
97
|
};
|
|
91
98
|
} & {
|
|
@@ -113,7 +120,8 @@ declare const _default: {
|
|
|
113
120
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
114
121
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
115
122
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
116
|
-
'no-
|
|
123
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
124
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
117
125
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
118
126
|
};
|
|
119
127
|
};
|
|
@@ -150,7 +158,8 @@ declare const _default: {
|
|
|
150
158
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
151
159
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
152
160
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
153
|
-
'no-
|
|
161
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
162
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
154
163
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
155
164
|
};
|
|
156
165
|
};
|
|
@@ -187,7 +196,8 @@ declare const _default: {
|
|
|
187
196
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
188
197
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
189
198
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
190
|
-
'no-
|
|
199
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
200
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
191
201
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
192
202
|
};
|
|
193
203
|
};
|
|
@@ -224,7 +234,8 @@ declare const _default: {
|
|
|
224
234
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
225
235
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
226
236
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
227
|
-
'no-
|
|
237
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
238
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
228
239
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
229
240
|
};
|
|
230
241
|
};
|
|
@@ -261,7 +272,8 @@ declare const _default: {
|
|
|
261
272
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
262
273
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
263
274
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
264
|
-
'no-
|
|
275
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
276
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
265
277
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
266
278
|
};
|
|
267
279
|
};
|
|
@@ -298,7 +310,8 @@ declare const _default: {
|
|
|
298
310
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
299
311
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
300
312
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
301
|
-
'no-
|
|
313
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
314
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
302
315
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
303
316
|
};
|
|
304
317
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ interface PluginRuleModule<TOptions extends readonly unknown[] = []> extends Rul
|
|
|
4
4
|
defaultOptions: TOptions;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
type Options$
|
|
7
|
+
type Options$7 = [
|
|
8
8
|
{
|
|
9
9
|
extensions: string[];
|
|
10
10
|
ignoreKeys: string[];
|
|
@@ -12,6 +12,11 @@ type Options$6 = [
|
|
|
12
12
|
}
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
+
interface Options$6 {
|
|
16
|
+
factories: string[];
|
|
17
|
+
testFilePattern: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
type Options$5 = [{
|
|
16
21
|
legacy: boolean;
|
|
17
22
|
}];
|
|
@@ -59,7 +64,8 @@ declare const plugin: {
|
|
|
59
64
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
60
65
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
61
66
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
62
|
-
'no-
|
|
67
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
68
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
63
69
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
64
70
|
};
|
|
65
71
|
};
|
|
@@ -85,7 +91,8 @@ declare const _default: {
|
|
|
85
91
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
86
92
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
87
93
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
88
|
-
'no-
|
|
94
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
95
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
89
96
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
90
97
|
};
|
|
91
98
|
} & {
|
|
@@ -113,7 +120,8 @@ declare const _default: {
|
|
|
113
120
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
114
121
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
115
122
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
116
|
-
'no-
|
|
123
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
124
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
117
125
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
118
126
|
};
|
|
119
127
|
};
|
|
@@ -150,7 +158,8 @@ declare const _default: {
|
|
|
150
158
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
151
159
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
152
160
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
153
|
-
'no-
|
|
161
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
162
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
154
163
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
155
164
|
};
|
|
156
165
|
};
|
|
@@ -187,7 +196,8 @@ declare const _default: {
|
|
|
187
196
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
188
197
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
189
198
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
190
|
-
'no-
|
|
199
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
200
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
191
201
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
192
202
|
};
|
|
193
203
|
};
|
|
@@ -224,7 +234,8 @@ declare const _default: {
|
|
|
224
234
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
225
235
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
226
236
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
227
|
-
'no-
|
|
237
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
238
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
228
239
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
229
240
|
};
|
|
230
241
|
};
|
|
@@ -261,7 +272,8 @@ declare const _default: {
|
|
|
261
272
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
262
273
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
263
274
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
264
|
-
'no-
|
|
275
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
276
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
265
277
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
266
278
|
};
|
|
267
279
|
};
|
|
@@ -298,7 +310,8 @@ declare const _default: {
|
|
|
298
310
|
'no-dot-ts-imports': PluginRuleModule<[]>;
|
|
299
311
|
'no-legacy-library-import': PluginRuleModule<[]>;
|
|
300
312
|
'no-redundant-flex-row': PluginRuleModule<[]>;
|
|
301
|
-
'no-
|
|
313
|
+
'no-shared-pinia': PluginRuleModule<[Options$6]>;
|
|
314
|
+
'no-unused-i18n-keys': PluginRuleModule<Options$7>;
|
|
302
315
|
'require-jsdoc-on-composable-options': PluginRuleModule<[]>;
|
|
303
316
|
};
|
|
304
317
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { statSync, readFileSync } from 'node:fs';
|
|
|
6
6
|
import { globSync } from 'tinyglobby';
|
|
7
7
|
import { parse } from 'vue-eslint-parser';
|
|
8
8
|
|
|
9
|
-
const version = "1.
|
|
9
|
+
const version = "1.5.0";
|
|
10
10
|
const pkg = {
|
|
11
11
|
version: version};
|
|
12
12
|
|
|
@@ -127,13 +127,13 @@ function createRule({
|
|
|
127
127
|
meta
|
|
128
128
|
}) {
|
|
129
129
|
return {
|
|
130
|
-
create: (
|
|
130
|
+
create: (context) => {
|
|
131
131
|
const optionsWithDefault = context.options.map((options, index) => ({
|
|
132
132
|
...defaultOptions[index] || {},
|
|
133
133
|
...options || {}
|
|
134
134
|
}));
|
|
135
135
|
return create(context, optionsWithDefault);
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
137
|
defaultOptions,
|
|
138
138
|
meta
|
|
139
139
|
};
|
|
@@ -164,7 +164,7 @@ function defineTemplateBodyVisitor(context, templateBodyVisitor, scriptVisitor,
|
|
|
164
164
|
);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
const RULE_NAME$
|
|
167
|
+
const RULE_NAME$h = "composable-input-flexibility";
|
|
168
168
|
function checkParamForRef(param) {
|
|
169
169
|
let annotation;
|
|
170
170
|
if (param.type === AST_NODE_TYPES.Identifier && param.typeAnnotation) {
|
|
@@ -177,44 +177,73 @@ function checkParamForRef(param) {
|
|
|
177
177
|
}
|
|
178
178
|
return void 0;
|
|
179
179
|
}
|
|
180
|
+
function getParamName(param) {
|
|
181
|
+
if (param.type === AST_NODE_TYPES.Identifier)
|
|
182
|
+
return param.name;
|
|
183
|
+
if (param.type === AST_NODE_TYPES.AssignmentPattern && param.left.type === AST_NODE_TYPES.Identifier)
|
|
184
|
+
return param.left.name;
|
|
185
|
+
return void 0;
|
|
186
|
+
}
|
|
187
|
+
function isWriteReference(reference) {
|
|
188
|
+
const { identifier } = reference;
|
|
189
|
+
const parent = identifier.parent;
|
|
190
|
+
if (parent.type === AST_NODE_TYPES.CallExpression) {
|
|
191
|
+
return parent.callee.type === AST_NODE_TYPES.Identifier && parent.callee.name === "set" && parent.arguments[0] === identifier;
|
|
192
|
+
}
|
|
193
|
+
if (parent.type === AST_NODE_TYPES.MemberExpression && parent.object === identifier && !parent.computed && parent.property.type === AST_NODE_TYPES.Identifier && parent.property.name === "value") {
|
|
194
|
+
const grandparent = parent.parent;
|
|
195
|
+
if (grandparent.type === AST_NODE_TYPES.AssignmentExpression)
|
|
196
|
+
return grandparent.left === parent;
|
|
197
|
+
return grandparent.type === AST_NODE_TYPES.UpdateExpression;
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
function isWrittenParam(scope, name) {
|
|
202
|
+
const variable = scope.variables.find((candidate) => candidate.name === name);
|
|
203
|
+
return variable?.references.some(isWriteReference) ?? false;
|
|
204
|
+
}
|
|
180
205
|
const composableInputFlexibility = createEslintRule({
|
|
181
206
|
create(context) {
|
|
182
207
|
const autofix = context.options[0]?.autofix ?? false;
|
|
183
208
|
return {
|
|
184
209
|
FunctionDeclaration: (node) => {
|
|
185
|
-
if (!node.id || !isComposableName(node.id.name))
|
|
210
|
+
if (!node.id || !isComposableName(node.id.name) || !node.body)
|
|
186
211
|
return;
|
|
187
|
-
checkParams(node.params);
|
|
212
|
+
checkParams(node.params, node);
|
|
188
213
|
},
|
|
189
214
|
VariableDeclarator: (node) => {
|
|
190
215
|
if (node.id.type !== AST_NODE_TYPES.Identifier || !isComposableName(node.id.name))
|
|
191
216
|
return;
|
|
192
217
|
if (node.init?.type === AST_NODE_TYPES.ArrowFunctionExpression || node.init?.type === AST_NODE_TYPES.FunctionExpression) {
|
|
193
|
-
checkParams(node.init.params);
|
|
218
|
+
checkParams(node.init.params, node.init);
|
|
194
219
|
}
|
|
195
220
|
}
|
|
196
221
|
};
|
|
197
|
-
function checkParams(params) {
|
|
222
|
+
function checkParams(params, fn) {
|
|
223
|
+
const scope = context.sourceCode.getScope(fn);
|
|
198
224
|
for (const param of params) {
|
|
199
225
|
const refType = checkParamForRef(param);
|
|
200
|
-
if (refType)
|
|
201
|
-
|
|
202
|
-
|
|
226
|
+
if (!refType)
|
|
227
|
+
continue;
|
|
228
|
+
const name = getParamName(param);
|
|
229
|
+
if (name && isWrittenParam(scope, name))
|
|
230
|
+
continue;
|
|
231
|
+
context.report({
|
|
232
|
+
...autofix ? {
|
|
233
|
+
fix(fixer) {
|
|
234
|
+
return fixer.replaceText(refType.typeName, "MaybeRefOrGetter");
|
|
235
|
+
}
|
|
236
|
+
} : {
|
|
237
|
+
suggest: [{
|
|
203
238
|
fix(fixer) {
|
|
204
239
|
return fixer.replaceText(refType.typeName, "MaybeRefOrGetter");
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}]
|
|
213
|
-
},
|
|
214
|
-
messageId: "preferMaybeRefOrGetter",
|
|
215
|
-
node: refType
|
|
216
|
-
});
|
|
217
|
-
}
|
|
240
|
+
},
|
|
241
|
+
messageId: "suggestMaybeRefOrGetter"
|
|
242
|
+
}]
|
|
243
|
+
},
|
|
244
|
+
messageId: "preferMaybeRefOrGetter",
|
|
245
|
+
node: refType
|
|
246
|
+
});
|
|
218
247
|
}
|
|
219
248
|
}
|
|
220
249
|
},
|
|
@@ -245,10 +274,10 @@ const composableInputFlexibility = createEslintRule({
|
|
|
245
274
|
],
|
|
246
275
|
type: "suggestion"
|
|
247
276
|
},
|
|
248
|
-
name: RULE_NAME$
|
|
277
|
+
name: RULE_NAME$h
|
|
249
278
|
});
|
|
250
279
|
|
|
251
|
-
const RULE_NAME$
|
|
280
|
+
const RULE_NAME$g = "composable-naming-convention";
|
|
252
281
|
function getComposableFunction(node) {
|
|
253
282
|
if (node.type === AST_NODE_TYPES.FunctionDeclaration) {
|
|
254
283
|
if (!node.id || !isComposableName(node.id.name))
|
|
@@ -321,10 +350,10 @@ const composableNamingConvention = createEslintRule({
|
|
|
321
350
|
schema: [],
|
|
322
351
|
type: "suggestion"
|
|
323
352
|
},
|
|
324
|
-
name: RULE_NAME$
|
|
353
|
+
name: RULE_NAME$g
|
|
325
354
|
});
|
|
326
355
|
|
|
327
|
-
const RULE_NAME$
|
|
356
|
+
const RULE_NAME$f = "composable-no-default-export";
|
|
328
357
|
const composableNoDefaultExport = createEslintRule({
|
|
329
358
|
create(context) {
|
|
330
359
|
let hasComposable = false;
|
|
@@ -364,10 +393,10 @@ const composableNoDefaultExport = createEslintRule({
|
|
|
364
393
|
schema: [],
|
|
365
394
|
type: "problem"
|
|
366
395
|
},
|
|
367
|
-
name: RULE_NAME$
|
|
396
|
+
name: RULE_NAME$f
|
|
368
397
|
});
|
|
369
398
|
|
|
370
|
-
const RULE_NAME$
|
|
399
|
+
const RULE_NAME$e = "composable-prefer-shallowref";
|
|
371
400
|
const composablePreferShallowref = createEslintRule({
|
|
372
401
|
create(context) {
|
|
373
402
|
const autofix = context.options[0]?.autofix ?? false;
|
|
@@ -426,10 +455,10 @@ const composablePreferShallowref = createEslintRule({
|
|
|
426
455
|
],
|
|
427
456
|
type: "suggestion"
|
|
428
457
|
},
|
|
429
|
-
name: RULE_NAME$
|
|
458
|
+
name: RULE_NAME$e
|
|
430
459
|
});
|
|
431
460
|
|
|
432
|
-
const RULE_NAME$
|
|
461
|
+
const RULE_NAME$d = "composable-require-cleanup";
|
|
433
462
|
const SIDE_EFFECT_CALLS = /* @__PURE__ */ new Set(["addEventListener", "setInterval", "setTimeout"]);
|
|
434
463
|
const SIDE_EFFECT_CONSTRUCTORS = /* @__PURE__ */ new Set(["MutationObserver", "ResizeObserver", "IntersectionObserver"]);
|
|
435
464
|
const CLEANUP_HOOKS = /* @__PURE__ */ new Set(["onUnmounted", "onBeforeUnmount", "onScopeDispose", "tryOnScopeDispose"]);
|
|
@@ -523,10 +552,10 @@ const composableRequireCleanup = createEslintRule({
|
|
|
523
552
|
schema: [],
|
|
524
553
|
type: "problem"
|
|
525
554
|
},
|
|
526
|
-
name: RULE_NAME$
|
|
555
|
+
name: RULE_NAME$d
|
|
527
556
|
});
|
|
528
557
|
|
|
529
|
-
const RULE_NAME$
|
|
558
|
+
const RULE_NAME$c = "composable-return-readonly";
|
|
530
559
|
const DEFAULT_WRITABLE_PREFIXES = ["model"];
|
|
531
560
|
const REACTIVE_CREATORS = /* @__PURE__ */ new Set(["ref", "shallowRef"]);
|
|
532
561
|
const READONLY_CREATORS = /* @__PURE__ */ new Set(["computed"]);
|
|
@@ -643,10 +672,10 @@ const composableReturnReadonly = createEslintRule({
|
|
|
643
672
|
],
|
|
644
673
|
type: "suggestion"
|
|
645
674
|
},
|
|
646
|
-
name: RULE_NAME$
|
|
675
|
+
name: RULE_NAME$c
|
|
647
676
|
});
|
|
648
677
|
|
|
649
|
-
const RULE_NAME$
|
|
678
|
+
const RULE_NAME$b = "composable-ssr-safety";
|
|
650
679
|
const BROWSER_GLOBALS = /* @__PURE__ */ new Set(["window", "document", "navigator"]);
|
|
651
680
|
const LIFECYCLE_HOOKS = /* @__PURE__ */ new Set(["onMounted", "onBeforeMount"]);
|
|
652
681
|
function isInsideLifecycleHook(node) {
|
|
@@ -734,11 +763,11 @@ const composableSsrSafety = createEslintRule({
|
|
|
734
763
|
schema: [],
|
|
735
764
|
type: "problem"
|
|
736
765
|
},
|
|
737
|
-
name: RULE_NAME$
|
|
766
|
+
name: RULE_NAME$b
|
|
738
767
|
});
|
|
739
768
|
|
|
740
|
-
const debug$
|
|
741
|
-
const RULE_NAME$
|
|
769
|
+
const debug$7 = debugFactory("@rotki/eslint-plugin:consistent-ref-type-annotation");
|
|
770
|
+
const RULE_NAME$a = "consistent-ref-type-annotation";
|
|
742
771
|
const FIXABLE_METHODS = /* @__PURE__ */ new Set(["ref", "computed"]);
|
|
743
772
|
function getFixableCallExpression(declaration) {
|
|
744
773
|
const init = declaration.init;
|
|
@@ -761,13 +790,13 @@ function checkAssignmentDeclaration(context, source, node, declaration, allowInf
|
|
|
761
790
|
return;
|
|
762
791
|
const { callee, init } = call;
|
|
763
792
|
const name = callee.name;
|
|
764
|
-
debug$
|
|
793
|
+
debug$7(`found ${name}, checking type arguments`);
|
|
765
794
|
const initTypeArgs = init.typeArguments;
|
|
766
795
|
const declTypeArgs = getDeclarationTypeArguments(declaration);
|
|
767
796
|
const typeAnnotation = declaration.id.typeAnnotation;
|
|
768
797
|
if (initTypeArgs && !declTypeArgs)
|
|
769
798
|
return;
|
|
770
|
-
debug$
|
|
799
|
+
debug$7(`generating report for ${name}`);
|
|
771
800
|
if (!initTypeArgs && !declTypeArgs) {
|
|
772
801
|
if (!allowInference)
|
|
773
802
|
context.report({ data: { name }, messageId: "missingType", node });
|
|
@@ -827,10 +856,10 @@ const consistentRefTypeAnnotation = createEslintRule({
|
|
|
827
856
|
],
|
|
828
857
|
type: "problem"
|
|
829
858
|
},
|
|
830
|
-
name: RULE_NAME$
|
|
859
|
+
name: RULE_NAME$a
|
|
831
860
|
});
|
|
832
861
|
|
|
833
|
-
const RULE_NAME$
|
|
862
|
+
const RULE_NAME$9 = "max-dependencies";
|
|
834
863
|
const maxDependencies = createEslintRule({
|
|
835
864
|
create(context, [options]) {
|
|
836
865
|
let dependencyCount = 0;
|
|
@@ -890,11 +919,11 @@ const maxDependencies = createEslintRule({
|
|
|
890
919
|
],
|
|
891
920
|
type: "suggestion"
|
|
892
921
|
},
|
|
893
|
-
name: RULE_NAME$
|
|
922
|
+
name: RULE_NAME$9
|
|
894
923
|
});
|
|
895
924
|
|
|
896
|
-
const RULE_NAME$
|
|
897
|
-
const debug$
|
|
925
|
+
const RULE_NAME$8 = "no-deprecated-classes";
|
|
926
|
+
const debug$6 = debugFactory("@rotki/eslint-plugin:no-deprecated-classes");
|
|
898
927
|
const stringReplacements = /* @__PURE__ */ new Map([
|
|
899
928
|
["d-block", "block"],
|
|
900
929
|
["d-flex", "flex"],
|
|
@@ -948,7 +977,7 @@ function getRange(node) {
|
|
|
948
977
|
return node.range;
|
|
949
978
|
}
|
|
950
979
|
function reportReplacement(className, replacement, node, context, source, position = 1) {
|
|
951
|
-
debug$
|
|
980
|
+
debug$6(`found replacement ${replacement} for ${className}`);
|
|
952
981
|
const initialRange = getRange(node);
|
|
953
982
|
const range = [
|
|
954
983
|
initialRange[0] + position,
|
|
@@ -1072,11 +1101,11 @@ const noDeprecatedClasses = createEslintRule({
|
|
|
1072
1101
|
schema: [],
|
|
1073
1102
|
type: "problem"
|
|
1074
1103
|
},
|
|
1075
|
-
name: RULE_NAME$
|
|
1104
|
+
name: RULE_NAME$8
|
|
1076
1105
|
});
|
|
1077
1106
|
|
|
1078
|
-
const debug$
|
|
1079
|
-
const RULE_NAME$
|
|
1107
|
+
const debug$5 = debugFactory("@rotki/eslint-plugin:no-deprecated-components");
|
|
1108
|
+
const RULE_NAME$7 = "no-deprecated-components";
|
|
1080
1109
|
const vuetify = {
|
|
1081
1110
|
VApp: true,
|
|
1082
1111
|
VAppBar: true,
|
|
@@ -1129,7 +1158,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
1129
1158
|
return;
|
|
1130
1159
|
const replacement = replacements$1[tag];
|
|
1131
1160
|
if (replacement || legacy && skipInLegacy.has(tag)) {
|
|
1132
|
-
debug$
|
|
1161
|
+
debug$5(`${tag} has been deprecated`);
|
|
1133
1162
|
context.report({
|
|
1134
1163
|
data: {
|
|
1135
1164
|
name: tag
|
|
@@ -1138,7 +1167,7 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
1138
1167
|
node: element
|
|
1139
1168
|
});
|
|
1140
1169
|
} else {
|
|
1141
|
-
debug$
|
|
1170
|
+
debug$5(`${tag} has will be removed`);
|
|
1142
1171
|
context.report({
|
|
1143
1172
|
data: {
|
|
1144
1173
|
name: tag
|
|
@@ -1181,10 +1210,10 @@ const noDeprecatedComponents = createEslintRule({
|
|
|
1181
1210
|
],
|
|
1182
1211
|
type: "problem"
|
|
1183
1212
|
},
|
|
1184
|
-
name: RULE_NAME$
|
|
1213
|
+
name: RULE_NAME$7
|
|
1185
1214
|
});
|
|
1186
1215
|
|
|
1187
|
-
const RULE_NAME$
|
|
1216
|
+
const RULE_NAME$6 = "no-deprecated-props";
|
|
1188
1217
|
const replacements = {
|
|
1189
1218
|
RuiRadio: {
|
|
1190
1219
|
internalValue: "value"
|
|
@@ -1251,10 +1280,10 @@ const noDeprecatedProps = createEslintRule({
|
|
|
1251
1280
|
schema: [],
|
|
1252
1281
|
type: "problem"
|
|
1253
1282
|
},
|
|
1254
|
-
name: RULE_NAME$
|
|
1283
|
+
name: RULE_NAME$6
|
|
1255
1284
|
});
|
|
1256
1285
|
|
|
1257
|
-
const RULE_NAME$
|
|
1286
|
+
const RULE_NAME$5 = "no-dot-ts-imports";
|
|
1258
1287
|
const noDotTsImport = createEslintRule({
|
|
1259
1288
|
create(context) {
|
|
1260
1289
|
return {
|
|
@@ -1289,10 +1318,10 @@ const noDotTsImport = createEslintRule({
|
|
|
1289
1318
|
schema: [],
|
|
1290
1319
|
type: "problem"
|
|
1291
1320
|
},
|
|
1292
|
-
name: RULE_NAME$
|
|
1321
|
+
name: RULE_NAME$5
|
|
1293
1322
|
});
|
|
1294
1323
|
|
|
1295
|
-
const RULE_NAME$
|
|
1324
|
+
const RULE_NAME$4 = "no-legacy-library-import";
|
|
1296
1325
|
const legacyLibrary = "@rotki/ui-library-compat";
|
|
1297
1326
|
const newLibrary = "@rotki/ui-library";
|
|
1298
1327
|
const noLegacyLibraryImport = createEslintRule({
|
|
@@ -1325,11 +1354,11 @@ const noLegacyLibraryImport = createEslintRule({
|
|
|
1325
1354
|
schema: [],
|
|
1326
1355
|
type: "problem"
|
|
1327
1356
|
},
|
|
1328
|
-
name: RULE_NAME$
|
|
1357
|
+
name: RULE_NAME$4
|
|
1329
1358
|
});
|
|
1330
1359
|
|
|
1331
|
-
const RULE_NAME$
|
|
1332
|
-
const debug$
|
|
1360
|
+
const RULE_NAME$3 = "no-redundant-flex-row";
|
|
1361
|
+
const debug$4 = debugFactory("@rotki/eslint-plugin:no-redundant-flex-row");
|
|
1333
1362
|
function stripImportant(token) {
|
|
1334
1363
|
return token.replace(/^!/, "").replace(/!$/, "");
|
|
1335
1364
|
}
|
|
@@ -1374,7 +1403,7 @@ function reportRedundant(source, context, sourceCode) {
|
|
|
1374
1403
|
for (const token of tokens) {
|
|
1375
1404
|
if (!isFlexRow(token.text))
|
|
1376
1405
|
continue;
|
|
1377
|
-
debug$
|
|
1406
|
+
debug$4(`found redundant flex-row token '${token.text}'`);
|
|
1378
1407
|
const tokenRange = [
|
|
1379
1408
|
source.contentStart + token.start,
|
|
1380
1409
|
source.contentStart + token.start + token.text.length
|
|
@@ -1438,6 +1467,148 @@ const noRedundantFlexRow = createEslintRule({
|
|
|
1438
1467
|
schema: [],
|
|
1439
1468
|
type: "suggestion"
|
|
1440
1469
|
},
|
|
1470
|
+
name: RULE_NAME$3
|
|
1471
|
+
});
|
|
1472
|
+
|
|
1473
|
+
const RULE_NAME$2 = "no-shared-pinia";
|
|
1474
|
+
const debug$3 = debugFactory("@rotki/eslint-plugin:no-shared-pinia");
|
|
1475
|
+
const DESCRIBE_NAMES = /* @__PURE__ */ new Set(["describe", "fdescribe", "xdescribe", "suite"]);
|
|
1476
|
+
const BEFORE_EACH_NAMES = /* @__PURE__ */ new Set(["beforeEach"]);
|
|
1477
|
+
const DEFAULT_FACTORIES = ["createPinia", "createCustomPinia", "createTestingPinia"];
|
|
1478
|
+
const DEFAULT_TEST_FILE_PATTERN = "\\.(spec|test)\\.[cm]?[jt]sx?$";
|
|
1479
|
+
function isFunctionNode(node) {
|
|
1480
|
+
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
1481
|
+
}
|
|
1482
|
+
function getRootCalleeName(callee) {
|
|
1483
|
+
if (callee.type === "Identifier")
|
|
1484
|
+
return callee.name;
|
|
1485
|
+
if (callee.type === "MemberExpression")
|
|
1486
|
+
return getRootCalleeName(callee.object);
|
|
1487
|
+
if (callee.type === "CallExpression")
|
|
1488
|
+
return getRootCalleeName(callee.callee);
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1491
|
+
function callbackOwnerName(fn) {
|
|
1492
|
+
const parent = fn.parent;
|
|
1493
|
+
if (!parent || parent.type !== "CallExpression")
|
|
1494
|
+
return null;
|
|
1495
|
+
return getRootCalleeName(parent.callee);
|
|
1496
|
+
}
|
|
1497
|
+
function isBeforeEachCallback(fn) {
|
|
1498
|
+
const owner = callbackOwnerName(fn);
|
|
1499
|
+
return owner != null && BEFORE_EACH_NAMES.has(owner);
|
|
1500
|
+
}
|
|
1501
|
+
function isDescribeCallback(fn) {
|
|
1502
|
+
const owner = callbackOwnerName(fn);
|
|
1503
|
+
return owner != null && DESCRIBE_NAMES.has(owner);
|
|
1504
|
+
}
|
|
1505
|
+
function nearestFunction(node) {
|
|
1506
|
+
let current = node.parent;
|
|
1507
|
+
while (current) {
|
|
1508
|
+
if (isFunctionNode(current))
|
|
1509
|
+
return current;
|
|
1510
|
+
current = current.parent;
|
|
1511
|
+
}
|
|
1512
|
+
return null;
|
|
1513
|
+
}
|
|
1514
|
+
function buildTestFileMatcher(pattern) {
|
|
1515
|
+
const regex = new RegExp(pattern, "u");
|
|
1516
|
+
return (filename) => regex.test(filename);
|
|
1517
|
+
}
|
|
1518
|
+
const noSharedPinia = createEslintRule({
|
|
1519
|
+
create(context, optionsWithDefault) {
|
|
1520
|
+
const options = optionsWithDefault[0] ?? {};
|
|
1521
|
+
const factories = new Set(options.factories ?? DEFAULT_FACTORIES);
|
|
1522
|
+
const isTestFile = buildTestFileMatcher(options.testFilePattern ?? DEFAULT_TEST_FILE_PATTERN);
|
|
1523
|
+
const filename = getFilename(context);
|
|
1524
|
+
if (!isTestFile(filename)) {
|
|
1525
|
+
debug$3(`skipping non-test file '${filename}'`);
|
|
1526
|
+
return {};
|
|
1527
|
+
}
|
|
1528
|
+
let program = null;
|
|
1529
|
+
const candidates = [];
|
|
1530
|
+
const freshContainers = /* @__PURE__ */ new Set();
|
|
1531
|
+
return {
|
|
1532
|
+
CallExpression(node) {
|
|
1533
|
+
const name = getRootCalleeName(node.callee);
|
|
1534
|
+
if (name == null || !factories.has(name) || program == null)
|
|
1535
|
+
return;
|
|
1536
|
+
const enclosing = nearestFunction(node);
|
|
1537
|
+
if (enclosing != null && isBeforeEachCallback(enclosing)) {
|
|
1538
|
+
freshContainers.add(nearestFunction(enclosing) ?? program);
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
if (enclosing != null && !isDescribeCallback(enclosing))
|
|
1542
|
+
return;
|
|
1543
|
+
candidates.push({
|
|
1544
|
+
atModuleScope: enclosing == null,
|
|
1545
|
+
container: enclosing ?? program,
|
|
1546
|
+
factory: name,
|
|
1547
|
+
node
|
|
1548
|
+
});
|
|
1549
|
+
},
|
|
1550
|
+
Program(node) {
|
|
1551
|
+
program = node;
|
|
1552
|
+
},
|
|
1553
|
+
"Program:exit": function() {
|
|
1554
|
+
const isProtected = (container) => {
|
|
1555
|
+
let current = container;
|
|
1556
|
+
while (current != null) {
|
|
1557
|
+
if (freshContainers.has(current))
|
|
1558
|
+
return true;
|
|
1559
|
+
if (current.type === "Program")
|
|
1560
|
+
break;
|
|
1561
|
+
current = nearestFunction(current) ?? program;
|
|
1562
|
+
}
|
|
1563
|
+
return false;
|
|
1564
|
+
};
|
|
1565
|
+
for (const candidate of candidates) {
|
|
1566
|
+
if (isProtected(candidate.container))
|
|
1567
|
+
continue;
|
|
1568
|
+
debug$3(`found shared pinia via '${candidate.factory}' ${candidate.atModuleScope ? "at module scope" : "in describe body"}`);
|
|
1569
|
+
context.report({
|
|
1570
|
+
data: {
|
|
1571
|
+
factory: candidate.factory,
|
|
1572
|
+
location: candidate.atModuleScope ? "at module scope" : "in the `describe` body"
|
|
1573
|
+
},
|
|
1574
|
+
messageId: "sharedPinia",
|
|
1575
|
+
node: candidate.node
|
|
1576
|
+
});
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
},
|
|
1581
|
+
defaultOptions: [
|
|
1582
|
+
{
|
|
1583
|
+
factories: DEFAULT_FACTORIES,
|
|
1584
|
+
testFilePattern: DEFAULT_TEST_FILE_PATTERN
|
|
1585
|
+
}
|
|
1586
|
+
],
|
|
1587
|
+
meta: {
|
|
1588
|
+
docs: {
|
|
1589
|
+
description: "disallow a Pinia instance shared across tests via `describe`-body or module scope",
|
|
1590
|
+
recommendation: "recommended"
|
|
1591
|
+
},
|
|
1592
|
+
messages: {
|
|
1593
|
+
sharedPinia: "`{{ factory }}()` is called {{ location }}, so the Pinia instance is shared across every test and store state leaks between them. Create a fresh instance per test with `beforeEach(() => setActivePinia(createPinia()))`, or add an inline disable if the shared instance is intentional."
|
|
1594
|
+
},
|
|
1595
|
+
schema: [
|
|
1596
|
+
{
|
|
1597
|
+
additionalProperties: false,
|
|
1598
|
+
properties: {
|
|
1599
|
+
factories: {
|
|
1600
|
+
items: { type: "string" },
|
|
1601
|
+
type: "array"
|
|
1602
|
+
},
|
|
1603
|
+
testFilePattern: {
|
|
1604
|
+
type: "string"
|
|
1605
|
+
}
|
|
1606
|
+
},
|
|
1607
|
+
type: "object"
|
|
1608
|
+
}
|
|
1609
|
+
],
|
|
1610
|
+
type: "problem"
|
|
1611
|
+
},
|
|
1441
1612
|
name: RULE_NAME$2
|
|
1442
1613
|
});
|
|
1443
1614
|
|
|
@@ -2093,6 +2264,7 @@ const plugin = {
|
|
|
2093
2264
|
"no-dot-ts-imports": noDotTsImport,
|
|
2094
2265
|
"no-legacy-library-import": noLegacyLibraryImport,
|
|
2095
2266
|
"no-redundant-flex-row": noRedundantFlexRow,
|
|
2267
|
+
"no-shared-pinia": noSharedPinia,
|
|
2096
2268
|
"no-unused-i18n-keys": noUnusedI18nKeys,
|
|
2097
2269
|
"require-jsdoc-on-composable-options": requireJsdocOnComposableOptions
|
|
2098
2270
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotki/eslint-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"bugs": {
|
|
@@ -28,37 +28,37 @@
|
|
|
28
28
|
"eslint": "^9.20.0 || ^10.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@typescript-eslint/utils": "8.
|
|
31
|
+
"@typescript-eslint/utils": "8.64.0",
|
|
32
32
|
"debug": "4.4.3",
|
|
33
33
|
"jsonc-eslint-parser": "3.1.0",
|
|
34
34
|
"scule": "1.3.0",
|
|
35
35
|
"tinyglobby": "0.2.17",
|
|
36
36
|
"vue-eslint-parser": "10.4.1",
|
|
37
|
-
"yaml-eslint-parser": "2.
|
|
37
|
+
"yaml-eslint-parser": "2.1.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@commitlint/cli": "21.
|
|
41
|
-
"@commitlint/config-conventional": "21.0
|
|
42
|
-
"@rotki/eslint-config": "6.
|
|
43
|
-
"@rotki/eslint-plugin": "1.
|
|
40
|
+
"@commitlint/cli": "21.2.1",
|
|
41
|
+
"@commitlint/config-conventional": "21.2.0",
|
|
42
|
+
"@rotki/eslint-config": "6.2.0",
|
|
43
|
+
"@rotki/eslint-plugin": "1.4.0",
|
|
44
44
|
"@types/debug": "4.1.13",
|
|
45
|
-
"@types/node": "24.13.
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
47
|
-
"@typescript-eslint/parser": "8.
|
|
48
|
-
"@typescript-eslint/rule-tester": "8.
|
|
49
|
-
"@vitest/coverage-v8": "4.1.
|
|
45
|
+
"@types/node": "24.13.3",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "8.64.0",
|
|
47
|
+
"@typescript-eslint/parser": "8.64.0",
|
|
48
|
+
"@typescript-eslint/rule-tester": "8.64.0",
|
|
49
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
50
50
|
"bumpp": "11.1.0",
|
|
51
|
-
"eslint": "10.
|
|
51
|
+
"eslint": "10.7.0",
|
|
52
52
|
"husky": "9.1.7",
|
|
53
|
-
"lint-staged": "17.0.
|
|
54
|
-
"oxc-minify": "0.
|
|
55
|
-
"prettier": "3.
|
|
53
|
+
"lint-staged": "17.0.8",
|
|
54
|
+
"oxc-minify": "0.140.0",
|
|
55
|
+
"prettier": "3.9.5",
|
|
56
56
|
"rimraf": "6.1.3",
|
|
57
|
-
"tsx": "4.
|
|
57
|
+
"tsx": "4.23.1",
|
|
58
58
|
"typescript": "6.0.3",
|
|
59
59
|
"unbuild": "3.6.1",
|
|
60
|
-
"vitepress": "2.0.0-alpha.
|
|
61
|
-
"vitest": "4.1.
|
|
60
|
+
"vitepress": "2.0.0-alpha.18",
|
|
61
|
+
"vitest": "4.1.10"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=24 <25",
|