@borela-tech/eslint-config 2.2.2 → 2.4.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.
Files changed (107) hide show
  1. package/README.md +308 -19
  2. package/dist/index.d.ts +5 -0
  3. package/dist/index.mjs +3864 -811
  4. package/dist/index.mjs.map +1 -1
  5. package/jest.config.ts +19 -0
  6. package/package.json +15 -9
  7. package/vite.config.ts +41 -0
  8. package/bin/build +0 -9
  9. package/bin/lint +0 -14
  10. package/bin/publish +0 -12
  11. package/bin/test +0 -12
  12. package/bin/typecheck +0 -8
  13. package/dist/index.d.mts +0 -7
  14. package/src/index.ts +0 -149
  15. package/src/lib/ReExportDeclaration.ts +0 -5
  16. package/src/lib/ReplacementRange.ts +0 -4
  17. package/src/lib/compare.ts +0 -3
  18. package/src/rules/__tests__/dedent/countLeadingSpaces.ts +0 -4
  19. package/src/rules/__tests__/dedent/findMinIndent.ts +0 -7
  20. package/src/rules/__tests__/dedent/index.ts +0 -17
  21. package/src/rules/__tests__/dedent/interpolate.ts +0 -11
  22. package/src/rules/__tests__/dedent/removeEmptyPrefix.ts +0 -6
  23. package/src/rules/__tests__/dedent/removeEmptySuffix.ts +0 -6
  24. package/src/rules/__tests__/dedent/removeIndent.ts +0 -3
  25. package/src/rules/__tests__/importsAndReExportsAtTop.test.ts +0 -88
  26. package/src/rules/__tests__/individualImports.test.ts +0 -44
  27. package/src/rules/__tests__/individualReExports.test.ts +0 -64
  28. package/src/rules/__tests__/multilineUnionTypes.test.ts +0 -75
  29. package/src/rules/__tests__/singleLineImports.test.ts +0 -129
  30. package/src/rules/__tests__/singleLineReExports.test.ts +0 -100
  31. package/src/rules/__tests__/sortedImports.test.ts +0 -227
  32. package/src/rules/__tests__/sortedReExports.test.ts +0 -220
  33. package/src/rules/importsAndReExportsAtTop/CategorizedStatements.ts +0 -8
  34. package/src/rules/importsAndReExportsAtTop/StatementIndices.ts +0 -5
  35. package/src/rules/importsAndReExportsAtTop/categorizeStatements.ts +0 -28
  36. package/src/rules/importsAndReExportsAtTop/findStatementIndices.ts +0 -25
  37. package/src/rules/importsAndReExportsAtTop/generateSortedText.ts +0 -16
  38. package/src/rules/importsAndReExportsAtTop/getStatementType.ts +0 -17
  39. package/src/rules/importsAndReExportsAtTop/hasViolation.ts +0 -25
  40. package/src/rules/importsAndReExportsAtTop/index.ts +0 -45
  41. package/src/rules/importsAndReExportsAtTop/isImportDeclaration.ts +0 -7
  42. package/src/rules/importsAndReExportsAtTop/isReExport.ts +0 -12
  43. package/src/rules/importsAndReExportsAtTop/statementType.ts +0 -4
  44. package/src/rules/individualImports.ts +0 -38
  45. package/src/rules/individualReExports.ts +0 -51
  46. package/src/rules/multilineUnionTypes/createFix.ts +0 -13
  47. package/src/rules/multilineUnionTypes/index.ts +0 -52
  48. package/src/rules/multilineUnionTypes/isMultiline.ts +0 -6
  49. package/src/rules/singleLineImports/createFix.ts +0 -23
  50. package/src/rules/singleLineImports/formatAttributes.ts +0 -20
  51. package/src/rules/singleLineImports/formatNamed.ts +0 -9
  52. package/src/rules/singleLineImports/formatSpecifiers.ts +0 -32
  53. package/src/rules/singleLineImports/index.ts +0 -34
  54. package/src/rules/singleLineImports/isMultiline.ts +0 -6
  55. package/src/rules/singleLineReExports/createFix.ts +0 -29
  56. package/src/rules/singleLineReExports/index.ts +0 -48
  57. package/src/rules/singleLineReExports/isMultiline.ts +0 -6
  58. package/src/rules/sortedImports/CategorizedImport.ts +0 -8
  59. package/src/rules/sortedImports/ImportError.ts +0 -9
  60. package/src/rules/sortedImports/ImportGroup.ts +0 -6
  61. package/src/rules/sortedImports/ImportGroupOrder.ts +0 -9
  62. package/src/rules/sortedImports/areSpecifiersSorted.ts +0 -9
  63. package/src/rules/sortedImports/categorizeImport.ts +0 -23
  64. package/src/rules/sortedImports/categorizeImports.ts +0 -12
  65. package/src/rules/sortedImports/checkAlphabeticalSorting.ts +0 -23
  66. package/src/rules/sortedImports/checkGroupOrdering.ts +0 -21
  67. package/src/rules/sortedImports/checkSpecifiersSorting.ts +0 -21
  68. package/src/rules/sortedImports/createFix/buildSortedCode.ts +0 -23
  69. package/src/rules/sortedImports/createFix/findLastImportIndex.ts +0 -12
  70. package/src/rules/sortedImports/createFix/formatNamedImport.ts +0 -21
  71. package/src/rules/sortedImports/createFix/getReplacementRange.ts +0 -14
  72. package/src/rules/sortedImports/createFix/groupImportsByType.ts +0 -19
  73. package/src/rules/sortedImports/createFix/index.ts +0 -47
  74. package/src/rules/sortedImports/createFix/sortImportGroups.ts +0 -13
  75. package/src/rules/sortedImports/getImportGroups.ts +0 -23
  76. package/src/rules/sortedImports/getNamedSpecifiers.ts +0 -7
  77. package/src/rules/sortedImports/getSortKey.ts +0 -26
  78. package/src/rules/sortedImports/getSpecifierName.ts +0 -7
  79. package/src/rules/sortedImports/index.ts +0 -63
  80. package/src/rules/sortedImports/sortSpecifiersText.ts +0 -16
  81. package/src/rules/sortedReExports/CategorizedNamedReExport.ts +0 -6
  82. package/src/rules/sortedReExports/CategorizedReExport.ts +0 -26
  83. package/src/rules/sortedReExports/ReExportError.ts +0 -9
  84. package/src/rules/sortedReExports/ReExportGroup.ts +0 -5
  85. package/src/rules/sortedReExports/ReExportGroupOrder.ts +0 -8
  86. package/src/rules/sortedReExports/areSpecifiersSorted.ts +0 -9
  87. package/src/rules/sortedReExports/categorizeReExport.ts +0 -21
  88. package/src/rules/sortedReExports/categorizeReExports.ts +0 -14
  89. package/src/rules/sortedReExports/checkAlphabeticalSorting.ts +0 -25
  90. package/src/rules/sortedReExports/checkGroupOrdering.ts +0 -21
  91. package/src/rules/sortedReExports/checkSpecifiersSorting.ts +0 -23
  92. package/src/rules/sortedReExports/createFix/buildSortedCode.ts +0 -29
  93. package/src/rules/sortedReExports/createFix/findFirstExportIndex.ts +0 -11
  94. package/src/rules/sortedReExports/createFix/findLastExportIndex.ts +0 -12
  95. package/src/rules/sortedReExports/createFix/formatNamedReExport.ts +0 -21
  96. package/src/rules/sortedReExports/createFix/getReplacementRange.ts +0 -22
  97. package/src/rules/sortedReExports/createFix/groupReExportsByType.ts +0 -18
  98. package/src/rules/sortedReExports/createFix/index.ts +0 -47
  99. package/src/rules/sortedReExports/createFix/sortExportGroups.ts +0 -12
  100. package/src/rules/sortedReExports/getNamedSpecifiers.ts +0 -9
  101. package/src/rules/sortedReExports/getReExportGroups.ts +0 -33
  102. package/src/rules/sortedReExports/getSortKey.ts +0 -22
  103. package/src/rules/sortedReExports/getSpecifierName.ts +0 -7
  104. package/src/rules/sortedReExports/index.ts +0 -63
  105. package/src/rules/sortedReExports/isNamedReExport.ts +0 -6
  106. package/src/rules/sortedReExports/sortSpecifiersText.ts +0 -16
  107. package/tsdown.config.ts +0 -22
