@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.
Files changed (75) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +291 -58
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -2
  5. package/src/index.ts +18 -5
  6. package/src/rules/__tests__/importsAndReExportsAtTop.test.ts +3 -33
  7. package/src/rules/__tests__/individualImports.test.ts +3 -1
  8. package/src/rules/__tests__/individualReExports.test.ts +3 -1
  9. package/src/rules/__tests__/multilineUnionTypes.test.ts +75 -0
  10. package/src/rules/__tests__/singleLineImports.test.ts +129 -0
  11. package/src/rules/__tests__/singleLineReExports.test.ts +100 -0
  12. package/src/rules/__tests__/sortedImports.test.ts +37 -1
  13. package/src/rules/__tests__/sortedReExports.test.ts +27 -1
  14. package/src/rules/importsAndReExportsAtTop/CategorizedStatements.ts +2 -2
  15. package/src/rules/importsAndReExportsAtTop/StatementIndices.ts +3 -3
  16. package/src/rules/importsAndReExportsAtTop/categorizeStatements.ts +7 -6
  17. package/src/rules/importsAndReExportsAtTop/findStatementIndices.ts +25 -0
  18. package/src/rules/importsAndReExportsAtTop/generateSortedText.ts +4 -6
  19. package/src/rules/importsAndReExportsAtTop/getStatementType.ts +1 -1
  20. package/src/rules/importsAndReExportsAtTop/hasViolation.ts +13 -17
  21. package/src/rules/importsAndReExportsAtTop/index.ts +7 -7
  22. package/src/rules/importsAndReExportsAtTop/isImportDeclaration.ts +7 -0
  23. package/src/rules/importsAndReExportsAtTop/isReExport.ts +12 -0
  24. package/src/rules/individualImports.ts +4 -3
  25. package/src/rules/individualReExports.ts +8 -9
  26. package/src/rules/multilineUnionTypes/createFix.ts +13 -0
  27. package/src/rules/multilineUnionTypes/index.ts +52 -0
  28. package/src/rules/multilineUnionTypes/isMultiline.ts +6 -0
  29. package/src/rules/singleLineImports/createFix.ts +23 -0
  30. package/src/rules/singleLineImports/formatAttributes.ts +20 -0
  31. package/src/rules/singleLineImports/formatNamed.ts +9 -0
  32. package/src/rules/singleLineImports/formatSpecifiers.ts +32 -0
  33. package/src/rules/singleLineImports/index.ts +34 -0
  34. package/src/rules/singleLineImports/isMultiline.ts +6 -0
  35. package/src/rules/singleLineReExports/createFix.ts +29 -0
  36. package/src/rules/singleLineReExports/index.ts +48 -0
  37. package/src/rules/singleLineReExports/isMultiline.ts +6 -0
  38. package/src/rules/sortedImports/ImportError.ts +4 -1
  39. package/src/rules/sortedImports/ImportGroup.ts +2 -1
  40. package/src/rules/sortedImports/ImportGroupOrder.ts +2 -1
  41. package/src/rules/sortedImports/areSpecifiersSorted.ts +1 -1
  42. package/src/rules/sortedImports/categorizeImport.ts +4 -0
  43. package/src/rules/sortedImports/checkAlphabeticalSorting.ts +1 -1
  44. package/src/rules/sortedImports/createFix/buildSortedCode.ts +2 -1
  45. package/src/rules/sortedImports/createFix/formatNamedImport.ts +3 -2
  46. package/src/rules/sortedImports/createFix/getReplacementRange.ts +3 -3
  47. package/src/rules/sortedImports/createFix/groupImportsByType.ts +1 -0
  48. package/src/rules/sortedImports/createFix/index.ts +10 -11
  49. package/src/rules/sortedImports/createFix/sortImportGroups.ts +2 -1
  50. package/src/rules/sortedImports/getSortKey.ts +8 -2
  51. package/src/rules/sortedImports/index.ts +8 -5
  52. package/src/rules/sortedImports/sortSpecifiersText.ts +4 -3
  53. package/src/rules/sortedReExports/CategorizedReExport.ts +14 -3
  54. package/src/rules/sortedReExports/ReExportError.ts +5 -2
  55. package/src/rules/sortedReExports/ReExportGroup.ts +1 -0
  56. package/src/rules/sortedReExports/ReExportGroupOrder.ts +2 -1
  57. package/src/rules/sortedReExports/areSpecifiersSorted.ts +1 -1
  58. package/src/rules/sortedReExports/categorizeReExport.ts +8 -4
  59. package/src/rules/sortedReExports/categorizeReExports.ts +1 -1
  60. package/src/rules/sortedReExports/checkAlphabeticalSorting.ts +1 -1
  61. package/src/rules/sortedReExports/createFix/buildSortedCode.ts +2 -1
  62. package/src/rules/sortedReExports/createFix/formatNamedReExport.ts +3 -2
  63. package/src/rules/sortedReExports/createFix/getReplacementRange.ts +1 -1
  64. package/src/rules/sortedReExports/createFix/groupReExportsByType.ts +1 -0
  65. package/src/rules/sortedReExports/createFix/index.ts +10 -11
  66. package/src/rules/sortedReExports/createFix/sortExportGroups.ts +2 -1
  67. package/src/rules/sortedReExports/getNamedSpecifiers.ts +1 -1
  68. package/src/rules/sortedReExports/getReExportGroups.ts +1 -1
  69. package/src/rules/sortedReExports/getSortKey.ts +11 -5
  70. package/src/rules/sortedReExports/index.ts +8 -5
  71. package/src/rules/sortedReExports/isNamedReExport.ts +2 -2
  72. package/src/rules/sortedReExports/sortSpecifiersText.ts +4 -3
  73. package/src/rules/importsAndReExportsAtTop/ReExport.ts +0 -5
  74. package/src/rules/importsAndReExportsAtTop/findFirstIndices.ts +0 -25
  75. /package/src/{rules/sortedReExports → lib}/ReExportDeclaration.ts +0 -0
