@borela-tech/eslint-config 2.1.1 → 2.2.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.ts +2 -2
- package/dist/index.js +291 -58
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/index.ts +18 -5
- package/src/rules/__tests__/importsAndReExportsAtTop.test.ts +3 -33
- package/src/rules/__tests__/individualImports.test.ts +3 -1
- package/src/rules/__tests__/individualReExports.test.ts +3 -1
- package/src/rules/__tests__/multilineUnionTypes.test.ts +75 -0
- package/src/rules/__tests__/singleLineImports.test.ts +129 -0
- package/src/rules/__tests__/singleLineReExports.test.ts +100 -0
- package/src/rules/__tests__/sortedImports.test.ts +37 -1
- package/src/rules/__tests__/sortedReExports.test.ts +27 -1
- package/src/rules/importsAndReExportsAtTop/CategorizedStatements.ts +2 -2
- package/src/rules/importsAndReExportsAtTop/StatementIndices.ts +3 -3
- package/src/rules/importsAndReExportsAtTop/categorizeStatements.ts +7 -6
- package/src/rules/importsAndReExportsAtTop/findStatementIndices.ts +25 -0
- package/src/rules/importsAndReExportsAtTop/generateSortedText.ts +4 -6
- package/src/rules/importsAndReExportsAtTop/getStatementType.ts +1 -1
- package/src/rules/importsAndReExportsAtTop/hasViolation.ts +13 -17
- package/src/rules/importsAndReExportsAtTop/index.ts +7 -7
- package/src/rules/importsAndReExportsAtTop/isImportDeclaration.ts +7 -0
- package/src/rules/importsAndReExportsAtTop/isReExport.ts +12 -0
- package/src/rules/individualImports.ts +4 -3
- package/src/rules/individualReExports.ts +8 -9
- package/src/rules/multilineUnionTypes/createFix.ts +13 -0
- package/src/rules/multilineUnionTypes/index.ts +52 -0
- package/src/rules/multilineUnionTypes/isMultiline.ts +6 -0
- package/src/rules/singleLineImports/createFix.ts +23 -0
- package/src/rules/singleLineImports/formatAttributes.ts +20 -0
- package/src/rules/singleLineImports/formatNamed.ts +9 -0
- package/src/rules/singleLineImports/formatSpecifiers.ts +32 -0
- package/src/rules/singleLineImports/index.ts +34 -0
- package/src/rules/singleLineImports/isMultiline.ts +6 -0
- package/src/rules/singleLineReExports/createFix.ts +29 -0
- package/src/rules/singleLineReExports/index.ts +48 -0
- package/src/rules/singleLineReExports/isMultiline.ts +6 -0
- package/src/rules/sortedImports/ImportError.ts +4 -1
- package/src/rules/sortedImports/ImportGroup.ts +2 -1
- package/src/rules/sortedImports/ImportGroupOrder.ts +2 -1
- package/src/rules/sortedImports/areSpecifiersSorted.ts +1 -1
- package/src/rules/sortedImports/categorizeImport.ts +4 -0
- package/src/rules/sortedImports/checkAlphabeticalSorting.ts +1 -1
- package/src/rules/sortedImports/createFix/buildSortedCode.ts +2 -1
- package/src/rules/sortedImports/createFix/formatNamedImport.ts +3 -2
- package/src/rules/sortedImports/createFix/getReplacementRange.ts +3 -3
- package/src/rules/sortedImports/createFix/groupImportsByType.ts +1 -0
- package/src/rules/sortedImports/createFix/index.ts +10 -11
- package/src/rules/sortedImports/createFix/sortImportGroups.ts +2 -1
- package/src/rules/sortedImports/getSortKey.ts +8 -2
- package/src/rules/sortedImports/index.ts +8 -5
- package/src/rules/sortedImports/sortSpecifiersText.ts +4 -3
- package/src/rules/sortedReExports/CategorizedReExport.ts +14 -3
- package/src/rules/sortedReExports/ReExportError.ts +5 -2
- package/src/rules/sortedReExports/ReExportGroup.ts +1 -0
- package/src/rules/sortedReExports/ReExportGroupOrder.ts +2 -1
- package/src/rules/sortedReExports/areSpecifiersSorted.ts +1 -1
- package/src/rules/sortedReExports/categorizeReExport.ts +8 -4
- package/src/rules/sortedReExports/categorizeReExports.ts +1 -1
- package/src/rules/sortedReExports/checkAlphabeticalSorting.ts +1 -1
- package/src/rules/sortedReExports/createFix/buildSortedCode.ts +2 -1
- package/src/rules/sortedReExports/createFix/formatNamedReExport.ts +3 -2
- package/src/rules/sortedReExports/createFix/getReplacementRange.ts +1 -1
- package/src/rules/sortedReExports/createFix/groupReExportsByType.ts +1 -0
- package/src/rules/sortedReExports/createFix/index.ts +10 -11
- package/src/rules/sortedReExports/createFix/sortExportGroups.ts +2 -1
- package/src/rules/sortedReExports/getNamedSpecifiers.ts +1 -1
- package/src/rules/sortedReExports/getReExportGroups.ts +1 -1
- package/src/rules/sortedReExports/getSortKey.ts +11 -5
- package/src/rules/sortedReExports/index.ts +8 -5
- package/src/rules/sortedReExports/isNamedReExport.ts +2 -2
- package/src/rules/sortedReExports/sortSpecifiersText.ts +4 -3
- package/src/rules/importsAndReExportsAtTop/ReExport.ts +0 -5
- package/src/rules/importsAndReExportsAtTop/findFirstIndices.ts +0 -25
- /package/src/{rules/sortedReExports → lib}/ReExportDeclaration.ts +0 -0
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import react from "eslint-plugin-react";
|
|
|
4
4
|
import reactHooks from "eslint-plugin-react-hooks";
|
|
5
5
|
import stylistic from "@stylistic/eslint-plugin";
|
|
6
6
|
import typescript from "typescript-eslint";
|
|
7
|
-
import { defineConfig } from "eslint/config";
|
|
8
7
|
|
|
9
8
|
// src/rules/importsAndReExportsAtTop/getStatementType.ts
|
|
10
9
|
function getStatementType(statement) {
|
|
@@ -19,6 +18,20 @@ function getStatementType(statement) {
|
|
|
19
18
|
return "other";
|
|
20
19
|
}
|
|
21
20
|
|
|
21
|
+
// src/rules/importsAndReExportsAtTop/isImportDeclaration.ts
|
|
22
|
+
function isImportDeclaration(statement) {
|
|
23
|
+
return statement.type === "ImportDeclaration";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/rules/importsAndReExportsAtTop/isReExport.ts
|
|
27
|
+
function isReExport(statement) {
|
|
28
|
+
if (statement.type === "ExportAllDeclaration")
|
|
29
|
+
return true;
|
|
30
|
+
if (statement.type === "ExportNamedDeclaration")
|
|
31
|
+
return statement.source !== null;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
// src/rules/importsAndReExportsAtTop/categorizeStatements.ts
|
|
23
36
|
function categorizeStatements(statements) {
|
|
24
37
|
const result = {
|
|
@@ -28,9 +41,9 @@ function categorizeStatements(statements) {
|
|
|
28
41
|
};
|
|
29
42
|
for (const statement of statements) {
|
|
30
43
|
const type = getStatementType(statement);
|
|
31
|
-
if (type === "import")
|
|
44
|
+
if (type === "import" && isImportDeclaration(statement))
|
|
32
45
|
result.imports.push(statement);
|
|
33
|
-
else if (type === "re-export")
|
|
46
|
+
else if (type === "re-export" && isReExport(statement))
|
|
34
47
|
result.reExports.push(statement);
|
|
35
48
|
else
|
|
36
49
|
result.other.push(statement);
|
|
@@ -38,21 +51,21 @@ function categorizeStatements(statements) {
|
|
|
38
51
|
return result;
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
// src/rules/importsAndReExportsAtTop/
|
|
42
|
-
function
|
|
43
|
-
let
|
|
44
|
-
let
|
|
45
|
-
let
|
|
54
|
+
// src/rules/importsAndReExportsAtTop/findStatementIndices.ts
|
|
55
|
+
function findStatementIndices(statements) {
|
|
56
|
+
let firstRegularStatement = -1;
|
|
57
|
+
let lastImport = -1;
|
|
58
|
+
let lastReExport = -1;
|
|
46
59
|
for (let i = 0; i < statements.length; i++) {
|
|
47
60
|
const type = getStatementType(statements[i]);
|
|
48
|
-
if (type === "import"
|
|
49
|
-
|
|
50
|
-
else if (type === "re-export"
|
|
51
|
-
|
|
52
|
-
else if (type === "other" &&
|
|
53
|
-
|
|
61
|
+
if (type === "import")
|
|
62
|
+
lastImport = i;
|
|
63
|
+
else if (type === "re-export")
|
|
64
|
+
lastReExport = i;
|
|
65
|
+
else if (type === "other" && firstRegularStatement === -1)
|
|
66
|
+
firstRegularStatement = i;
|
|
54
67
|
}
|
|
55
|
-
return {
|
|
68
|
+
return { firstRegularStatement, lastImport, lastReExport };
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
// src/rules/importsAndReExportsAtTop/generateSortedText.ts
|
|
@@ -69,18 +82,12 @@ function generateSortedText(context, categories) {
|
|
|
69
82
|
|
|
70
83
|
// src/rules/importsAndReExportsAtTop/hasViolation.ts
|
|
71
84
|
function hasViolation(indices, categories) {
|
|
72
|
-
const {
|
|
73
|
-
|
|
74
|
-
firstReExport,
|
|
75
|
-
firstOther
|
|
76
|
-
} = indices;
|
|
77
|
-
if (categories.imports.length === 0 || categories.reExports.length === 0)
|
|
85
|
+
const { firstRegularStatement, lastImport, lastReExport } = indices;
|
|
86
|
+
if (categories.imports.length === 0 && categories.reExports.length === 0)
|
|
78
87
|
return false;
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
return true;
|
|
83
|
-
return false;
|
|
88
|
+
const hasImportAfterRegularStatement = categories.imports.length > 0 && firstRegularStatement !== -1 && lastImport > firstRegularStatement;
|
|
89
|
+
const hasReExportAfterRegularStatement = categories.reExports.length > 0 && firstRegularStatement !== -1 && lastReExport > firstRegularStatement;
|
|
90
|
+
return hasImportAfterRegularStatement || hasReExportAfterRegularStatement;
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
// src/rules/importsAndReExportsAtTop/index.ts
|
|
@@ -88,8 +95,7 @@ var importsAndReExportsAtTop = {
|
|
|
88
95
|
meta: {
|
|
89
96
|
type: "suggestion",
|
|
90
97
|
docs: {
|
|
91
|
-
description: "Enforce imports and re-exports at the top of the file"
|
|
92
|
-
recommended: false
|
|
98
|
+
description: "Enforce imports and re-exports at the top of the file"
|
|
93
99
|
},
|
|
94
100
|
fixable: "code",
|
|
95
101
|
messages: {
|
|
@@ -102,7 +108,7 @@ var importsAndReExportsAtTop = {
|
|
|
102
108
|
Program(node) {
|
|
103
109
|
const statements = node.body;
|
|
104
110
|
const categories = categorizeStatements(statements);
|
|
105
|
-
const indices =
|
|
111
|
+
const indices = findStatementIndices(statements);
|
|
106
112
|
if (!hasViolation(indices, categories))
|
|
107
113
|
return;
|
|
108
114
|
context.report({
|
|
@@ -122,8 +128,7 @@ var importsAndReExportsAtTop = {
|
|
|
122
128
|
var individualImports = {
|
|
123
129
|
meta: {
|
|
124
130
|
docs: {
|
|
125
|
-
description: "Enforce individual imports instead of grouped imports"
|
|
126
|
-
recommended: true
|
|
131
|
+
description: "Enforce individual imports instead of grouped imports"
|
|
127
132
|
},
|
|
128
133
|
fixable: "code",
|
|
129
134
|
messages: {
|
|
@@ -155,8 +160,7 @@ var individualImports = {
|
|
|
155
160
|
var individualReExports = {
|
|
156
161
|
meta: {
|
|
157
162
|
docs: {
|
|
158
|
-
description: "Enforce individual exports instead of grouped exports"
|
|
159
|
-
recommended: true
|
|
163
|
+
description: "Enforce individual exports instead of grouped exports"
|
|
160
164
|
},
|
|
161
165
|
fixable: "code",
|
|
162
166
|
messages: {
|
|
@@ -168,16 +172,15 @@ var individualReExports = {
|
|
|
168
172
|
create(context) {
|
|
169
173
|
return {
|
|
170
174
|
ExportNamedDeclaration(node) {
|
|
171
|
-
|
|
172
|
-
if (!exportNode.source || exportNode.specifiers.length <= 1)
|
|
175
|
+
if (!node.source || node.specifiers.length <= 1)
|
|
173
176
|
return;
|
|
174
177
|
context.report({
|
|
175
178
|
node,
|
|
176
179
|
messageId: "individualReExports",
|
|
177
180
|
fix(fixer) {
|
|
178
|
-
const source =
|
|
179
|
-
const typeKeyword =
|
|
180
|
-
const specifiers =
|
|
181
|
+
const source = node.source.value;
|
|
182
|
+
const typeKeyword = node.exportKind === "type" ? "type " : "";
|
|
183
|
+
const specifiers = node.specifiers.map((s) => {
|
|
181
184
|
const localName = s.local.type === "Identifier" ? s.local.name : s.local.value;
|
|
182
185
|
const exportedName = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
|
|
183
186
|
const name = localName === exportedName ? localName : `${localName} as ${exportedName}`;
|
|
@@ -191,12 +194,215 @@ var individualReExports = {
|
|
|
191
194
|
}
|
|
192
195
|
};
|
|
193
196
|
|
|
197
|
+
// src/rules/multilineUnionTypes/createFix.ts
|
|
198
|
+
function createFix(fixer, node, sourceCode) {
|
|
199
|
+
const types = node.types.map((t) => sourceCode.getText(t));
|
|
200
|
+
const formattedTypes = types.map((t) => ` | ${t}`).join("\n");
|
|
201
|
+
const result = `
|
|
202
|
+
${formattedTypes}`;
|
|
203
|
+
return fixer.replaceText(node, result);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/rules/multilineUnionTypes/isMultiline.ts
|
|
207
|
+
function isMultiline(unionType) {
|
|
208
|
+
const { start, end } = unionType.loc ?? {};
|
|
209
|
+
return start?.line !== end?.line;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/rules/multilineUnionTypes/index.ts
|
|
213
|
+
var multilineUnionTypes = {
|
|
214
|
+
meta: {
|
|
215
|
+
docs: {
|
|
216
|
+
description: "Enforce union types with multiple members to be on multiple lines"
|
|
217
|
+
},
|
|
218
|
+
fixable: "code",
|
|
219
|
+
messages: {
|
|
220
|
+
singleLine: "Union types with multiple members should be on multiple lines",
|
|
221
|
+
missingPipes: "Multiline union types should have leading pipes on each member"
|
|
222
|
+
},
|
|
223
|
+
schema: [],
|
|
224
|
+
type: "layout"
|
|
225
|
+
},
|
|
226
|
+
create(context) {
|
|
227
|
+
return {
|
|
228
|
+
TSUnionType(node) {
|
|
229
|
+
if (node.types.length < 2)
|
|
230
|
+
return;
|
|
231
|
+
const sourceCode = context.sourceCode;
|
|
232
|
+
const text = sourceCode.getText(node);
|
|
233
|
+
if (text.trim().startsWith("|"))
|
|
234
|
+
return;
|
|
235
|
+
if (!isMultiline(node)) {
|
|
236
|
+
context.report({
|
|
237
|
+
node,
|
|
238
|
+
messageId: "singleLine",
|
|
239
|
+
fix: (fixer) => createFix(fixer, node, sourceCode)
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
context.report({
|
|
244
|
+
node,
|
|
245
|
+
messageId: "missingPipes",
|
|
246
|
+
fix: (fixer) => createFix(fixer, node, sourceCode)
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// src/rules/singleLineImports/formatAttributes.ts
|
|
254
|
+
function formatAttributes(attributes) {
|
|
255
|
+
if (attributes.length === 0)
|
|
256
|
+
return "";
|
|
257
|
+
const formatted = attributes.map(
|
|
258
|
+
(attr) => {
|
|
259
|
+
const key = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
|
|
260
|
+
const value = attr.value.value;
|
|
261
|
+
return `${key}: '${value}'`;
|
|
262
|
+
}
|
|
263
|
+
).join(", ");
|
|
264
|
+
return ` with {${formatted}}`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/rules/singleLineImports/formatNamed.ts
|
|
268
|
+
function formatNamed(specifiers, sourceCode) {
|
|
269
|
+
return specifiers.map((s) => sourceCode.getText(s)).join(", ");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// src/rules/singleLineImports/formatSpecifiers.ts
|
|
273
|
+
function formatSpecifiers(declaration, sourceCode) {
|
|
274
|
+
const defaultSpecifier = declaration.specifiers.find(
|
|
275
|
+
(s) => s.type === "ImportDefaultSpecifier"
|
|
276
|
+
);
|
|
277
|
+
const namespaceSpecifier = declaration.specifiers.find(
|
|
278
|
+
(s) => s.type === "ImportNamespaceSpecifier"
|
|
279
|
+
);
|
|
280
|
+
const namedSpecifiers = declaration.specifiers.filter(
|
|
281
|
+
(s) => s.type === "ImportSpecifier"
|
|
282
|
+
);
|
|
283
|
+
if (namespaceSpecifier)
|
|
284
|
+
return `* as ${namespaceSpecifier.local.name}`;
|
|
285
|
+
if (defaultSpecifier && namedSpecifiers.length > 0)
|
|
286
|
+
return `${defaultSpecifier.local.name}, {${formatNamed(namedSpecifiers, sourceCode)}}`;
|
|
287
|
+
if (defaultSpecifier)
|
|
288
|
+
return defaultSpecifier.local.name;
|
|
289
|
+
if (namedSpecifiers.length === 0)
|
|
290
|
+
return "";
|
|
291
|
+
return `{${formatNamed(namedSpecifiers, sourceCode)}}`;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/rules/singleLineImports/createFix.ts
|
|
295
|
+
function createFix2(fixer, declaration, sourceCode) {
|
|
296
|
+
const source = declaration.source.value;
|
|
297
|
+
const prefix = declaration.importKind === "type" ? "import type " : "import ";
|
|
298
|
+
const specifiers = formatSpecifiers(declaration, sourceCode);
|
|
299
|
+
const attributes = formatAttributes(declaration.attributes);
|
|
300
|
+
if (specifiers === "") {
|
|
301
|
+
const result2 = `${prefix}'${source}'${attributes}`;
|
|
302
|
+
return fixer.replaceText(declaration, result2);
|
|
303
|
+
}
|
|
304
|
+
const result = `${prefix}${specifiers} from '${source}'${attributes}`;
|
|
305
|
+
return fixer.replaceText(declaration, result);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/rules/singleLineImports/isMultiline.ts
|
|
309
|
+
function isMultiline2(declaration) {
|
|
310
|
+
const { start, end } = declaration.loc ?? {};
|
|
311
|
+
return start?.line !== end?.line;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// src/rules/singleLineImports/index.ts
|
|
315
|
+
var singleLineImports = {
|
|
316
|
+
meta: {
|
|
317
|
+
docs: {
|
|
318
|
+
description: "Enforce imports to be on a single line"
|
|
319
|
+
},
|
|
320
|
+
fixable: "code",
|
|
321
|
+
messages: {
|
|
322
|
+
multiline: "Import should be on a single line"
|
|
323
|
+
},
|
|
324
|
+
schema: [],
|
|
325
|
+
type: "layout"
|
|
326
|
+
},
|
|
327
|
+
create(context) {
|
|
328
|
+
return {
|
|
329
|
+
ImportDeclaration(node) {
|
|
330
|
+
if (!isMultiline2(node))
|
|
331
|
+
return;
|
|
332
|
+
context.report({
|
|
333
|
+
node,
|
|
334
|
+
messageId: "multiline",
|
|
335
|
+
fix: (fixer) => createFix2(fixer, node, context.sourceCode)
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// src/rules/singleLineReExports/createFix.ts
|
|
343
|
+
function createFix3(fixer, declaration, sourceCode) {
|
|
344
|
+
const source = declaration.source.value;
|
|
345
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
346
|
+
const exported = declaration.exported ? `* as ${sourceCode.getText(declaration.exported)}` : "*";
|
|
347
|
+
const attributes2 = formatAttributes(declaration.attributes);
|
|
348
|
+
const result2 = `export ${exported} from '${source}'${attributes2}`;
|
|
349
|
+
return fixer.replaceText(declaration, result2);
|
|
350
|
+
}
|
|
351
|
+
const prefix = declaration.exportKind === "type" ? "export type " : "export ";
|
|
352
|
+
const specifiers = declaration.specifiers.map(
|
|
353
|
+
(s) => sourceCode.getText(s)
|
|
354
|
+
).join(", ");
|
|
355
|
+
const attributes = formatAttributes(declaration.attributes);
|
|
356
|
+
const result = `${prefix}{${specifiers}} from '${source}'${attributes}`;
|
|
357
|
+
return fixer.replaceText(declaration, result);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/rules/singleLineReExports/isMultiline.ts
|
|
361
|
+
function isMultiline3(declaration) {
|
|
362
|
+
const { start, end } = declaration.loc ?? {};
|
|
363
|
+
return start?.line !== end?.line;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// src/rules/singleLineReExports/index.ts
|
|
367
|
+
var singleLineReExports = {
|
|
368
|
+
meta: {
|
|
369
|
+
docs: {
|
|
370
|
+
description: "Enforce re-exports to be on a single line"
|
|
371
|
+
},
|
|
372
|
+
fixable: "code",
|
|
373
|
+
messages: {
|
|
374
|
+
multiline: "Re-export should be on a single line"
|
|
375
|
+
},
|
|
376
|
+
schema: [],
|
|
377
|
+
type: "layout"
|
|
378
|
+
},
|
|
379
|
+
create(context) {
|
|
380
|
+
const checkDeclaration = (node, declaration) => {
|
|
381
|
+
if (!declaration.source)
|
|
382
|
+
return;
|
|
383
|
+
if (!isMultiline3(declaration))
|
|
384
|
+
return;
|
|
385
|
+
context.report({
|
|
386
|
+
node,
|
|
387
|
+
messageId: "multiline",
|
|
388
|
+
fix: (fixer) => createFix3(fixer, declaration, context.sourceCode)
|
|
389
|
+
});
|
|
390
|
+
};
|
|
391
|
+
return {
|
|
392
|
+
ExportNamedDeclaration: (node) => checkDeclaration(node, node),
|
|
393
|
+
ExportAllDeclaration: (node) => checkDeclaration(node, node)
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
194
398
|
// src/rules/sortedImports/categorizeImport.ts
|
|
195
399
|
function categorizeImport(declaration) {
|
|
196
400
|
if (declaration.importKind === "type")
|
|
197
401
|
return "type";
|
|
198
402
|
if (declaration.specifiers.length === 0)
|
|
199
403
|
return "side-effect";
|
|
404
|
+
if (declaration.specifiers.some((s) => s.type === "ImportNamespaceSpecifier"))
|
|
405
|
+
return "namespace";
|
|
200
406
|
if (declaration.specifiers.some((s) => s.type === "ImportDefaultSpecifier"))
|
|
201
407
|
return "default";
|
|
202
408
|
return "named";
|
|
@@ -207,6 +413,12 @@ function getSortKey(declaration) {
|
|
|
207
413
|
const group = categorizeImport(declaration);
|
|
208
414
|
if (group === "side-effect")
|
|
209
415
|
return declaration.source.value;
|
|
416
|
+
if (group === "namespace") {
|
|
417
|
+
const namespaceSpecifier = declaration.specifiers.find(
|
|
418
|
+
(s) => s.type === "ImportNamespaceSpecifier"
|
|
419
|
+
);
|
|
420
|
+
return `*${namespaceSpecifier?.local.name ?? ""}`;
|
|
421
|
+
}
|
|
210
422
|
if (group === "default") {
|
|
211
423
|
const defaultSpecifier = declaration.specifiers.find(
|
|
212
424
|
(s) => s.type === "ImportDefaultSpecifier"
|
|
@@ -234,6 +446,7 @@ function compare(a, b) {
|
|
|
234
446
|
// src/rules/sortedImports/ImportGroupOrder.ts
|
|
235
447
|
var importGroupOrder = [
|
|
236
448
|
"side-effect",
|
|
449
|
+
"namespace",
|
|
237
450
|
"default",
|
|
238
451
|
"named",
|
|
239
452
|
"type"
|
|
@@ -349,6 +562,7 @@ function buildSortedCode(grouped, sourceCode) {
|
|
|
349
562
|
function groupImportsByType(categorized) {
|
|
350
563
|
const grouped = {
|
|
351
564
|
"side-effect": [],
|
|
565
|
+
namespace: [],
|
|
352
566
|
default: [],
|
|
353
567
|
named: [],
|
|
354
568
|
type: []
|
|
@@ -361,6 +575,7 @@ function groupImportsByType(categorized) {
|
|
|
361
575
|
// src/rules/sortedImports/createFix/sortImportGroups.ts
|
|
362
576
|
function sortImportGroups(grouped) {
|
|
363
577
|
grouped["side-effect"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
578
|
+
grouped["namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
364
579
|
grouped["default"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
365
580
|
grouped["named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
366
581
|
grouped["type"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
@@ -368,9 +583,8 @@ function sortImportGroups(grouped) {
|
|
|
368
583
|
|
|
369
584
|
// src/rules/sortedImports/createFix/index.ts
|
|
370
585
|
function createFixForGroup(fixer, importDeclarations, sourceCode) {
|
|
371
|
-
if (importDeclarations.length === 0)
|
|
586
|
+
if (importDeclarations.length === 0)
|
|
372
587
|
return null;
|
|
373
|
-
}
|
|
374
588
|
const categorized = categorizeImports(importDeclarations);
|
|
375
589
|
const grouped = groupImportsByType(categorized);
|
|
376
590
|
sortImportGroups(grouped);
|
|
@@ -382,7 +596,7 @@ function createFixForGroup(fixer, importDeclarations, sourceCode) {
|
|
|
382
596
|
sortedCode
|
|
383
597
|
);
|
|
384
598
|
}
|
|
385
|
-
function
|
|
599
|
+
function createFix4(fixer, importGroups, sourceCode) {
|
|
386
600
|
const fixes = [];
|
|
387
601
|
for (const group of importGroups) {
|
|
388
602
|
const fix = createFixForGroup(fixer, group, sourceCode);
|
|
@@ -415,8 +629,7 @@ function getImportGroups(programBody) {
|
|
|
415
629
|
var sortedImports = {
|
|
416
630
|
meta: {
|
|
417
631
|
docs: {
|
|
418
|
-
description: "Enforce sorted imports alphabetically"
|
|
419
|
-
recommended: true
|
|
632
|
+
description: "Enforce sorted imports alphabetically"
|
|
420
633
|
},
|
|
421
634
|
fixable: "code",
|
|
422
635
|
messages: {
|
|
@@ -450,7 +663,7 @@ var sortedImports = {
|
|
|
450
663
|
messageId: error.messageId,
|
|
451
664
|
fix(fixer) {
|
|
452
665
|
const sourceCode = context.sourceCode;
|
|
453
|
-
return
|
|
666
|
+
return createFix4(fixer, importGroups, sourceCode);
|
|
454
667
|
}
|
|
455
668
|
});
|
|
456
669
|
}
|
|
@@ -461,8 +674,11 @@ var sortedImports = {
|
|
|
461
674
|
|
|
462
675
|
// src/rules/sortedReExports/categorizeReExport.ts
|
|
463
676
|
function categorizeReExport(declaration) {
|
|
464
|
-
if (declaration.type === "ExportAllDeclaration")
|
|
677
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
678
|
+
if (declaration.exported)
|
|
679
|
+
return "re-export-namespace";
|
|
465
680
|
return "re-export-all";
|
|
681
|
+
}
|
|
466
682
|
if (declaration.exportKind === "type")
|
|
467
683
|
return "re-export-type";
|
|
468
684
|
return "re-export-named";
|
|
@@ -470,8 +686,14 @@ function categorizeReExport(declaration) {
|
|
|
470
686
|
|
|
471
687
|
// src/rules/sortedReExports/getSortKey.ts
|
|
472
688
|
function getSortKey2(declaration) {
|
|
473
|
-
|
|
689
|
+
const group = categorizeReExport(declaration);
|
|
690
|
+
if (declaration.type === "ExportAllDeclaration") {
|
|
691
|
+
if (group === "re-export-namespace") {
|
|
692
|
+
if (declaration.exported?.type === "Identifier")
|
|
693
|
+
return `*${declaration.exported.name}`;
|
|
694
|
+
}
|
|
474
695
|
return declaration.source.value;
|
|
696
|
+
}
|
|
475
697
|
const specifier = declaration.specifiers[0];
|
|
476
698
|
if (!specifier)
|
|
477
699
|
return "";
|
|
@@ -492,6 +714,7 @@ function categorizeReExports(declarations) {
|
|
|
492
714
|
// src/rules/sortedReExports/ReExportGroupOrder.ts
|
|
493
715
|
var reExportGroupOrder = [
|
|
494
716
|
"re-export-all",
|
|
717
|
+
"re-export-namespace",
|
|
495
718
|
"re-export-named",
|
|
496
719
|
"re-export-type"
|
|
497
720
|
];
|
|
@@ -554,7 +777,7 @@ function getNamedSpecifiers2(declaration) {
|
|
|
554
777
|
|
|
555
778
|
// src/rules/sortedReExports/isNamedReExport.ts
|
|
556
779
|
function isNamedReExport(x) {
|
|
557
|
-
return x.group !== "re-export-all";
|
|
780
|
+
return x.group !== "re-export-all" && x.group !== "re-export-namespace";
|
|
558
781
|
}
|
|
559
782
|
|
|
560
783
|
// src/rules/sortedReExports/checkSpecifiersSorting.ts
|
|
@@ -619,6 +842,7 @@ function buildSortedCode2(grouped, sourceCode) {
|
|
|
619
842
|
function groupReExportsByType(categorized) {
|
|
620
843
|
const grouped = {
|
|
621
844
|
"re-export-all": [],
|
|
845
|
+
"re-export-namespace": [],
|
|
622
846
|
"re-export-named": [],
|
|
623
847
|
"re-export-type": []
|
|
624
848
|
};
|
|
@@ -630,15 +854,15 @@ function groupReExportsByType(categorized) {
|
|
|
630
854
|
// src/rules/sortedReExports/createFix/sortExportGroups.ts
|
|
631
855
|
function sortExportGroups(grouped) {
|
|
632
856
|
grouped["re-export-all"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
857
|
+
grouped["re-export-namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
633
858
|
grouped["re-export-named"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
634
859
|
grouped["re-export-type"].sort((a, b) => compare(a.sortKey, b.sortKey));
|
|
635
860
|
}
|
|
636
861
|
|
|
637
862
|
// src/rules/sortedReExports/createFix/index.ts
|
|
638
863
|
function createFixForGroup2(fixer, reExportDeclarations, sourceCode) {
|
|
639
|
-
if (reExportDeclarations.length === 0)
|
|
864
|
+
if (reExportDeclarations.length === 0)
|
|
640
865
|
return null;
|
|
641
|
-
}
|
|
642
866
|
const categorized = categorizeReExports(reExportDeclarations);
|
|
643
867
|
const grouped = groupReExportsByType(categorized);
|
|
644
868
|
sortExportGroups(grouped);
|
|
@@ -650,7 +874,7 @@ function createFixForGroup2(fixer, reExportDeclarations, sourceCode) {
|
|
|
650
874
|
sortedCode
|
|
651
875
|
);
|
|
652
876
|
}
|
|
653
|
-
function
|
|
877
|
+
function createFix5(fixer, reExportGroups, sourceCode) {
|
|
654
878
|
const fixes = [];
|
|
655
879
|
for (const group of reExportGroups) {
|
|
656
880
|
const fix = createFixForGroup2(fixer, group, sourceCode);
|
|
@@ -686,8 +910,7 @@ function getReExportGroups(programBody) {
|
|
|
686
910
|
var sortedReExports = {
|
|
687
911
|
meta: {
|
|
688
912
|
docs: {
|
|
689
|
-
description: "Enforce sorted exports alphabetically"
|
|
690
|
-
recommended: true
|
|
913
|
+
description: "Enforce sorted exports alphabetically"
|
|
691
914
|
},
|
|
692
915
|
fixable: "code",
|
|
693
916
|
messages: {
|
|
@@ -721,7 +944,7 @@ var sortedReExports = {
|
|
|
721
944
|
messageId: error.messageId,
|
|
722
945
|
fix(fixer) {
|
|
723
946
|
const sourceCode = context.sourceCode;
|
|
724
|
-
return
|
|
947
|
+
return createFix5(fixer, reExportGroups, sourceCode);
|
|
725
948
|
}
|
|
726
949
|
});
|
|
727
950
|
}
|
|
@@ -731,7 +954,7 @@ var sortedReExports = {
|
|
|
731
954
|
};
|
|
732
955
|
|
|
733
956
|
// src/index.ts
|
|
734
|
-
var CONFIG =
|
|
957
|
+
var CONFIG = [
|
|
735
958
|
{
|
|
736
959
|
ignores: [
|
|
737
960
|
"src/graphql/sdk.ts",
|
|
@@ -749,8 +972,8 @@ var CONFIG = defineConfig([
|
|
|
749
972
|
eslint.configs.recommended,
|
|
750
973
|
react.configs.flat.recommended,
|
|
751
974
|
stylistic.configs.recommended,
|
|
752
|
-
typescript.configs.recommended,
|
|
753
|
-
typescript.configs.stylistic,
|
|
975
|
+
...typescript.configs.recommended,
|
|
976
|
+
...typescript.configs.stylistic,
|
|
754
977
|
{
|
|
755
978
|
plugins: {
|
|
756
979
|
"react-hooks": reactHooks
|
|
@@ -764,6 +987,9 @@ var CONFIG = defineConfig([
|
|
|
764
987
|
"imports-and-re-exports-at-top": importsAndReExportsAtTop,
|
|
765
988
|
"individual-imports": individualImports,
|
|
766
989
|
"individual-re-exports": individualReExports,
|
|
990
|
+
"multiline-union-types": multilineUnionTypes,
|
|
991
|
+
"single-line-imports": singleLineImports,
|
|
992
|
+
"single-line-re-exports": singleLineReExports,
|
|
767
993
|
"sorted-imports": sortedImports,
|
|
768
994
|
"sorted-re-exports": sortedReExports
|
|
769
995
|
}
|
|
@@ -773,6 +999,9 @@ var CONFIG = defineConfig([
|
|
|
773
999
|
"@borela-tech/imports-and-re-exports-at-top": "error",
|
|
774
1000
|
"@borela-tech/individual-imports": "error",
|
|
775
1001
|
"@borela-tech/individual-re-exports": "error",
|
|
1002
|
+
"@borela-tech/multiline-union-types": "error",
|
|
1003
|
+
"@borela-tech/single-line-imports": "error",
|
|
1004
|
+
"@borela-tech/single-line-re-exports": "error",
|
|
776
1005
|
"@borela-tech/sorted-imports": "error",
|
|
777
1006
|
"@borela-tech/sorted-re-exports": "error"
|
|
778
1007
|
}
|
|
@@ -851,10 +1080,14 @@ var CONFIG = defineConfig([
|
|
|
851
1080
|
{ beforeStatementContinuationChars: "always" }
|
|
852
1081
|
],
|
|
853
1082
|
"@typescript-eslint/no-empty-function": "off",
|
|
854
|
-
"@typescript-eslint/consistent-indexed-object-style": "off"
|
|
1083
|
+
"@typescript-eslint/consistent-indexed-object-style": "off",
|
|
1084
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
1085
|
+
"error",
|
|
1086
|
+
{ fixStyle: "separate-type-imports" }
|
|
1087
|
+
]
|
|
855
1088
|
}
|
|
856
1089
|
}
|
|
857
|
-
]
|
|
1090
|
+
];
|
|
858
1091
|
export {
|
|
859
1092
|
CONFIG
|
|
860
1093
|
};
|