@borela-tech/eslint-config 2.2.0 → 2.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.js DELETED
@@ -1,1094 +0,0 @@
1
- // src/index.ts
2
- import eslint from "@eslint/js";
3
- import react from "eslint-plugin-react";
4
- import reactHooks from "eslint-plugin-react-hooks";
5
- import stylistic from "@stylistic/eslint-plugin";
6
- import typescript from "typescript-eslint";
7
-
8
- // src/rules/importsAndReExportsAtTop/getStatementType.ts
9
- function getStatementType(statement) {
10
- if (statement.type === "ImportDeclaration")
11
- return "import";
12
- if (statement.type === "ExportAllDeclaration")
13
- return "re-export";
14
- if (statement.type === "ExportNamedDeclaration") {
15
- if (statement.source !== null)
16
- return "re-export";
17
- }
18
- return "other";
19
- }
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
-
35
- // src/rules/importsAndReExportsAtTop/categorizeStatements.ts
36
- function categorizeStatements(statements) {
37
- const result = {
38
- imports: [],
39
- reExports: [],
40
- other: []
41
- };
42
- for (const statement of statements) {
43
- const type = getStatementType(statement);
44
- if (type === "import" && isImportDeclaration(statement))
45
- result.imports.push(statement);
46
- else if (type === "re-export" && isReExport(statement))
47
- result.reExports.push(statement);
48
- else
49
- result.other.push(statement);
50
- }
51
- return result;
52
- }
53
-
54
- // src/rules/importsAndReExportsAtTop/findStatementIndices.ts
55
- function findStatementIndices(statements) {
56
- let firstRegularStatement = -1;
57
- let lastImport = -1;
58
- let lastReExport = -1;
59
- for (let i = 0; i < statements.length; i++) {
60
- const type = getStatementType(statements[i]);
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;
67
- }
68
- return { firstRegularStatement, lastImport, lastReExport };
69
- }
70
-
71
- // src/rules/importsAndReExportsAtTop/generateSortedText.ts
72
- function generateSortedText(context, categories) {
73
- const allStatements = [
74
- ...categories.imports,
75
- ...categories.reExports,
76
- ...categories.other
77
- ];
78
- return allStatements.map(
79
- (node) => context.sourceCode.getText(node)
80
- ).join("\n");
81
- }
82
-
83
- // src/rules/importsAndReExportsAtTop/hasViolation.ts
84
- function hasViolation(indices, categories) {
85
- const { firstRegularStatement, lastImport, lastReExport } = indices;
86
- if (categories.imports.length === 0 && categories.reExports.length === 0)
87
- 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;
91
- }
92
-
93
- // src/rules/importsAndReExportsAtTop/index.ts
94
- var importsAndReExportsAtTop = {
95
- meta: {
96
- type: "suggestion",
97
- docs: {
98
- description: "Enforce imports and re-exports at the top of the file"
99
- },
100
- fixable: "code",
101
- messages: {
102
- importsAndReExportsAtTop: "Imports and re-exports should be at the top of the file."
103
- },
104
- schema: []
105
- },
106
- create(context) {
107
- return {
108
- Program(node) {
109
- const statements = node.body;
110
- const categories = categorizeStatements(statements);
111
- const indices = findStatementIndices(statements);
112
- if (!hasViolation(indices, categories))
113
- return;
114
- context.report({
115
- node,
116
- messageId: "importsAndReExportsAtTop",
117
- fix(fixer) {
118
- const sortedText = generateSortedText(context, categories);
119
- return fixer.replaceText(node, sortedText);
120
- }
121
- });
122
- }
123
- };
124
- }
125
- };
126
-
127
- // src/rules/individualImports.ts
128
- var individualImports = {
129
- meta: {
130
- docs: {
131
- description: "Enforce individual imports instead of grouped imports"
132
- },
133
- fixable: "code",
134
- messages: {
135
- individualImports: "Use individual imports instead of grouped imports."
136
- },
137
- schema: [],
138
- type: "suggestion"
139
- },
140
- create(context) {
141
- return {
142
- ImportDeclaration(node) {
143
- if (node.specifiers.length <= 1)
144
- return;
145
- context.report({
146
- node,
147
- messageId: "individualImports",
148
- fix(fixer) {
149
- const source = node.source.raw;
150
- const specifiers = node.specifiers.filter((s) => s.type === "ImportSpecifier").map((s) => `import {${s.local.name}} from ${source}`).join("\n");
151
- return fixer.replaceText(node, specifiers);
152
- }
153
- });
154
- }
155
- };
156
- }
157
- };
158
-
159
- // src/rules/individualReExports.ts
160
- var individualReExports = {
161
- meta: {
162
- docs: {
163
- description: "Enforce individual exports instead of grouped exports"
164
- },
165
- fixable: "code",
166
- messages: {
167
- individualReExports: "Use individual exports instead of grouped exports."
168
- },
169
- schema: [],
170
- type: "suggestion"
171
- },
172
- create(context) {
173
- return {
174
- ExportNamedDeclaration(node) {
175
- if (!node.source || node.specifiers.length <= 1)
176
- return;
177
- context.report({
178
- node,
179
- messageId: "individualReExports",
180
- fix(fixer) {
181
- const source = node.source.value;
182
- const typeKeyword = node.exportKind === "type" ? "type " : "";
183
- const specifiers = node.specifiers.map((s) => {
184
- const localName = s.local.type === "Identifier" ? s.local.name : s.local.value;
185
- const exportedName = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
186
- const name = localName === exportedName ? localName : `${localName} as ${exportedName}`;
187
- return `export ${typeKeyword}{${name}} from '${source}'`;
188
- }).join("\n");
189
- return fixer.replaceText(node, specifiers);
190
- }
191
- });
192
- }
193
- };
194
- }
195
- };
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
-
398
- // src/rules/sortedImports/categorizeImport.ts
399
- function categorizeImport(declaration) {
400
- if (declaration.importKind === "type")
401
- return "type";
402
- if (declaration.specifiers.length === 0)
403
- return "side-effect";
404
- if (declaration.specifiers.some((s) => s.type === "ImportNamespaceSpecifier"))
405
- return "namespace";
406
- if (declaration.specifiers.some((s) => s.type === "ImportDefaultSpecifier"))
407
- return "default";
408
- return "named";
409
- }
410
-
411
- // src/rules/sortedImports/getSortKey.ts
412
- function getSortKey(declaration) {
413
- const group = categorizeImport(declaration);
414
- if (group === "side-effect")
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
- }
422
- if (group === "default") {
423
- const defaultSpecifier = declaration.specifiers.find(
424
- (s) => s.type === "ImportDefaultSpecifier"
425
- );
426
- return defaultSpecifier?.local.name ?? "";
427
- }
428
- const specifier = declaration.specifiers[0];
429
- return specifier.local.name;
430
- }
431
-
432
- // src/rules/sortedImports/categorizeImports.ts
433
- function categorizeImports(declarations) {
434
- return declarations.map((declaration) => ({
435
- declaration,
436
- group: categorizeImport(declaration),
437
- sortKey: getSortKey(declaration)
438
- }));
439
- }
440
-
441
- // src/lib/compare.ts
442
- function compare(a, b) {
443
- return a.localeCompare(b, "en", { sensitivity: "case" });
444
- }
445
-
446
- // src/rules/sortedImports/ImportGroupOrder.ts
447
- var importGroupOrder = [
448
- "side-effect",
449
- "namespace",
450
- "default",
451
- "named",
452
- "type"
453
- ];
454
-
455
- // src/rules/sortedImports/checkAlphabeticalSorting.ts
456
- function checkAlphabeticalSorting(categorized) {
457
- const errors = [];
458
- for (const group of importGroupOrder) {
459
- const groupImports = categorized.filter((c) => c.group === group);
460
- const sorted = [...groupImports].sort((a, b) => compare(a.sortKey, b.sortKey));
461
- for (let i = 0; i < groupImports.length; i++) {
462
- if (groupImports[i] !== sorted[i]) {
463
- errors.push({
464
- node: groupImports[i].declaration,
465
- messageId: "sortedImports"
466
- });
467
- }
468
- }
469
- }
470
- return errors;
471
- }
472
-
473
- // src/rules/sortedImports/checkGroupOrdering.ts
474
- function checkGroupOrdering(categorized) {
475
- const errors = [];
476
- let currentGroupIndex = -1;
477
- for (const { declaration, group } of categorized) {
478
- const groupIndex = importGroupOrder.indexOf(group);
479
- if (groupIndex < currentGroupIndex) {
480
- errors.push({
481
- node: declaration,
482
- messageId: "wrongGroup"
483
- });
484
- } else
485
- currentGroupIndex = groupIndex;
486
- }
487
- return errors;
488
- }
489
-
490
- // src/rules/sortedImports/getSpecifierName.ts
491
- function getSpecifierName(specifier) {
492
- return specifier.imported.type === "Identifier" ? specifier.imported.name : String(specifier.imported.value);
493
- }
494
-
495
- // src/rules/sortedImports/areSpecifiersSorted.ts
496
- function areSpecifiersSorted(specifiers) {
497
- const names = specifiers.map((s) => getSpecifierName(s));
498
- const sorted = [...names].sort((a, b) => compare(a, b));
499
- return names.every((name, i) => name === sorted[i]);
500
- }
501
-
502
- // src/rules/sortedImports/getNamedSpecifiers.ts
503
- function getNamedSpecifiers(declaration) {
504
- return declaration.specifiers.filter(
505
- (s) => s.type === "ImportSpecifier"
506
- );
507
- }
508
-
509
- // src/rules/sortedImports/checkSpecifiersSorting.ts
510
- function checkSpecifiersSorting(categorized) {
511
- const errors = [];
512
- const namedImports = categorized.filter((c) => c.group === "named");
513
- for (const { declaration } of namedImports) {
514
- const specifiers = getNamedSpecifiers(declaration);
515
- if (specifiers.length > 1 && !areSpecifiersSorted(specifiers)) {
516
- errors.push({
517
- node: declaration,
518
- messageId: "sortedNames"
519
- });
520
- }
521
- }
522
- return errors;
523
- }
524
-
525
- // src/rules/sortedImports/sortSpecifiersText.ts
526
- function sortSpecifiersText(specifiers, sourceCode) {
527
- const sorted = [...specifiers].sort((a, b) => {
528
- const nameA = getSpecifierName(a);
529
- const nameB = getSpecifierName(b);
530
- return compare(nameA, nameB);
531
- });
532
- return sorted.map((s) => sourceCode.getText(s)).join(", ");
533
- }
534
-
535
- // src/rules/sortedImports/createFix/formatNamedImport.ts
536
- function formatNamedImport(declaration, sourceCode) {
537
- const specifiers = getNamedSpecifiers(declaration);
538
- if (specifiers.length > 1 && !areSpecifiersSorted(specifiers)) {
539
- const sortedSpecifiers = sortSpecifiersText(specifiers, sourceCode);
540
- const source = declaration.source.value;
541
- const prefix = declaration.importKind === "type" ? "import type " : "import ";
542
- return `${prefix}{${sortedSpecifiers}} from '${source}'`;
543
- }
544
- return sourceCode.getText(declaration);
545
- }
546
-
547
- // src/rules/sortedImports/createFix/buildSortedCode.ts
548
- function buildSortedCode(grouped, sourceCode) {
549
- const sortedCode = [];
550
- for (const group of importGroupOrder) {
551
- for (const { declaration } of grouped[group]) {
552
- if (group === "named" || group === "type")
553
- sortedCode.push(formatNamedImport(declaration, sourceCode));
554
- else
555
- sortedCode.push(sourceCode.getText(declaration));
556
- }
557
- }
558
- return sortedCode;
559
- }
560
-
561
- // src/rules/sortedImports/createFix/groupImportsByType.ts
562
- function groupImportsByType(categorized) {
563
- const grouped = {
564
- "side-effect": [],
565
- namespace: [],
566
- default: [],
567
- named: [],
568
- type: []
569
- };
570
- for (const item of categorized)
571
- grouped[item.group].push(item);
572
- return grouped;
573
- }
574
-
575
- // src/rules/sortedImports/createFix/sortImportGroups.ts
576
- function sortImportGroups(grouped) {
577
- grouped["side-effect"].sort((a, b) => compare(a.sortKey, b.sortKey));
578
- grouped["namespace"].sort((a, b) => compare(a.sortKey, b.sortKey));
579
- grouped["default"].sort((a, b) => compare(a.sortKey, b.sortKey));
580
- grouped["named"].sort((a, b) => compare(a.sortKey, b.sortKey));
581
- grouped["type"].sort((a, b) => compare(a.sortKey, b.sortKey));
582
- }
583
-
584
- // src/rules/sortedImports/createFix/index.ts
585
- function createFixForGroup(fixer, importDeclarations, sourceCode) {
586
- if (importDeclarations.length === 0)
587
- return null;
588
- const categorized = categorizeImports(importDeclarations);
589
- const grouped = groupImportsByType(categorized);
590
- sortImportGroups(grouped);
591
- const sortedCode = buildSortedCode(grouped, sourceCode).join("\n");
592
- const firstImport = importDeclarations[0];
593
- const lastImport = importDeclarations[importDeclarations.length - 1];
594
- return fixer.replaceTextRange(
595
- [firstImport.range[0], lastImport.range[1]],
596
- sortedCode
597
- );
598
- }
599
- function createFix4(fixer, importGroups, sourceCode) {
600
- const fixes = [];
601
- for (const group of importGroups) {
602
- const fix = createFixForGroup(fixer, group, sourceCode);
603
- if (fix)
604
- fixes.push(fix);
605
- }
606
- return fixes;
607
- }
608
-
609
- // src/rules/sortedImports/getImportGroups.ts
610
- function getImportGroups(programBody) {
611
- const groups = [];
612
- let currentGroup = [];
613
- for (const statement of programBody) {
614
- if (statement.type === "ImportDeclaration") {
615
- currentGroup.push(statement);
616
- continue;
617
- }
618
- if (currentGroup.length > 0) {
619
- groups.push(currentGroup);
620
- currentGroup = [];
621
- }
622
- }
623
- if (currentGroup.length > 0)
624
- groups.push(currentGroup);
625
- return groups;
626
- }
627
-
628
- // src/rules/sortedImports/index.ts
629
- var sortedImports = {
630
- meta: {
631
- docs: {
632
- description: "Enforce sorted imports alphabetically"
633
- },
634
- fixable: "code",
635
- messages: {
636
- sortedImports: "Imports should be sorted alphabetically",
637
- sortedNames: "Named imports should be sorted alphabetically",
638
- wrongGroup: "Import is in wrong group"
639
- },
640
- schema: [],
641
- type: "suggestion"
642
- },
643
- create(context) {
644
- return {
645
- Program(node) {
646
- const body = node.body;
647
- const importGroups = getImportGroups(body);
648
- if (importGroups.length === 0)
649
- return;
650
- const allErrors = [];
651
- for (const group of importGroups) {
652
- const categorized = categorizeImports(group);
653
- const errors = [
654
- ...checkGroupOrdering(categorized),
655
- ...checkAlphabeticalSorting(categorized),
656
- ...checkSpecifiersSorting(categorized)
657
- ];
658
- allErrors.push(...errors);
659
- }
660
- for (const error of allErrors) {
661
- context.report({
662
- node: error.node,
663
- messageId: error.messageId,
664
- fix(fixer) {
665
- const sourceCode = context.sourceCode;
666
- return createFix4(fixer, importGroups, sourceCode);
667
- }
668
- });
669
- }
670
- }
671
- };
672
- }
673
- };
674
-
675
- // src/rules/sortedReExports/categorizeReExport.ts
676
- function categorizeReExport(declaration) {
677
- if (declaration.type === "ExportAllDeclaration") {
678
- if (declaration.exported)
679
- return "re-export-namespace";
680
- return "re-export-all";
681
- }
682
- if (declaration.exportKind === "type")
683
- return "re-export-type";
684
- return "re-export-named";
685
- }
686
-
687
- // src/rules/sortedReExports/getSortKey.ts
688
- function getSortKey2(declaration) {
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
- }
695
- return declaration.source.value;
696
- }
697
- const specifier = declaration.specifiers[0];
698
- if (!specifier)
699
- return "";
700
- return specifier.local.type === "Identifier" ? specifier.local.name : specifier.local.value;
701
- }
702
-
703
- // src/rules/sortedReExports/categorizeReExports.ts
704
- function categorizeReExports(declarations) {
705
- return declarations.map((declaration) => {
706
- return {
707
- declaration,
708
- group: categorizeReExport(declaration),
709
- sortKey: getSortKey2(declaration)
710
- };
711
- });
712
- }
713
-
714
- // src/rules/sortedReExports/ReExportGroupOrder.ts
715
- var reExportGroupOrder = [
716
- "re-export-all",
717
- "re-export-namespace",
718
- "re-export-named",
719
- "re-export-type"
720
- ];
721
-
722
- // src/rules/sortedReExports/checkAlphabeticalSorting.ts
723
- function checkAlphabeticalSorting2(categorized) {
724
- const errors = [];
725
- for (const group of reExportGroupOrder) {
726
- const groupReExports = categorized.filter((c) => c.group === group);
727
- const sorted = [...groupReExports].sort(
728
- (a, b) => compare(a.sortKey, b.sortKey)
729
- );
730
- for (let i = 0; i < groupReExports.length; i++) {
731
- if (groupReExports[i] !== sorted[i]) {
732
- errors.push({
733
- node: groupReExports[i].declaration,
734
- messageId: "sortedReExports"
735
- });
736
- }
737
- }
738
- }
739
- return errors;
740
- }
741
-
742
- // src/rules/sortedReExports/checkGroupOrdering.ts
743
- function checkGroupOrdering2(categorized) {
744
- const errors = [];
745
- let currentGroupIndex = -1;
746
- for (const { declaration, group } of categorized) {
747
- const groupIndex = reExportGroupOrder.indexOf(group);
748
- if (groupIndex < currentGroupIndex) {
749
- errors.push({
750
- node: declaration,
751
- messageId: "wrongGroup"
752
- });
753
- } else
754
- currentGroupIndex = groupIndex;
755
- }
756
- return errors;
757
- }
758
-
759
- // src/rules/sortedReExports/getSpecifierName.ts
760
- function getSpecifierName2(specifier) {
761
- return specifier.local.type === "Identifier" ? specifier.local.name : String(specifier.local.value);
762
- }
763
-
764
- // src/rules/sortedReExports/areSpecifiersSorted.ts
765
- function areSpecifiersSorted2(specifiers) {
766
- const names = specifiers.map((s) => getSpecifierName2(s));
767
- const sorted = [...names].sort((a, b) => compare(a, b));
768
- return names.every((name, i) => name === sorted[i]);
769
- }
770
-
771
- // src/rules/sortedReExports/getNamedSpecifiers.ts
772
- function getNamedSpecifiers2(declaration) {
773
- return declaration.specifiers.filter(
774
- (s) => s.type === "ExportSpecifier" && s.local.type === "Identifier"
775
- );
776
- }
777
-
778
- // src/rules/sortedReExports/isNamedReExport.ts
779
- function isNamedReExport(x) {
780
- return x.group !== "re-export-all" && x.group !== "re-export-namespace";
781
- }
782
-
783
- // src/rules/sortedReExports/checkSpecifiersSorting.ts
784
- function checkSpecifiersSorting2(categorized) {
785
- const errors = [];
786
- const namedReExports = categorized.filter(isNamedReExport);
787
- for (const { declaration } of namedReExports) {
788
- const specifiers = getNamedSpecifiers2(declaration);
789
- const isSorted = areSpecifiersSorted2(specifiers);
790
- if (specifiers.length > 1 && !isSorted) {
791
- errors.push({
792
- node: declaration,
793
- messageId: "sortedNames"
794
- });
795
- }
796
- }
797
- return errors;
798
- }
799
-
800
- // src/rules/sortedReExports/sortSpecifiersText.ts
801
- function sortSpecifiersText2(specifiers, sourceCode) {
802
- const sorted = [...specifiers].sort((a, b) => {
803
- const nameA = getSpecifierName2(a);
804
- const nameB = getSpecifierName2(b);
805
- return compare(nameA, nameB);
806
- });
807
- return sorted.map((s) => sourceCode.getText(s)).join(", ");
808
- }
809
-
810
- // src/rules/sortedReExports/createFix/formatNamedReExport.ts
811
- function formatNamedReExport(declaration, sourceCode) {
812
- const specifiers = getNamedSpecifiers2(declaration);
813
- if (specifiers.length > 1 && !areSpecifiersSorted2(specifiers)) {
814
- const sortedSpecifiers = sortSpecifiersText2(specifiers, sourceCode);
815
- const source = declaration.source.value;
816
- const prefix = declaration.exportKind === "type" ? "export type " : "export ";
817
- return `${prefix}{${sortedSpecifiers}} from '${source}'`;
818
- }
819
- return sourceCode.getText(declaration);
820
- }
821
-
822
- // src/rules/sortedReExports/createFix/buildSortedCode.ts
823
- function buildSortedCode2(grouped, sourceCode) {
824
- const sortedCode = [];
825
- for (const group of reExportGroupOrder) {
826
- for (const item of grouped[group]) {
827
- if (isNamedReExport(item)) {
828
- sortedCode.push(
829
- formatNamedReExport(
830
- item.declaration,
831
- sourceCode
832
- )
833
- );
834
- } else
835
- sortedCode.push(sourceCode.getText(item.declaration));
836
- }
837
- }
838
- return sortedCode;
839
- }
840
-
841
- // src/rules/sortedReExports/createFix/groupReExportsByType.ts
842
- function groupReExportsByType(categorized) {
843
- const grouped = {
844
- "re-export-all": [],
845
- "re-export-namespace": [],
846
- "re-export-named": [],
847
- "re-export-type": []
848
- };
849
- for (const item of categorized)
850
- grouped[item.group].push(item);
851
- return grouped;
852
- }
853
-
854
- // src/rules/sortedReExports/createFix/sortExportGroups.ts
855
- function sortExportGroups(grouped) {
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));
858
- grouped["re-export-named"].sort((a, b) => compare(a.sortKey, b.sortKey));
859
- grouped["re-export-type"].sort((a, b) => compare(a.sortKey, b.sortKey));
860
- }
861
-
862
- // src/rules/sortedReExports/createFix/index.ts
863
- function createFixForGroup2(fixer, reExportDeclarations, sourceCode) {
864
- if (reExportDeclarations.length === 0)
865
- return null;
866
- const categorized = categorizeReExports(reExportDeclarations);
867
- const grouped = groupReExportsByType(categorized);
868
- sortExportGroups(grouped);
869
- const sortedCode = buildSortedCode2(grouped, sourceCode).join("\n");
870
- const firstReExport = reExportDeclarations[0];
871
- const lastReExport = reExportDeclarations[reExportDeclarations.length - 1];
872
- return fixer.replaceTextRange(
873
- [firstReExport.range[0], lastReExport.range[1]],
874
- sortedCode
875
- );
876
- }
877
- function createFix5(fixer, reExportGroups, sourceCode) {
878
- const fixes = [];
879
- for (const group of reExportGroups) {
880
- const fix = createFixForGroup2(fixer, group, sourceCode);
881
- if (fix)
882
- fixes.push(fix);
883
- }
884
- return fixes;
885
- }
886
-
887
- // src/rules/sortedReExports/getReExportGroups.ts
888
- function isReExportDeclaration(statement) {
889
- return statement.type === "ExportNamedDeclaration" && statement.source !== null || statement.type === "ExportAllDeclaration";
890
- }
891
- function getReExportGroups(programBody) {
892
- const groups = [];
893
- let currentGroup = [];
894
- for (const statement of programBody) {
895
- if (isReExportDeclaration(statement)) {
896
- currentGroup.push(statement);
897
- continue;
898
- }
899
- if (currentGroup.length > 0) {
900
- groups.push(currentGroup);
901
- currentGroup = [];
902
- }
903
- }
904
- if (currentGroup.length > 0)
905
- groups.push(currentGroup);
906
- return groups;
907
- }
908
-
909
- // src/rules/sortedReExports/index.ts
910
- var sortedReExports = {
911
- meta: {
912
- docs: {
913
- description: "Enforce sorted exports alphabetically"
914
- },
915
- fixable: "code",
916
- messages: {
917
- sortedReExports: "Exports should be sorted alphabetically",
918
- sortedNames: "Named exports should be sorted alphabetically",
919
- wrongGroup: "Export is in wrong group"
920
- },
921
- schema: [],
922
- type: "suggestion"
923
- },
924
- create(context) {
925
- return {
926
- Program(node) {
927
- const body = node.body;
928
- const reExportGroups = getReExportGroups(body);
929
- if (reExportGroups.length === 0)
930
- return;
931
- const allErrors = [];
932
- for (const group of reExportGroups) {
933
- const categorized = categorizeReExports(group);
934
- const errors = [
935
- ...checkGroupOrdering2(categorized),
936
- ...checkAlphabeticalSorting2(categorized),
937
- ...checkSpecifiersSorting2(categorized)
938
- ];
939
- allErrors.push(...errors);
940
- }
941
- for (const error of allErrors) {
942
- context.report({
943
- node: error.node,
944
- messageId: error.messageId,
945
- fix(fixer) {
946
- const sourceCode = context.sourceCode;
947
- return createFix5(fixer, reExportGroups, sourceCode);
948
- }
949
- });
950
- }
951
- }
952
- };
953
- }
954
- };
955
-
956
- // src/index.ts
957
- var CONFIG = [
958
- {
959
- ignores: [
960
- "src/graphql/sdk.ts",
961
- "**/node_modules/**",
962
- "**/dist/**"
963
- ]
964
- },
965
- {
966
- settings: {
967
- react: {
968
- version: "19"
969
- }
970
- }
971
- },
972
- eslint.configs.recommended,
973
- react.configs.flat.recommended,
974
- stylistic.configs.recommended,
975
- ...typescript.configs.recommended,
976
- ...typescript.configs.stylistic,
977
- {
978
- plugins: {
979
- "react-hooks": reactHooks
980
- },
981
- rules: reactHooks.configs.recommended.rules
982
- },
983
- {
984
- plugins: {
985
- "@borela-tech": {
986
- rules: {
987
- "imports-and-re-exports-at-top": importsAndReExportsAtTop,
988
- "individual-imports": individualImports,
989
- "individual-re-exports": individualReExports,
990
- "multiline-union-types": multilineUnionTypes,
991
- "single-line-imports": singleLineImports,
992
- "single-line-re-exports": singleLineReExports,
993
- "sorted-imports": sortedImports,
994
- "sorted-re-exports": sortedReExports
995
- }
996
- }
997
- },
998
- rules: {
999
- "@borela-tech/imports-and-re-exports-at-top": "error",
1000
- "@borela-tech/individual-imports": "error",
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",
1005
- "@borela-tech/sorted-imports": "error",
1006
- "@borela-tech/sorted-re-exports": "error"
1007
- }
1008
- },
1009
- {
1010
- rules: {
1011
- "capitalized-comments": [
1012
- "error",
1013
- "always",
1014
- { ignoreConsecutiveComments: true }
1015
- ],
1016
- "react/react-in-jsx-scope": "off",
1017
- "@stylistic/arrow-parens": [
1018
- "error",
1019
- "as-needed"
1020
- ],
1021
- "@stylistic/array-bracket-newline": [
1022
- "error",
1023
- "consistent"
1024
- ],
1025
- "@stylistic/array-bracket-spacing": [
1026
- "error",
1027
- "never"
1028
- ],
1029
- "@stylistic/array-element-newline": [
1030
- "error",
1031
- "consistent"
1032
- ],
1033
- "@stylistic/block-spacing": "off",
1034
- "@stylistic/brace-style": [
1035
- "error",
1036
- "1tbs",
1037
- { allowSingleLine: true }
1038
- ],
1039
- "@stylistic/indent": [
1040
- "error",
1041
- 2,
1042
- { ignoredNodes: ["TSMappedType > *"] }
1043
- ],
1044
- "@stylistic/jsx-tag-spacing": [
1045
- "error",
1046
- {
1047
- afterOpening: "never",
1048
- beforeClosing: "never",
1049
- beforeSelfClosing: "never",
1050
- closingSlash: "never"
1051
- }
1052
- ],
1053
- "@stylistic/jsx-wrap-multilines": "off",
1054
- "@stylistic/lines-between-class-members": "off",
1055
- "@stylistic/object-curly-newline": [
1056
- "error",
1057
- { consistent: true }
1058
- ],
1059
- "@stylistic/object-curly-spacing": [
1060
- "error",
1061
- "never"
1062
- ],
1063
- "@stylistic/operator-linebreak": [
1064
- "error",
1065
- "before",
1066
- { overrides: { "=": "after" } }
1067
- ],
1068
- "@stylistic/quotes": [
1069
- "error",
1070
- "single",
1071
- { avoidEscape: true }
1072
- ],
1073
- "@stylistic/quote-props": [
1074
- "error",
1075
- "as-needed"
1076
- ],
1077
- "@stylistic/semi": [
1078
- "error",
1079
- "never",
1080
- { beforeStatementContinuationChars: "always" }
1081
- ],
1082
- "@typescript-eslint/no-empty-function": "off",
1083
- "@typescript-eslint/consistent-indexed-object-style": "off",
1084
- "@typescript-eslint/consistent-type-imports": [
1085
- "error",
1086
- { fixStyle: "separate-type-imports" }
1087
- ]
1088
- }
1089
- }
1090
- ];
1091
- export {
1092
- CONFIG
1093
- };
1094
- //# sourceMappingURL=index.js.map