@@ -0,0 +1,6 @@
1
+ import type {TSESTree} from '@typescript-eslint/types'
2
+
3
+ export function isMultiline(unionType: TSESTree.TSUnionType) {
4
+ const {start, end} = unionType.loc ?? {}
5
+ return start?.line !== end?.line
6
+ }
@@ -0,0 +1,23 @@
1
+ import {formatAttributes} from './formatAttributes'
2
+ import {formatSpecifiers} from './formatSpecifiers'
3
+ import type {TSESLint} from '@typescript-eslint/utils'
4
+ import type {TSESTree} from '@typescript-eslint/utils'
5
+
6
+ export function createFix(
7
+ fixer: TSESLint.RuleFixer,
8
+ declaration: TSESTree.ImportDeclaration,
9
+ sourceCode: TSESLint.SourceCode,
10
+ ): TSESLint.RuleFix {
11
+ const source = declaration.source.value
12
+ const prefix = declaration.importKind === 'type' ? 'import type ' : 'import '
13
+ const specifiers = formatSpecifiers(declaration, sourceCode)
14
+ const attributes = formatAttributes(declaration.attributes)
15
+
16
+ if (specifiers === '') {
17
+ const result = `${prefix}'${source}'${attributes}`
18
+ return fixer.replaceText(declaration, result)
19
+ }
20
+
21
+ const result = `${prefix}${specifiers} from '${source}'${attributes}`
22
+ return fixer.replaceText(declaration, result)
23
+ }
@@ -0,0 +1,20 @@
1
+ import type {TSESTree} from '@typescript-eslint/types'
2
+
3
+ export function formatAttributes(
4
+ attributes: readonly TSESTree.ImportAttribute[],
5
+ ): string {
6
+ if (attributes.length === 0)
7
+ return ''
8
+
9
+ const formatted = attributes.map(
10
+ attr => {
11
+ const key = attr.key.type === 'Identifier'
12
+ ? attr.key.name
13
+ : attr.key.value
14
+ const value = attr.value.value
15
+ return `${key}: '${value}'`
16
+ },
17
+ ).join(', ')
18
+
19
+ return ` with {${formatted}}`
20
+ }
@@ -0,0 +1,9 @@
1
+ import type {TSESLint} from '@typescript-eslint/utils'
2
+ import type {TSESTree} from '@typescript-eslint/utils'
3
+
4
+ export function formatNamed(
5
+ specifiers: TSESTree.ImportSpecifier[],
6
+ sourceCode: TSESLint.SourceCode,
7
+ ): string {
8
+ return specifiers.map(s => sourceCode.getText(s)).join(', ')
9
+ }
@@ -0,0 +1,32 @@
1
+ import {formatNamed} from './formatNamed'
2
+ import type {TSESLint} from '@typescript-eslint/utils'
3
+ import type {TSESTree} from '@typescript-eslint/utils'
4
+
5
+ export function formatSpecifiers(
6
+ declaration: TSESTree.ImportDeclaration,
7
+ sourceCode: TSESLint.SourceCode,
8
+ ): string {
9
+ const defaultSpecifier = declaration.specifiers.find(
10
+ (s): s is TSESTree.ImportDefaultSpecifier => s.type === 'ImportDefaultSpecifier',
11
+ )
12
+ const namespaceSpecifier = declaration.specifiers.find(
13
+ (s): s is TSESTree.ImportNamespaceSpecifier => s.type === 'ImportNamespaceSpecifier',
14
+ )
15
+ const namedSpecifiers = declaration.specifiers.filter(
16
+ (s): s is TSESTree.ImportSpecifier => s.type === 'ImportSpecifier',
17
+ )
18
+
19
+ if (namespaceSpecifier)
20
+ return `* as ${namespaceSpecifier.local.name}`
21
+
22
+ if (defaultSpecifier && namedSpecifiers.length > 0)
23
+ return `${defaultSpecifier.local.name}, {${formatNamed(namedSpecifiers, sourceCode)}}`
24
+
25
+ if (defaultSpecifier)
26
+ return defaultSpecifier.local.name
27
+
28
+ if (namedSpecifiers.length === 0)
29
+ return ''
30
+
31
+ return `{${formatNamed(namedSpecifiers, sourceCode)}}`
32
+ }
@@ -0,0 +1,34 @@
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
+ }
@@ -0,0 +1,6 @@
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
+ }
@@ -0,0 +1,29 @@
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
+ }
@@ -0,0 +1,48 @@
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
+ }
@@ -0,0 +1,6 @@
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
+ }
@@ -2,5 +2,8 @@ import type {TSESTree} from '@typescript-eslint/types'
2
2
 