@@ -1,34 +0,0 @@
1
- import {createFix} from './createFix'
2
- import {isMultiline} from './isMultiline'
3
- import type {TSESLint} from '@typescript-eslint/utils'
4
-
5
- type MessageIds = 'multiline'
6
-
7
- export const singleLineImports: TSESLint.RuleModule<MessageIds, []> = {
8
- meta: {
9
- docs: {
10
- description: 'Enforce imports to be on a single line',
11
- },
12
- fixable: 'code',
13
- messages: {
14
- multiline: 'Import should be on a single line',
15
- },
16
- schema: [],
17
- type: 'layout',
18
- },
19
-
20
- create(context) {
21
- return {
22
- ImportDeclaration(node) {
23
- if (!isMultiline(node))
24
- return
25
-
26
- context.report({
27
- node,
28
- messageId: 'multiline',
29
- fix: fixer => createFix(fixer, node, context.sourceCode),
30
- })
31
- },
32
- }
33
- },
34
- }
@@ -1,6 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function isMultiline(declaration: TSESTree.ImportDeclaration) {
4
- const {start, end} = declaration.loc ?? {}
5
- return start?.line !== end?.line
6
- }
@@ -1,29 +0,0 @@
1
- import {formatAttributes} from '../singleLineImports/formatAttributes'
2
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
3
- import type {TSESLint} from '@typescript-eslint/utils'
4
-
5
- export function createFix(
6
- fixer: TSESLint.RuleFixer,
7
- declaration: ReExportDeclaration,
8
- sourceCode: TSESLint.SourceCode,
9
- ): TSESLint.RuleFix {
10
- const source = declaration.source!.value
11
-
12
- if (declaration.type === 'ExportAllDeclaration') {
13
- const exported = declaration.exported
14
- ? `* as ${sourceCode.getText(declaration.exported)}`
15
- : '*'
16
- const attributes = formatAttributes(declaration.attributes)
17
- const result = `export ${exported} from '${source}'${attributes}`
18
- return fixer.replaceText(declaration, result)
19
- }
20
-
21
- const prefix = declaration.exportKind === 'type' ? 'export type ' : 'export '
22
- const specifiers = declaration.specifiers.map(
23
- s => sourceCode.getText(s),
24
- ).join(', ')
25
- const attributes = formatAttributes(declaration.attributes)
26
- const result = `${prefix}{${specifiers}} from '${source}'${attributes}`
27
-
28
- return fixer.replaceText(declaration, result)
29
- }
@@ -1,48 +0,0 @@
1
- import {createFix} from './createFix'
2
- import {isMultiline} from './isMultiline'
3
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
4
- import type {TSESLint} from '@typescript-eslint/utils'
5
- import type {TSESTree} from '@typescript-eslint/utils'
6
-
7
- type MessageIds = 'multiline'
8
-
9
- export const singleLineReExports: TSESLint.RuleModule<MessageIds, []> = {
10
- meta: {
11
- docs: {
12
- description: 'Enforce re-exports to be on a single line',
13
- },
14
- fixable: 'code',
15
- messages: {
16
- multiline: 'Re-export should be on a single line',
17
- },
18
- schema: [],
19
- type: 'layout',
20
- },
21
-
22
- create(context) {
23
- const checkDeclaration = (
24
- node: TSESTree.Node,
25
- declaration: ReExportDeclaration,
26
- ) => {
27
- // Skip local exports (only process re-exports with a source)
28
- if (!declaration.source)
29
- return
30
-
31
- if (!isMultiline(declaration))
32
- return
33
-
34
- context.report({
35
- node,
36
- messageId: 'multiline',
37
- fix: fixer => createFix(fixer, declaration, context.sourceCode),
38
- })
39
- }
40
-
41
- return {
42
- ExportNamedDeclaration: node =>
43
- checkDeclaration(node, node),
44
- ExportAllDeclaration: node =>
45
- checkDeclaration(node, node),
46
- }
47
- },
48
- }
@@ -1,6 +0,0 @@
1
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
2
-
3
- export function isMultiline(declaration: ReExportDeclaration) {
4
- const {start, end} = declaration.loc ?? {}
5
- return start?.line !== end?.line
6
- }
@@ -1,8 +0,0 @@
1
- import type {ImportGroup} from './ImportGroup'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export interface CategorizedImport {
5
- declaration: TSESTree.ImportDeclaration
6
- group: ImportGroup
7
- sortKey: string
8
- }
@@ -1,9 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export interface ImportError {
4
- node: TSESTree.ImportDeclaration
5
- messageId:
6
- | 'sortedImports'
7
- | 'sortedNames'
8
- | 'wrongGroup'
9
- }
@@ -1,6 +0,0 @@
1
- export type ImportGroup =
2
- | 'default'
3
- | 'named'
4
- | 'namespace'
5
- | 'side-effect'
6
- | 'type'
@@ -1,9 +0,0 @@
1
- import type {ImportGroup} from './ImportGroup'
2
-
3
- export const importGroupOrder: ImportGroup[] = [
4
- 'side-effect',
5
- 'namespace',
6
- 'default',
7
- 'named',
8
- 'type',
9
- ]
@@ -1,9 +0,0 @@
1
- import {compare} from '@lib/compare'
2
- import {getSpecifierName} from './getSpecifierName'
3
- import type {TSESTree} from '@typescript-eslint/types'
4
-
5
- export function areSpecifiersSorted(specifiers: TSESTree.ImportSpecifier[]): boolean {
6
- const names = specifiers.map(s => getSpecifierName(s))
7
- const sorted = [...names].sort((a, b) => compare(a, b))
8
- return names.every((name, i) => name === sorted[i])
9
- }
@@ -1,23 +0,0 @@
1
- import type {ImportGroup} from './ImportGroup'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export function categorizeImport(declaration: TSESTree.ImportDeclaration): ImportGroup {
5
- // Example: import type {Type} from 'module'
6
- if (declaration.importKind === 'type')
7
- return 'type'
8
-
9
- // Example: import 'module'
10
- if (declaration.specifiers.length === 0)
11
- return 'side-effect'
12
-
13
- // Example: import * as fs from 'module'
14
- if (declaration.specifiers.some(s => s.type === 'ImportNamespaceSpecifier'))
15
- return 'namespace'
16
-
17
- // Example: import value from 'module'
18
- if (declaration.specifiers.some(s => s.type === 'ImportDefaultSpecifier'))
19
- return 'default'
20
-
21
- // Example: import {value} from 'module'
22
- return 'named'
23
- }
@@ -1,12 +0,0 @@
1
- import {categorizeImport} from './categorizeImport'
2
- import {getSortKey} from './getSortKey'
3
- import type {CategorizedImport} from './CategorizedImport'
4
- import type {TSESTree} from '@typescript-eslint/types'
5
-
6
- export function categorizeImports(declarations: TSESTree.ImportDeclaration[]): CategorizedImport[] {
7
- return declarations.map(declaration => ({
8
- declaration,
9
- group: categorizeImport(declaration),
10
- sortKey: getSortKey(declaration),
11
- }))
12
- }
@@ -1,23 +0,0 @@
1
- import {compare} from '@lib/compare'
2
- import {importGroupOrder} from './ImportGroupOrder'
3
- import type {CategorizedImport} from './CategorizedImport'
4
- import type {ImportError} from './ImportError'
5
-
6
- export function checkAlphabeticalSorting(categorized: CategorizedImport[]): ImportError[] {
7
- const errors: ImportError[] = []
8
-
9
- for (const group of importGroupOrder) {
10
- const groupImports = categorized.filter(c => c.group === group)
11
- const sorted = [...groupImports].sort((a, b) => compare(a.sortKey, b.sortKey))
12
- for (let i = 0; i < groupImports.length; i++) {
13
- if (groupImports[i] !== sorted[i]) {
14
- errors.push({
15
- node: groupImports[i].declaration,
16
- messageId: 'sortedImports',
17
- })
18
- }
19
- }
20
- }
21
-
22
- return errors
23
- }
@@ -1,21 +0,0 @@
1
- import {importGroupOrder} from './ImportGroupOrder'
2
- import type {CategorizedImport} from './CategorizedImport'
3
- import type {ImportError} from './ImportError'
4
-
5
- export function checkGroupOrdering(categorized: CategorizedImport[]): ImportError[] {
6
- const errors: ImportError[] = []
7
-
8
- let currentGroupIndex = -1
9
- for (const {declaration, group} of categorized) {
10
- const groupIndex = importGroupOrder.indexOf(group)
11
- if (groupIndex < currentGroupIndex) {
12
- errors.push({
13
- node: declaration,
14
- messageId: 'wrongGroup',
15
- })
16
- } else
17
- currentGroupIndex = groupIndex
18
- }
19
-
20
- return errors
21
- }
@@ -1,21 +0,0 @@
1
- import {areSpecifiersSorted} from './areSpecifiersSorted'
2
- import {getNamedSpecifiers} from './getNamedSpecifiers'
3
- import type {CategorizedImport} from './CategorizedImport'
4
- import type {ImportError} from './ImportError'
5
-
6
- export function checkSpecifiersSorting(categorized: CategorizedImport[]): ImportError[] {
7
- const errors: ImportError[] = []
8
- const namedImports = categorized.filter(c => c.group === 'named')
9
-
10
- for (const {declaration} of namedImports) {
11
- const specifiers = getNamedSpecifiers(declaration)
12
- if (specifiers.length > 1 && !areSpecifiersSorted(specifiers)) {
13
- errors.push({
14
- node: declaration,
15
- messageId: 'sortedNames',
16
- })
17
- }
18
- }
19
-
20
- return errors
21
- }
@@ -1,23 +0,0 @@
1
- import {formatNamedImport} from './formatNamedImport'
2
- import {importGroupOrder} from '../ImportGroupOrder'
3
- import type {CategorizedImport} from '../CategorizedImport'
4
- import type {ImportGroup} from '../ImportGroup'
5
- import type {TSESLint} from '@typescript-eslint/utils'
6
-
7
- export function buildSortedCode(
8
- grouped: Record<ImportGroup, CategorizedImport[]>,
9
- sourceCode: TSESLint.SourceCode,
10
- ): string[] {
11
- const sortedCode: string[] = []
12
-
13
- for (const group of importGroupOrder) {
14
- for (const {declaration} of grouped[group]) {
15
- if (group === 'named' || group === 'type')
16
- sortedCode.push(formatNamedImport(declaration, sourceCode))
17
- else
18
- sortedCode.push(sourceCode.getText(declaration))
19
- }
20
- }
21
-
22
- return sortedCode
23
- }
@@ -1,12 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function findLastImportIndex(programBody: TSESTree.ProgramStatement[]): number {
4
- let lastIndex = 0
5
- for (let i = 0; i < programBody.length; i++) {
6
- if (programBody[i].type === 'ImportDeclaration')
7
- lastIndex = i
8
- else
9
- break
10
- }
11
- return lastIndex
12
- }
@@ -1,21 +0,0 @@
1
- import {areSpecifiersSorted} from '../areSpecifiersSorted'
2
- import {getNamedSpecifiers} from '../getNamedSpecifiers'
3
- import {sortSpecifiersText} from '../sortSpecifiersText'
4
- import type {TSESLint} from '@typescript-eslint/utils'
5
- import type {TSESTree} from '@typescript-eslint/utils'
6
-
7
- export function formatNamedImport(
8
- declaration: TSESTree.ImportDeclaration,
9
- sourceCode: TSESLint.SourceCode,
10
- ): string {
11
- const specifiers = getNamedSpecifiers(declaration)
12
-
13
- if (specifiers.length > 1 && !areSpecifiersSorted(specifiers)) {
14
- const sortedSpecifiers = sortSpecifiersText(specifiers, sourceCode)
15
- const source = declaration.source.value
16
- const prefix = declaration.importKind === 'type' ? 'import type ' : 'import '
17
- return `${prefix}{${sortedSpecifiers}} from '${source}'`
18
- }
19
-
20
- return sourceCode.getText(declaration)
21
- }
@@ -1,14 +0,0 @@
1
- import {findLastImportIndex} from './findLastImportIndex'
2
- import type {ReplacementRange} from '@lib/ReplacementRange'
3
- import type {TSESTree} from '@typescript-eslint/types'
4
-
5
- export function getReplacementRange(
6
- programBody: TSESTree.ProgramStatement[],
7
- ): ReplacementRange {
8
- const lastIndex = findLastImportIndex(programBody)
9
- const firstImport = programBody[0]
10
- const lastImport = programBody[lastIndex]
11
- const start = firstImport.range![0]
12
- const end = lastImport.range![1]
13
- return {start, end}
14
- }
@@ -1,19 +0,0 @@
1
- import type {CategorizedImport} from '../CategorizedImport'
2
- import type {ImportGroup} from '../ImportGroup'
3
-
4
- export function groupImportsByType(
5
- categorized: CategorizedImport[],
6
- ): Record<ImportGroup, CategorizedImport[]> {
7
- const grouped: Record<ImportGroup, CategorizedImport[]> = {
8
- 'side-effect': [],
9
- namespace: [],
10
- default: [],
11
- named: [],
12
- type: [],
13
- }
14
-
15
- for (const item of categorized)
16
- grouped[item.group].push(item)
17
-
18
- return grouped
19
- }
@@ -1,47 +0,0 @@
1
- import {buildSortedCode} from './buildSortedCode'
2
- import {categorizeImports} from '../categorizeImports'
3
- import {groupImportsByType} from './groupImportsByType'
4
- import {sortImportGroups} from './sortImportGroups'
5
- import type {TSESLint} from '@typescript-eslint/utils'
6
- import type {TSESTree} from '@typescript-eslint/utils'
7
-
8
- function createFixForGroup(
9
- fixer: TSESLint.RuleFixer,
10
- importDeclarations: TSESTree.ImportDeclaration[],
11
- sourceCode: TSESLint.SourceCode,
12
- ) {
13
- if (importDeclarations.length === 0)
14
- return null
15
-
16
- const categorized = categorizeImports(importDeclarations)
17
- const grouped = groupImportsByType(categorized)
18
-
19
- sortImportGroups(grouped)
20
-
21
- const sortedCode = buildSortedCode(grouped, sourceCode)
22
- .join('\n')
23
-
24
- const firstImport = importDeclarations[0]
25
- const lastImport = importDeclarations[importDeclarations.length - 1]
26
-
27
- return fixer.replaceTextRange(
28
- [firstImport.range![0], lastImport.range![1]],
29
- sortedCode,
30
- )
31
- }
32
-
33
- export function createFix(
34
- fixer: TSESLint.RuleFixer,
35
- importGroups: TSESTree.ImportDeclaration[][],
36
- sourceCode: TSESLint.SourceCode,
37
- ): TSESLint.RuleFix[] {
38
- const fixes: TSESLint.RuleFix[] = []
39
-
40
- for (const group of importGroups) {
41
- const fix = createFixForGroup(fixer, group, sourceCode)
42
- if (fix)
43
- fixes.push(fix)
44
- }
45
-
46
- return fixes
47
- }
@@ -1,13 +0,0 @@
1
- import {compare} from '@lib/compare'
2
- import type {CategorizedImport} from '../CategorizedImport'
3
- import type {ImportGroup} from '../ImportGroup'
4
-
5
- export function sortImportGroups(
6
- grouped: Record<ImportGroup, CategorizedImport[]>,
7
- ): void {
8
- grouped['side-effect'].sort((a, b) => compare(a.sortKey, b.sortKey))
9
- grouped['namespace'].sort((a, b) => compare(a.sortKey, b.sortKey))
10
- grouped['default'].sort((a, b) => compare(a.sortKey, b.sortKey))
11
- grouped['named'].sort((a, b) => compare(a.sortKey, b.sortKey))
12
- grouped['type'].sort((a, b) => compare(a.sortKey, b.sortKey))
13
- }
@@ -1,23 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function getImportGroups(programBody: TSESTree.ProgramStatement[]): TSESTree.ImportDeclaration[][] {
4
- const groups: TSESTree.ImportDeclaration[][] = []
5
- let currentGroup: TSESTree.ImportDeclaration[] = []
6
-
7
- for (const statement of programBody) {
8
- if (statement.type === 'ImportDeclaration') {
9
- currentGroup.push(statement)
10
- continue
11
- }
12
-
13
- if (currentGroup.length > 0) {
14
- groups.push(currentGroup)
15
- currentGroup = []
16
- }
17
- }
18
-
19
- if (currentGroup.length > 0)
20
- groups.push(currentGroup)
21
-
22
- return groups
23
- }
@@ -1,7 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function getNamedSpecifiers(declaration: TSESTree.ImportDeclaration): TSESTree.ImportSpecifier[] {
4
- return declaration.specifiers.filter(
5
- (s): s is TSESTree.ImportSpecifier => s.type === 'ImportSpecifier',
6
- )
7
- }
@@ -1,26 +0,0 @@
1
- import {categorizeImport} from './categorizeImport'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export function getSortKey(declaration: TSESTree.ImportDeclaration): string {
5
- const group = categorizeImport(declaration)
6
-
7
- if (group === 'side-effect')
8
- return declaration.source.value
9
-
10
- if (group === 'namespace') {
11
- const namespaceSpecifier = declaration.specifiers.find(
12
- s => s.type === 'ImportNamespaceSpecifier',
13
- )
14
- return `*${namespaceSpecifier?.local.name ?? ''}`
15
- }
16
-
17
- if (group === 'default') {
18
- const defaultSpecifier = declaration.specifiers.find(
19
- s => s.type === 'ImportDefaultSpecifier',
20
- )
21
- return defaultSpecifier?.local.name ?? ''
22
- }
23
-
24
- const specifier = declaration.specifiers[0]
25
- return specifier.local.name
26
- }
@@ -1,7 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function getSpecifierName(specifier: TSESTree.ImportSpecifier): string {
4
- return specifier.imported.type === 'Identifier'
5
- ? specifier.imported.name
6
- : String(specifier.imported.value)
7
- }
@@ -1,63 +0,0 @@
1
- import {categorizeImports} from './categorizeImports'
2
- import {checkAlphabeticalSorting} from './checkAlphabeticalSorting'
3
- import {checkGroupOrdering} from './checkGroupOrdering'
4
- import {checkSpecifiersSorting} from './checkSpecifiersSorting'
5
- import {createFix} from './createFix'
6
- import {getImportGroups} from './getImportGroups'
7
- import type {ImportError} from './ImportError'
8
- import type {TSESLint} from '@typescript-eslint/utils'
9
-
10
- type MessageIds =
11
- | 'sortedImports'
12
- | 'sortedNames'
13
- | 'wrongGroup'
14
-
15
- export const sortedImports: TSESLint.RuleModule<MessageIds, []> = {
16
- meta: {
17
- docs: {
18
- description: 'Enforce sorted imports alphabetically',
19
- },
20
- fixable: 'code',
21
- messages: {
22
- sortedImports: 'Imports should be sorted alphabetically',
23
- sortedNames: 'Named imports should be sorted alphabetically',
24
- wrongGroup: 'Import is in wrong group',
25
- },
26
- schema: [],
27
- type: 'suggestion',
28
- },
29
- create(context) {
30
- return {
31
- Program(node) {
32
- const body = node.body
33
- const importGroups = getImportGroups(body)
34
- if (importGroups.length === 0)
35
- return
36
-
37
- const allErrors: ImportError[] = []
38
-
39
- // Check each import group independently
40
- for (const group of importGroups) {
41
- const categorized = categorizeImports(group)
42
- const errors: ImportError[] = [
43
- ...checkGroupOrdering(categorized),
44
- ...checkAlphabeticalSorting(categorized),
45
- ...checkSpecifiersSorting(categorized),
46
- ]
47
- allErrors.push(...errors)
48
- }
49
-
50
- for (const error of allErrors) {
51
- context.report({
52
- node: error.node,
53
- messageId: error.messageId,
54
- fix(fixer) {
55
- const sourceCode = context.sourceCode
56
- return createFix(fixer, importGroups, sourceCode)
57
- },
58
- })
59
- }
60
- },
61
- }
62
- },
63
- }
@@ -1,16 +0,0 @@
1
- import {compare} from '@lib/compare'
2
- import {getSpecifierName} from './getSpecifierName'
3
- import type {TSESLint} from '@typescript-eslint/utils'
4
- import type {TSESTree} from '@typescript-eslint/utils'
5
-
6
- export function sortSpecifiersText(
7
- specifiers: TSESTree.ImportSpecifier[],
8
- sourceCode: TSESLint.SourceCode,
9
- ): string {
10
- const sorted = [...specifiers].sort((a, b) => {
11
- const nameA = getSpecifierName(a)
12
- const nameB = getSpecifierName(b)
13
- return compare(nameA, nameB)
14
- })
15
- return sorted.map(s => sourceCode.getText(s)).join(', ')
16
- }
@@ -1,6 +0,0 @@
1
- import type {CategorizedReExport} from './CategorizedReExport'
2
-
3
- export type CategorizedNamedReExport = Extract<
4
- CategorizedReExport,
5
- {declaration: {type: 'ExportNamedDeclaration'}}
6
- >
@@ -1,26 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- interface NamedReExport {
4
- declaration: TSESTree.ExportNamedDeclaration
5
- group:
6
- | 're-export-named'
7
- | 're-export-type'
8
- sortKey: string
9
- }
10
-
11
- interface ReExportAll {
12
- declaration: TSESTree.ExportAllDeclaration
13
- group: 're-export-all'
14
- sortKey: string
15
- }
16
-
17
- interface ReExportNamespace {
18
- declaration: TSESTree.ExportAllDeclaration
19
- group: 're-export-namespace'
20
- sortKey: string
21
- }
22
-
23
- export type CategorizedReExport =
24
- | NamedReExport
25
- | ReExportAll
26
- | ReExportNamespace
@@ -1,9 +0,0 @@
1
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
2
-
3
- export interface ReExportError {
4
- node: ReExportDeclaration
5
- messageId:
6
- | 'sortedReExports'
7
- | 'sortedNames'
8
- | 'wrongGroup'
9
- }
@@ -1,5 +0,0 @@
1
- export type ReExportGroup =
2
- | 're-export-all'
3
- | 're-export-namespace'
4
- | 're-export-named'
5
- | 're-export-type'
@@ -1,8 +0,0 @@
1
- import type {ReExportGroup} from './ReExportGroup'
2
-
3
- export const reExportGroupOrder: ReExportGroup[] = [
4
- 're-export-all',
5
- 're-export-namespace',
6
- 're-export-named',
7
- 're-export-type',
8
- ]