eslint-plugin-turmag-special-rules 1.0.33 → 1.0.35
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/add-vue-extension.d.ts +37 -0
- package/dist/add-vue-extension.js +52 -0
- package/dist/import-entities-by-column-or-line.d.ts +26 -0
- package/dist/import-entities-by-column-or-line.js +81 -0
- package/dist/index.d.ts +253 -0
- package/dist/index.js +13 -0
- package/dist/prefer-true-attribute-shorthand.d.ts +18 -0
- package/dist/prefer-true-attribute-shorthand.js +47 -0
- package/dist/use-shortest-alias.d.ts +25 -0
- package/dist/use-shortest-alias.js +62 -0
- package/dist/variable-entities-by-column-or-line.d.ts +26 -0
- package/dist/variable-entities-by-column-or-line.js +105 -0
- package/lib/rules/add-vue-extension.ts +2 -2
- package/package.json +4 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
meta: {
|
|
4
|
+
fixable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
docs: {
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
messages: {
|
|
10
|
+
proper: string;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: {
|
|
15
|
+
aliases: {
|
|
16
|
+
type: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
create(context: {
|
|
22
|
+
options: {
|
|
23
|
+
aliases: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
} | ArrayLike<string>;
|
|
26
|
+
}[];
|
|
27
|
+
getFilename: () => string;
|
|
28
|
+
report: (arg0: {
|
|
29
|
+
node: unknown;
|
|
30
|
+
messageId: string;
|
|
31
|
+
fix: (fixer: any) => any;
|
|
32
|
+
}) => void;
|
|
33
|
+
}): {
|
|
34
|
+
ImportDeclaration(node: TSESTree.ImportDeclaration): void;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export default _default;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
export default {
|
|
4
|
+
meta: {
|
|
5
|
+
fixable: 'code',
|
|
6
|
+
type: 'suggestion',
|
|
7
|
+
docs: {
|
|
8
|
+
description: 'Require .vue in vue files',
|
|
9
|
+
},
|
|
10
|
+
messages: {
|
|
11
|
+
proper: 'Use proper import of vue files',
|
|
12
|
+
},
|
|
13
|
+
schema: [{
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: { aliases: { type: 'object' } },
|
|
16
|
+
}],
|
|
17
|
+
},
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
ImportDeclaration(node) {
|
|
21
|
+
const aliases = Object.entries(context.options[0].aliases);
|
|
22
|
+
if (!aliases.length)
|
|
23
|
+
return;
|
|
24
|
+
const basedir = path.dirname(path.resolve(context.getFilename()));
|
|
25
|
+
let nodeName = node.source.value;
|
|
26
|
+
aliases.every(([key, value]) => {
|
|
27
|
+
if (nodeName.includes(key))
|
|
28
|
+
nodeName = nodeName.replace(key, value);
|
|
29
|
+
else
|
|
30
|
+
return nodeName === node.source.value;
|
|
31
|
+
});
|
|
32
|
+
const filePath = path.resolve(basedir, nodeName);
|
|
33
|
+
const vueExt = '.vue';
|
|
34
|
+
const findRealExtension = (filePath) => {
|
|
35
|
+
let realExt = fs.existsSync(filePath) ? path.extname(filePath) : null;
|
|
36
|
+
if (realExt === null)
|
|
37
|
+
realExt = fs.existsSync(`${filePath}${vueExt}`) ? path.extname(`${filePath}${vueExt}`) : null;
|
|
38
|
+
return realExt;
|
|
39
|
+
};
|
|
40
|
+
const nodeNameExt = path.extname(nodeName);
|
|
41
|
+
const realExt = findRealExtension(filePath);
|
|
42
|
+
if (realExt === vueExt && realExt !== nodeNameExt) {
|
|
43
|
+
context.report({
|
|
44
|
+
node,
|
|
45
|
+
messageId: 'proper',
|
|
46
|
+
fix: fixer => fixer.replaceText(node, node.specifiers.map(specifier => `import ${specifier.local.name} from '${node.source.value}${realExt}';`).join('\n')),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
meta: {
|
|
4
|
+
fixable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
docs: {
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
messages: {
|
|
10
|
+
column: string;
|
|
11
|
+
line: string;
|
|
12
|
+
};
|
|
13
|
+
schema: {
|
|
14
|
+
type: string;
|
|
15
|
+
properties: {
|
|
16
|
+
minProperties: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
22
|
+
create(context: any): {
|
|
23
|
+
ImportDeclaration(node: TSESTree.ImportDeclaration): void;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export default _default;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
fixable: 'code',
|
|
4
|
+
type: 'suggestion',
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'Prefered column or line import',
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
column: 'Use column import',
|
|
10
|
+
line: 'Use line import',
|
|
11
|
+
},
|
|
12
|
+
schema: [{
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: { minProperties: { type: 'number' } },
|
|
15
|
+
}],
|
|
16
|
+
},
|
|
17
|
+
// @ts-expect-error context type
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
ImportDeclaration(node) {
|
|
21
|
+
if (!node.specifiers[0])
|
|
22
|
+
return;
|
|
23
|
+
if (node.specifiers[0].type === 'ImportDefaultSpecifier')
|
|
24
|
+
return;
|
|
25
|
+
const minProperties = context.options[0].minProperties;
|
|
26
|
+
const isTypedNode = node.importKind === 'type';
|
|
27
|
+
let areSmallAttributesInColumn = false;
|
|
28
|
+
let areLinesRepeated = false;
|
|
29
|
+
if (node.specifiers.length < minProperties) {
|
|
30
|
+
if (node.specifiers[0].loc.start.line !== node.specifiers[0].parent.loc.start.line)
|
|
31
|
+
areSmallAttributesInColumn = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
node.specifiers.every((specifier, i) => {
|
|
35
|
+
if (i === 0)
|
|
36
|
+
return true;
|
|
37
|
+
if (specifier.loc.start.line === specifier.loc.end.line && node.specifiers[i - 1].loc.start.line === specifier.loc.start.line)
|
|
38
|
+
areLinesRepeated = true;
|
|
39
|
+
else
|
|
40
|
+
return !areLinesRepeated;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const getSpecifiersArr = (specifiers) => {
|
|
44
|
+
const specifiersArr = [];
|
|
45
|
+
specifiers.forEach(specifier => {
|
|
46
|
+
const localName = specifier.local.name;
|
|
47
|
+
let resultName = localName;
|
|
48
|
+
if (specifier.imported.name !== localName) {
|
|
49
|
+
resultName = `${specifier.imported.name} as ${localName}`;
|
|
50
|
+
}
|
|
51
|
+
const name = specifier.importKind === 'type' ? `type ${resultName}` : resultName;
|
|
52
|
+
specifiersArr.push(name);
|
|
53
|
+
});
|
|
54
|
+
return specifiersArr;
|
|
55
|
+
};
|
|
56
|
+
if (areLinesRepeated) {
|
|
57
|
+
context.report({
|
|
58
|
+
node,
|
|
59
|
+
messageId: 'column',
|
|
60
|
+
fix: (fixer) => {
|
|
61
|
+
const specifiersArr = getSpecifiersArr(node.specifiers);
|
|
62
|
+
const replaceShiftSign = '\n ';
|
|
63
|
+
return fixer.replaceText(node, `import ${isTypedNode ? 'type ' : ''}{${replaceShiftSign}${specifiersArr.join(`,${replaceShiftSign}`)},\n} from '${node.source.value}';`);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (areSmallAttributesInColumn) {
|
|
68
|
+
context.report({
|
|
69
|
+
node,
|
|
70
|
+
messageId: 'line',
|
|
71
|
+
fix: (fixer) => {
|
|
72
|
+
const specifiersArr = getSpecifiersArr(node.specifiers);
|
|
73
|
+
const replaceShiftSign = ' ';
|
|
74
|
+
return fixer.replaceText(node, `import ${isTypedNode ? 'type ' : ''}{${replaceShiftSign}${specifiersArr.join(`,${replaceShiftSign}`)} } from '${node.source.value}';`);
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
export declare const rules: {
|
|
2
|
+
'add-vue-extension': {
|
|
3
|
+
meta: {
|
|
4
|
+
fixable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
docs: {
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
messages: {
|
|
10
|
+
proper: string;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: {
|
|
15
|
+
aliases: {
|
|
16
|
+
type: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
create(context: {
|
|
22
|
+
options: {
|
|
23
|
+
aliases: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
} | ArrayLike<string>;
|
|
26
|
+
}[];
|
|
27
|
+
getFilename: () => string;
|
|
28
|
+
report: (arg0: {
|
|
29
|
+
node: unknown;
|
|
30
|
+
messageId: string;
|
|
31
|
+
fix: (fixer: any) => any;
|
|
32
|
+
}) => void;
|
|
33
|
+
}): {
|
|
34
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
'import-entities-by-column-or-line': {
|
|
38
|
+
meta: {
|
|
39
|
+
fixable: string;
|
|
40
|
+
type: string;
|
|
41
|
+
docs: {
|
|
42
|
+
description: string;
|
|
43
|
+
};
|
|
44
|
+
messages: {
|
|
45
|
+
column: string;
|
|
46
|
+
line: string;
|
|
47
|
+
};
|
|
48
|
+
schema: {
|
|
49
|
+
type: string;
|
|
50
|
+
properties: {
|
|
51
|
+
minProperties: {
|
|
52
|
+
type: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
}[];
|
|
56
|
+
};
|
|
57
|
+
create(context: any): {
|
|
58
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
'prefer-true-attribute-shorthand': {
|
|
62
|
+
meta: {
|
|
63
|
+
fixable: string;
|
|
64
|
+
type: string;
|
|
65
|
+
docs: {
|
|
66
|
+
description: string;
|
|
67
|
+
};
|
|
68
|
+
messages: {
|
|
69
|
+
shortHand: string;
|
|
70
|
+
longHand: string;
|
|
71
|
+
};
|
|
72
|
+
schema: {
|
|
73
|
+
enum: string[];
|
|
74
|
+
}[];
|
|
75
|
+
};
|
|
76
|
+
create(context: any): any;
|
|
77
|
+
};
|
|
78
|
+
'use-shortest-alias': {
|
|
79
|
+
meta: {
|
|
80
|
+
fixable: string;
|
|
81
|
+
type: string;
|
|
82
|
+
docs: {
|
|
83
|
+
description: string;
|
|
84
|
+
};
|
|
85
|
+
messages: {
|
|
86
|
+
shortest: string;
|
|
87
|
+
};
|
|
88
|
+
schema: {
|
|
89
|
+
type: string;
|
|
90
|
+
properties: {
|
|
91
|
+
aliases: {
|
|
92
|
+
type: string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
}[];
|
|
96
|
+
};
|
|
97
|
+
create(context: any): {
|
|
98
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
'variable-entities-by-column-or-line': {
|
|
102
|
+
meta: {
|
|
103
|
+
fixable: string;
|
|
104
|
+
type: string;
|
|
105
|
+
docs: {
|
|
106
|
+
description: string;
|
|
107
|
+
};
|
|
108
|
+
messages: {
|
|
109
|
+
column: string;
|
|
110
|
+
line: string;
|
|
111
|
+
};
|
|
112
|
+
schema: {
|
|
113
|
+
type: string;
|
|
114
|
+
properties: {
|
|
115
|
+
minProperties: {
|
|
116
|
+
type: string;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
}[];
|
|
120
|
+
};
|
|
121
|
+
create(context: any): {
|
|
122
|
+
VariableDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").VariableDeclaration): void;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
declare const _default: {
|
|
127
|
+
rules: {
|
|
128
|
+
'add-vue-extension': {
|
|
129
|
+
meta: {
|
|
130
|
+
fixable: string;
|
|
131
|
+
type: string;
|
|
132
|
+
docs: {
|
|
133
|
+
description: string;
|
|
134
|
+
};
|
|
135
|
+
messages: {
|
|
136
|
+
proper: string;
|
|
137
|
+
};
|
|
138
|
+
schema: {
|
|
139
|
+
type: string;
|
|
140
|
+
properties: {
|
|
141
|
+
aliases: {
|
|
142
|
+
type: string;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
}[];
|
|
146
|
+
};
|
|
147
|
+
create(context: {
|
|
148
|
+
options: {
|
|
149
|
+
aliases: {
|
|
150
|
+
[key: string]: string;
|
|
151
|
+
} | ArrayLike<string>;
|
|
152
|
+
}[];
|
|
153
|
+
getFilename: () => string;
|
|
154
|
+
report: (arg0: {
|
|
155
|
+
node: unknown;
|
|
156
|
+
messageId: string;
|
|
157
|
+
fix: (fixer: any) => any;
|
|
158
|
+
}) => void;
|
|
159
|
+
}): {
|
|
160
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
'import-entities-by-column-or-line': {
|
|
164
|
+
meta: {
|
|
165
|
+
fixable: string;
|
|
166
|
+
type: string;
|
|
167
|
+
docs: {
|
|
168
|
+
description: string;
|
|
169
|
+
};
|
|
170
|
+
messages: {
|
|
171
|
+
column: string;
|
|
172
|
+
line: string;
|
|
173
|
+
};
|
|
174
|
+
schema: {
|
|
175
|
+
type: string;
|
|
176
|
+
properties: {
|
|
177
|
+
minProperties: {
|
|
178
|
+
type: string;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
}[];
|
|
182
|
+
};
|
|
183
|
+
create(context: any): {
|
|
184
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
'prefer-true-attribute-shorthand': {
|
|
188
|
+
meta: {
|
|
189
|
+
fixable: string;
|
|
190
|
+
type: string;
|
|
191
|
+
docs: {
|
|
192
|
+
description: string;
|
|
193
|
+
};
|
|
194
|
+
messages: {
|
|
195
|
+
shortHand: string;
|
|
196
|
+
longHand: string;
|
|
197
|
+
};
|
|
198
|
+
schema: {
|
|
199
|
+
enum: string[];
|
|
200
|
+
}[];
|
|
201
|
+
};
|
|
202
|
+
create(context: any): any;
|
|
203
|
+
};
|
|
204
|
+
'use-shortest-alias': {
|
|
205
|
+
meta: {
|
|
206
|
+
fixable: string;
|
|
207
|
+
type: string;
|
|
208
|
+
docs: {
|
|
209
|
+
description: string;
|
|
210
|
+
};
|
|
211
|
+
messages: {
|
|
212
|
+
shortest: string;
|
|
213
|
+
};
|
|
214
|
+
schema: {
|
|
215
|
+
type: string;
|
|
216
|
+
properties: {
|
|
217
|
+
aliases: {
|
|
218
|
+
type: string;
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
}[];
|
|
222
|
+
};
|
|
223
|
+
create(context: any): {
|
|
224
|
+
ImportDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").ImportDeclaration): void;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
'variable-entities-by-column-or-line': {
|
|
228
|
+
meta: {
|
|
229
|
+
fixable: string;
|
|
230
|
+
type: string;
|
|
231
|
+
docs: {
|
|
232
|
+
description: string;
|
|
233
|
+
};
|
|
234
|
+
messages: {
|
|
235
|
+
column: string;
|
|
236
|
+
line: string;
|
|
237
|
+
};
|
|
238
|
+
schema: {
|
|
239
|
+
type: string;
|
|
240
|
+
properties: {
|
|
241
|
+
minProperties: {
|
|
242
|
+
type: string;
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
}[];
|
|
246
|
+
};
|
|
247
|
+
create(context: any): {
|
|
248
|
+
VariableDeclaration(node: import("@typescript-eslint/types/dist/generated/ast-spec.js").VariableDeclaration): void;
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
export default _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import addVueExtension from './add-vue-extension.js';
|
|
2
|
+
import importEntitesByColumnOrLine from './import-entities-by-column-or-line.js';
|
|
3
|
+
import preferTrueAttributeShorthand from './prefer-true-attribute-shorthand.js';
|
|
4
|
+
import useShortestAlias from './use-shortest-alias.js';
|
|
5
|
+
import variableEntitiesByColumnOrLine from './variable-entities-by-column-or-line.js';
|
|
6
|
+
export const rules = {
|
|
7
|
+
'add-vue-extension': addVueExtension,
|
|
8
|
+
'import-entities-by-column-or-line': importEntitesByColumnOrLine,
|
|
9
|
+
'prefer-true-attribute-shorthand': preferTrueAttributeShorthand,
|
|
10
|
+
'use-shortest-alias': useShortestAlias,
|
|
11
|
+
'variable-entities-by-column-or-line': variableEntitiesByColumnOrLine,
|
|
12
|
+
};
|
|
13
|
+
export default { rules };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
meta: {
|
|
3
|
+
fixable: string;
|
|
4
|
+
type: string;
|
|
5
|
+
docs: {
|
|
6
|
+
description: string;
|
|
7
|
+
};
|
|
8
|
+
messages: {
|
|
9
|
+
shortHand: string;
|
|
10
|
+
longHand: string;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
enum: string[];
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
create(context: any): any;
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
fixable: 'code',
|
|
4
|
+
type: 'suggestion',
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'Require shorthand form attribute when `v-bind` value is `true`',
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
shortHand: 'Boolean prop with \'true\' value should be written in shorthand form',
|
|
10
|
+
longHand: 'Boolean prop with \'true\' value should be written in longhand form',
|
|
11
|
+
},
|
|
12
|
+
schema: [{ enum: ['always', 'never'] }],
|
|
13
|
+
},
|
|
14
|
+
// @ts-expect-error create type
|
|
15
|
+
create(context) {
|
|
16
|
+
const sourceCode = context.getSourceCode();
|
|
17
|
+
return sourceCode.parserServices?.defineTemplateBodyVisitor
|
|
18
|
+
? sourceCode.parserServices.defineTemplateBodyVisitor({
|
|
19
|
+
VAttribute(node) {
|
|
20
|
+
const option = context.options[0] || 'always';
|
|
21
|
+
if (option === 'never' && !node.directive && !node.value) {
|
|
22
|
+
context.report({
|
|
23
|
+
node,
|
|
24
|
+
messageId: 'longHand',
|
|
25
|
+
fix: (fixer) => fixer.replaceText(node, `:${node.key.rawName}="true"`),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (option !== 'always')
|
|
29
|
+
return;
|
|
30
|
+
if (node.directive && node.key.name !== 'bind' && node.value?.expression?.value && node.value.expression.value === Boolean(node.value.expression.value)) {
|
|
31
|
+
const { argument } = node.key;
|
|
32
|
+
if (!argument)
|
|
33
|
+
return;
|
|
34
|
+
context.report({
|
|
35
|
+
node,
|
|
36
|
+
messageId: 'shortHand',
|
|
37
|
+
fix: (fixer) => {
|
|
38
|
+
const sourceCode = context.getSourceCode();
|
|
39
|
+
return fixer.replaceText(node, sourceCode.getText(argument));
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
: {};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
meta: {
|
|
4
|
+
fixable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
docs: {
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
messages: {
|
|
10
|
+
shortest: string;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: {
|
|
15
|
+
aliases: {
|
|
16
|
+
type: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
create(context: any): {
|
|
22
|
+
ImportDeclaration(node: TSESTree.ImportDeclaration): void;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
fixable: 'code',
|
|
4
|
+
type: 'suggestion',
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'There are can be used shortest alias',
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
shortest: 'Use shortest alias',
|
|
10
|
+
},
|
|
11
|
+
schema: [{
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: { aliases: { type: 'object' } },
|
|
14
|
+
}],
|
|
15
|
+
},
|
|
16
|
+
// @ts-expect-error context type
|
|
17
|
+
create(context) {
|
|
18
|
+
return {
|
|
19
|
+
ImportDeclaration(node) {
|
|
20
|
+
const aliases = Object.entries(context.options[0].aliases);
|
|
21
|
+
if (!aliases.length)
|
|
22
|
+
return;
|
|
23
|
+
const nodeName = node.source.value;
|
|
24
|
+
let nodeNameWithoutAlias = nodeName;
|
|
25
|
+
let resultNodeName = nodeName;
|
|
26
|
+
aliases.every(([key, value]) => {
|
|
27
|
+
if (nodeNameWithoutAlias.includes(key))
|
|
28
|
+
nodeNameWithoutAlias = nodeNameWithoutAlias.replace(key, value);
|
|
29
|
+
else
|
|
30
|
+
return nodeNameWithoutAlias === nodeName;
|
|
31
|
+
});
|
|
32
|
+
nodeNameWithoutAlias = nodeNameWithoutAlias.replace(/\\/ig, '/');
|
|
33
|
+
aliases.every(([key, value]) => {
|
|
34
|
+
value = value.replace(/\\/ig, '/');
|
|
35
|
+
if (nodeNameWithoutAlias.includes(value))
|
|
36
|
+
resultNodeName = nodeNameWithoutAlias.replace(value, key).replace(/\\/ig, '/');
|
|
37
|
+
else
|
|
38
|
+
return resultNodeName === nodeName;
|
|
39
|
+
});
|
|
40
|
+
if (nodeName !== resultNodeName) {
|
|
41
|
+
context.report({
|
|
42
|
+
node,
|
|
43
|
+
messageId: 'shortest',
|
|
44
|
+
fix: (fixer) => {
|
|
45
|
+
let replaceText = '';
|
|
46
|
+
if (node.specifiers[0].type === 'ImportDefaultSpecifier')
|
|
47
|
+
replaceText = `import ${node.specifiers[0].local.name} from '${resultNodeName}';`;
|
|
48
|
+
else {
|
|
49
|
+
const specifiersArr = [];
|
|
50
|
+
node.specifiers.forEach(specifier => specifiersArr.push(specifier.local.name));
|
|
51
|
+
const replaceSign = specifiersArr.length > 2 ? '\n' : ' ';
|
|
52
|
+
const replaceShiftSign = specifiersArr.length > 2 ? '\n ' : ' ';
|
|
53
|
+
replaceText = `import {${replaceShiftSign}${specifiersArr.join(`,${replaceShiftSign}`)}${specifiersArr.length > 2 ? ',' : ''}${replaceSign}} from '${resultNodeName}';`;
|
|
54
|
+
}
|
|
55
|
+
return fixer.replaceText(node, replaceText);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
meta: {
|
|
4
|
+
fixable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
docs: {
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
messages: {
|
|
10
|
+
column: string;
|
|
11
|
+
line: string;
|
|
12
|
+
};
|
|
13
|
+
schema: {
|
|
14
|
+
type: string;
|
|
15
|
+
properties: {
|
|
16
|
+
minProperties: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
22
|
+
create(context: any): {
|
|
23
|
+
VariableDeclaration(node: TSESTree.VariableDeclaration): void;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export default _default;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
fixable: 'code',
|
|
4
|
+
type: 'suggestion',
|
|
5
|
+
docs: { description: 'Prefered column or line destructuring' },
|
|
6
|
+
messages: {
|
|
7
|
+
column: 'Use column destructuring',
|
|
8
|
+
line: 'Use line destructuring',
|
|
9
|
+
},
|
|
10
|
+
schema: [{
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: { minProperties: { type: 'number' } },
|
|
13
|
+
}],
|
|
14
|
+
},
|
|
15
|
+
// @ts-expect-error context type
|
|
16
|
+
create(context) {
|
|
17
|
+
return {
|
|
18
|
+
VariableDeclaration(node) {
|
|
19
|
+
if (!node.declarations[0])
|
|
20
|
+
return;
|
|
21
|
+
if (node.declarations[0].id.type !== 'ObjectPattern')
|
|
22
|
+
return;
|
|
23
|
+
if (!node.declarations[0].init)
|
|
24
|
+
return;
|
|
25
|
+
const minProperties = context.options[0].minProperties;
|
|
26
|
+
const kind = node.kind;
|
|
27
|
+
const declaration = node.declarations[0];
|
|
28
|
+
// @ts-expect-error properties type
|
|
29
|
+
const properties = declaration.id.properties;
|
|
30
|
+
const sourceCode = context.sourceCode;
|
|
31
|
+
const rightSideText = sourceCode.getText(declaration.init);
|
|
32
|
+
let areSmallAttributesInColumn = false;
|
|
33
|
+
let areLinesRepeated = false;
|
|
34
|
+
let isObjectDestructured = false;
|
|
35
|
+
// @ts-expect-error property type
|
|
36
|
+
properties.forEach(property => {
|
|
37
|
+
if (property.value?.type === 'ObjectPattern')
|
|
38
|
+
isObjectDestructured = true;
|
|
39
|
+
});
|
|
40
|
+
if (isObjectDestructured)
|
|
41
|
+
return;
|
|
42
|
+
if (properties.length < minProperties) {
|
|
43
|
+
if (properties[0].loc.start.line !== properties[0].parent.loc.start.line)
|
|
44
|
+
areSmallAttributesInColumn = true;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// @ts-expect-error property type
|
|
48
|
+
properties.every((property, i) => {
|
|
49
|
+
if (i === 0)
|
|
50
|
+
return true;
|
|
51
|
+
if (property.loc.start.line === property.loc.end.line && properties[i - 1].loc.start.line === property.loc.start.line)
|
|
52
|
+
areLinesRepeated = true;
|
|
53
|
+
else
|
|
54
|
+
return !areLinesRepeated;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// @ts-expect-error properties type
|
|
58
|
+
const getPropertiesArr = properties => {
|
|
59
|
+
const propertiesArr = [];
|
|
60
|
+
// @ts-expect-error property type
|
|
61
|
+
properties.forEach(property => {
|
|
62
|
+
if (property.type === 'RestElement') {
|
|
63
|
+
propertiesArr.push(`...${property.argument.name}`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const key = property.key.name;
|
|
67
|
+
let value = property.value.name;
|
|
68
|
+
let name = key === value ? value : `${key}: ${value}`;
|
|
69
|
+
if (!value && property.value.left && property.value.right) {
|
|
70
|
+
value = property.value.left.name;
|
|
71
|
+
const rightValue = property.value.right.value;
|
|
72
|
+
name = key === value ? `${value} = ${rightValue}` : `${key}: ${value} = ${rightValue}`;
|
|
73
|
+
}
|
|
74
|
+
propertiesArr.push(name);
|
|
75
|
+
});
|
|
76
|
+
return propertiesArr;
|
|
77
|
+
};
|
|
78
|
+
if (areLinesRepeated) {
|
|
79
|
+
context.report({
|
|
80
|
+
node,
|
|
81
|
+
messageId: 'column',
|
|
82
|
+
fix: (fixer) => {
|
|
83
|
+
const propertiesArr = getPropertiesArr(properties);
|
|
84
|
+
const replaceShiftSign = '\n ';
|
|
85
|
+
// @ts-expect-error node type
|
|
86
|
+
return fixer.replaceText(node, `${kind} {${replaceShiftSign}${propertiesArr.join(`,${replaceShiftSign}`)},\n} = ${rightSideText};`);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else if (areSmallAttributesInColumn) {
|
|
91
|
+
context.report({
|
|
92
|
+
node,
|
|
93
|
+
messageId: 'line',
|
|
94
|
+
fix: (fixer) => {
|
|
95
|
+
const propertiesArr = getPropertiesArr(properties);
|
|
96
|
+
const replaceShiftSign = ' ';
|
|
97
|
+
// @ts-expect-error node type
|
|
98
|
+
return fixer.replaceText(node, `${kind} {${replaceShiftSign}${propertiesArr.join(`,${replaceShiftSign}`)} } = ${rightSideText};`);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-turmag-special-rules",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Special eslint rules for your awesome projects",
|
|
6
6
|
"keywords": [
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
"eslint-plugin"
|
|
10
10
|
],
|
|
11
11
|
"author": "Pavel",
|
|
12
|
-
"main": "./lib/index.ts",
|
|
12
|
+
"main": "./lib/rules/index.ts",
|
|
13
13
|
"exports": "./dist/index.js",
|
|
14
14
|
"files": [
|
|
15
|
-
"lib"
|
|
15
|
+
"lib",
|
|
16
|
+
"dist"
|
|
16
17
|
],
|
|
17
18
|
"scripts": {
|
|
18
19
|
"lint": "npm-run-all \"lint:*\"",
|