3
3
  export interface ImportError {
4
4
  node: TSESTree.ImportDeclaration
5
- messageId: 'sortedImports' | 'sortedNames' | 'wrongGroup'
5
+ messageId:
6
+ | 'sortedImports'
7
+ | 'sortedNames'
8
+ | 'wrongGroup'
6
9
  }
@@ -1,5 +1,6 @@
1
1
  export type ImportGroup =
2
- | 'side-effect'
3
2
  | 'default'
4
3
  | 'named'
4
+ | 'namespace'
5
+ | 'side-effect'
5
6
  | 'type'
@@ -1,7 +1,8 @@
1
- import {ImportGroup} from './ImportGroup'
1
+ import type {ImportGroup} from './ImportGroup'
2
2
 
3
3
  export const importGroupOrder: ImportGroup[] = [
4
4
  'side-effect',
5
+ 'namespace',
5
6
  'default',
6
7
  'named',
7
8
  'type',
@@ -1,4 +1,4 @@
1
- import {compare} from '../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import {getSpecifierName} from './getSpecifierName'
3
3
  import type {TSESTree} from '@typescript-eslint/types'
4
4
 
@@ -10,6 +10,10 @@ export function categorizeImport(declaration: TSESTree.ImportDeclaration): Impor
10
10
  if (declaration.specifiers.length === 0)
11
11
  return 'side-effect'
12
12
 
13
+ // Example: import * as fs from 'module'
14
+ if (declaration.specifiers.some(s => s.type === 'ImportNamespaceSpecifier'))
15
+ return 'namespace'
16
+
13
17
  // Example: import value from 'module'
14
18
  if (declaration.specifiers.some(s => s.type === 'ImportDefaultSpecifier'))
15
19
  return 'default'
@@ -1,4 +1,4 @@
1
- import {compare} from '../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import {importGroupOrder} from './ImportGroupOrder'
3
3
  import type {CategorizedImport} from './CategorizedImport'
4
4
  import type {ImportError} from './ImportError'
@@ -2,10 +2,11 @@ import {formatNamedImport} from './formatNamedImport'
2
2
  import {importGroupOrder} from '../ImportGroupOrder'
3
3
  import type {CategorizedImport} from '../CategorizedImport'
4
4
  import type {ImportGroup} from '../ImportGroup'
5
+ import type {TSESLint} from '@typescript-eslint/utils'
5
6
 
6
7
  export function buildSortedCode(
7
8
  grouped: Record<ImportGroup, CategorizedImport[]>,
8
- sourceCode: {getText: (node?: unknown) => string},
9
+ sourceCode: TSESLint.SourceCode,
9
10
  ): string[] {
10
11
  const sortedCode: string[] = []
11
12
 
@@ -1,11 +1,12 @@
1
1
  import {areSpecifiersSorted} from '../areSpecifiersSorted'
2
2
  import {getNamedSpecifiers} from '../getNamedSpecifiers'
3
3
  import {sortSpecifiersText} from '../sortSpecifiersText'
4
- import type {TSESTree} from '@typescript-eslint/types'
4
+ import type {TSESLint} from '@typescript-eslint/utils'
5
+ import type {TSESTree} from '@typescript-eslint/utils'
5
6
 
6
7
  export function formatNamedImport(
7
8
  declaration: TSESTree.ImportDeclaration,
8
- sourceCode: {getText: (node?: unknown) => string},
9
+ sourceCode: TSESLint.SourceCode,
9
10
  ): string {
10
11
  const specifiers = getNamedSpecifiers(declaration)
11
12
 
@@ -1,13 +1,13 @@
1
1
  import {findLastImportIndex} from './findLastImportIndex'
2
- import type {ReplacementRange} from '../../../lib/ReplacementRange'
2
+ import type {ReplacementRange} from '@lib/ReplacementRange'
3
3
  import type {TSESTree} from '@typescript-eslint/types'
4
4
 
5
5
  export function getReplacementRange(
6
6
  programBody: TSESTree.ProgramStatement[],
7
7
  ): ReplacementRange {
8
8
  const lastIndex = findLastImportIndex(programBody)
9
- const firstImport = programBody[0] as TSESTree.ImportDeclaration
10
- const lastImport = programBody[lastIndex] as TSESTree.ImportDeclaration
9
+ const firstImport = programBody[0]
10
+ const lastImport = programBody[lastIndex]
11
11
  const start = firstImport.range![0]
12
12
  const end = lastImport.range![1]
13
13
  return {start, end}
@@ -6,6 +6,7 @@ export function groupImportsByType(
6
6
  ): Record<ImportGroup, CategorizedImport[]> {
7
7
  const grouped: Record<ImportGroup, CategorizedImport[]> = {
8
8
  'side-effect': [],
9
+ namespace: [],
9
10
  default: [],
10
11
  named: [],
11
12
  type: [],
@@ -2,17 +2,16 @@ import {buildSortedCode} from './buildSortedCode'
2
2
  import {categorizeImports} from '../categorizeImports'
3
3
  import {groupImportsByType} from './groupImportsByType'
4
4
  import {sortImportGroups} from './sortImportGroups'
5
- import type {Rule} from 'eslint'
6
- import type {TSESTree} from '@typescript-eslint/types'
5
+ import type {TSESLint} from '@typescript-eslint/utils'
6
+ import type {TSESTree} from '@typescript-eslint/utils'
7
7
 
8
8
  function createFixForGroup(
9
- fixer: Rule.RuleFixer,
9
+ fixer: TSESLint.RuleFixer,
10
10
  importDeclarations: TSESTree.ImportDeclaration[],
11
- sourceCode: {getText: (node?: unknown) => string},
12
- ): Rule.Fix | null {
13
- if (importDeclarations.length === 0) {
11
+ sourceCode: TSESLint.SourceCode,
12
+ ) {
13
+ if (importDeclarations.length === 0)
14
14
  return null
15
- }
16
15
 
17
16
  const categorized = categorizeImports(importDeclarations)
18
17
  const grouped = groupImportsByType(categorized)
@@ -32,11 +31,11 @@ function createFixForGroup(
32
31
  }
33
32
 
34
33
  export function createFix(
35
- fixer: Rule.RuleFixer,
34
+ fixer: TSESLint.RuleFixer,
36
35
  importGroups: TSESTree.ImportDeclaration[][],
37
- sourceCode: {getText: (node?: unknown) => string},
38
- ): Rule.Fix[] {
39
- const fixes: Rule.Fix[] = []
36
+ sourceCode: TSESLint.SourceCode,
37
+ ): TSESLint.RuleFix[] {
38
+ const fixes: TSESLint.RuleFix[] = []
40
39
 
41
40
  for (const group of importGroups) {
42
41
  const fix = createFixForGroup(fixer, group, sourceCode)
@@ -1,4 +1,4 @@
1
- import {compare} from '../../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import type {CategorizedImport} from '../CategorizedImport'
3
3
  import type {ImportGroup} from '../ImportGroup'
4
4
 
@@ -6,6 +6,7 @@ export function sortImportGroups(
6
6
  grouped: Record<ImportGroup, CategorizedImport[]>,
7
7
  ): void {
8
8
  grouped['side-effect'].sort((a, b) => compare(a.sortKey, b.sortKey))
9
+ grouped['namespace'].sort((a, b) => compare(a.sortKey, b.sortKey))
9
10
  grouped['default'].sort((a, b) => compare(a.sortKey, b.sortKey))
10
11
  grouped['named'].sort((a, b) => compare(a.sortKey, b.sortKey))
11
12
  grouped['type'].sort((a, b) => compare(a.sortKey, b.sortKey))
@@ -7,11 +7,17 @@ export function getSortKey(declaration: TSESTree.ImportDeclaration): string {
7
7
  if (group === 'side-effect')
8
8
  return declaration.source.value
9
9
 
10
+ if (group === 'namespace') {
11
+ const namespaceSpecifier = declaration.specifiers.find(
12
+ s => s.type === 'ImportNamespaceSpecifier',
13
+ )
14
+ return `*${namespaceSpecifier?.local.name ?? ''}`
15
+ }
16
+
10
17
  if (group === 'default') {
11
18
  const defaultSpecifier = declaration.specifiers.find(
12
19
  s => s.type === 'ImportDefaultSpecifier',
13
- ) as TSESTree.ImportDefaultSpecifier | undefined
14
-
20
+ )
15
21
  return defaultSpecifier?.local.name ?? ''
16
22
  }
17
23
 
@@ -5,14 +5,17 @@ import {checkSpecifiersSorting} from './checkSpecifiersSorting'
5
5
  import {createFix} from './createFix'
6
6
  import {getImportGroups} from './getImportGroups'
7
7
  import type {ImportError} from './ImportError'
8
- import type {Rule} from 'eslint'
9
- import type {TSESTree} from '@typescript-eslint/types'
8
+ import type {TSESLint} from '@typescript-eslint/utils'
10
9
 
11
- export const sortedImports: Rule.RuleModule = {
10
+ type MessageIds =
11
+ | 'sortedImports'
12
+ | 'sortedNames'
13
+ | 'wrongGroup'
14
+
15
+ export const sortedImports: TSESLint.RuleModule<MessageIds, []> = {
12
16
  meta: {
13
17
  docs: {
14
18
  description: 'Enforce sorted imports alphabetically',
15
- recommended: true,
16
19
  },
17
20
  fixable: 'code',
18
21
  messages: {
@@ -26,7 +29,7 @@ export const sortedImports: Rule.RuleModule = {
26
29
  create(context) {
27
30
  return {
28
31
  Program(node) {
29
- const body = node.body as TSESTree.ProgramStatement[]
32
+ const body = node.body
30
33
  const importGroups = getImportGroups(body)
31
34
  if (importGroups.length === 0)
32
35
  return
@@ -1,10 +1,11 @@
1
- import {compare} from '../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import {getSpecifierName} from './getSpecifierName'
3
- import type {TSESTree} from '@typescript-eslint/types'
3
+ import type {TSESLint} from '@typescript-eslint/utils'
4
+ import type {TSESTree} from '@typescript-eslint/utils'
4
5
 
5
6
  export function sortSpecifiersText(
6
7
  specifiers: TSESTree.ImportSpecifier[],
7
- sourceCode: {getText: (node: TSESTree.ImportSpecifier) => string},
8
+ sourceCode: TSESLint.SourceCode,
8
9
  ): string {
9
10
  const sorted = [...specifiers].sort((a, b) => {
10
11
  const nameA = getSpecifierName(a)
@@ -1,8 +1,10 @@
1
- import {TSESTree} from '@typescript-eslint/types'
1
+ import type {TSESTree} from '@typescript-eslint/types'
2
2
 
3
3
  interface NamedReExport {
4
4
  declaration: TSESTree.ExportNamedDeclaration
5
- group: 're-export-named' | 're-export-type'
5
+ group:
6
+ | 're-export-named'
7
+ | 're-export-type'
6
8
  sortKey: string
7
9
  }
8
10
 
@@ -12,4 +14,13 @@ interface ReExportAll {
12
14
  sortKey: string
13
15
  }
14
16
 
15
- export type CategorizedReExport = NamedReExport | ReExportAll
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,6 +1,9 @@
1
- import type {ReExportDeclaration} from './ReExportDeclaration'
1
+ import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
2
2
 
3
3
  export interface ReExportError {
4
4
  node: ReExportDeclaration
5
- messageId: 'sortedReExports' | 'sortedNames' | 'wrongGroup'
5
+ messageId:
6
+ | 'sortedReExports'
7
+ | 'sortedNames'
8
+ | 'wrongGroup'
6
9
  }
@@ -1,4 +1,5 @@
1
1
  export type ReExportGroup =
2
2
  | 're-export-all'
3
+ | 're-export-namespace'
3
4
  | 're-export-named'
4
5
  | 're-export-type'
@@ -1,7 +1,8 @@
1
- import {ReExportGroup} from './ReExportGroup'
1
+ import type {ReExportGroup} from './ReExportGroup'
2
2
 
3
3
  export const reExportGroupOrder: ReExportGroup[] = [
4
4
  're-export-all',
5
+ 're-export-namespace',
5
6
  're-export-named',
6
7
  're-export-type',
7
8
  ]
@@ -1,4 +1,4 @@
1
- import {compare} from '../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import {getSpecifierName} from './getSpecifierName'
3
3
  import type {TSESTree} from '@typescript-eslint/types'
4
4
 
@@ -1,12 +1,16 @@
1
+ import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
1
2
  import type {ReExportGroup} from './ReExportGroup'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
3
 
4
4
  export function categorizeReExport(
5
- declaration: TSESTree.ExportNamedDeclaration | TSESTree.ExportAllDeclaration,
5
+ declaration: ReExportDeclaration,
6
6
  ): ReExportGroup {
7
- // Example: export * from 'module'
8
- if (declaration.type === 'ExportAllDeclaration')
7
+ // Example: export * from 'module' or export * as ns from 'module'
8
+ if (declaration.type === 'ExportAllDeclaration') {
9
+ // Export * as ns from 'module' has an 'exported' property
10
+ if (declaration.exported)
11
+ return 're-export-namespace'
9
12
  return 're-export-all'
13
+ }
10
14
 
11
15
  // Example: export type {Type} from 'module'
12
16
  if (declaration.exportKind === 'type')
@@ -1,7 +1,7 @@
1
1
  import {categorizeReExport} from './categorizeReExport'
2
2
  import {getSortKey} from './getSortKey'
3
- import {ReExportDeclaration} from './ReExportDeclaration'
4
3
  import type {CategorizedReExport} from './CategorizedReExport'
4
+ import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
5
5
 
6
6
  export function categorizeReExports(declarations: ReExportDeclaration[]): CategorizedReExport[] {
7
7
  return declarations.map(declaration => {
@@ -1,4 +1,4 @@
1
- import {compare} from '../../lib/compare'
1
+ import {compare} from '@lib/compare'
2
2
  import {reExportGroupOrder} from './ReExportGroupOrder'
3
3
  import type {CategorizedReExport} from './CategorizedReExport'
4
4
  import type {ReExportError} from './ReExportError'
@@ -3,10 +3,11 @@ import {isNamedReExport} from '../isNamedReExport'
3
3
  import {reExportGroupOrder} from '../ReExportGroupOrder'
4
4
  import type {CategorizedReExport} from '../CategorizedReExport'
5
5
  import type {ReExportGroup} from '../ReExportGroup'
6
+ import type {TSESLint} from '@typescript-eslint/utils'
6
7
 
7
8
  export function buildSortedCode(
8
9
  grouped: Record<ReExportGroup, CategorizedReExport[]>,
9
- sourceCode: {getText: (node?: unknown) => string},
10
+ sourceCode: TSESLint.SourceCode,
10
11
  ): string[] {
11
12
  const sortedCode: string[] = []
12
13
 
@@ -1,11 +1,12 @@
1
1
  import {areSpecifiersSorted} from '../areSpecifiersSorted'
2
2
  import {getNamedSpecifiers} from '../getNamedSpecifiers'
3
3
  import {sortSpecifiersText} from '../sortSpecifiersText'
4
- import type {TSESTree} from '@typescript-eslint/types'
4
+ import type {TSESLint} from '@typescript-eslint/utils'
5
+ import type {TSESTree} from '@typescript-eslint/utils'
5
6
 
6
7
  export function formatNamedReExport(
7
8
  declaration: TSESTree.ExportNamedDeclaration,
8
- sourceCode: {getText: (node?: unknown) => string},
9
+ sourceCode: TSESLint.SourceCode,
9
10
  ): string {
10
11
  const specifiers = getNamedSpecifiers(declaration)
11
12
 
@@ -1,6 +1,6 @@
1
1
  import {findFirstExportIndex} from './findFirstExportIndex'
2
2
  import {findLastExportIndex} from './findLastExportIndex'
3
- import type {ReplacementRange} from '../../../lib/ReplacementRange'
3
+ import type {ReplacementRange} from '@lib/ReplacementRange'
4
4
  import type {TSESTree} from '@typescript-eslint/types'
5
5
 
6
6
  export function getReplacementRange(
@@ -6,6 +6,7 @@ export function groupReExportsByType(
6
6
  ): Record<ReExportGroup, CategorizedReExport[]> {
7
7
  const grouped: Record<ReExportGroup, CategorizedReExport[]> = {
8
8
  're-export-all': [],
9
+ 're-export-namespace': [],
9
10
  're-export-named': [],
10
11
  're-export-type': [],
11
12
  }