@borela-tech/eslint-config 2.2.2 → 2.3.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 +3589 -811
  4. package/dist/index.mjs.map +1 -1
  5. package/jest.config.ts +19 -0
  6. package/package.json +17 -8
  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,220 +0,0 @@
1
- import typescript from 'typescript-eslint'
2
- import {dedent} from './dedent'
3
- import {RuleTester} from 'eslint'
4
- import {sortedReExports} from '../sortedReExports'
5
- import type {Rule} from 'eslint'
6
-
7
- const rule = sortedReExports as unknown as Rule.RuleModule
8
- const ruleTester = new RuleTester({
9
- languageOptions: {
10
- parser: typescript.parser,
11
- parserOptions: {
12
- ecmaVersion: 2020,
13
- sourceType: 'module',
14
- },
15
- },
16
- })
17
-
18
- ruleTester.run('sorted-re-exports', rule, {
19
- valid: [{
20
- code: 'export const foo = 42',
21
- }, {
22
- code: 'export function bar() {}',
23
- }, {
24
- code: 'export {foo}',
25
- }, {
26
- code: "export {foo} from 'bar'",
27
- }, {
28
- code: "export * from 'bar'",
29
- }, {
30
- code: "export type {Foo} from 'bar'",
31
- }, {
32
- code: "export * as ns from 'bar'",
33
- }, {
34
- code: dedent`
35
- export * from 'aaa'
36
- export * as fs from 'fs'
37
- export * as path from 'path'
38
- export {a} from 'aaa'
39
- export {b} from 'bbb'
40
- export type {X} from 'xxx'
41
- export type {Y} from 'yyy'
42
- `,
43
- }, {
44
- code: dedent`
45
- export {a, b, c} from 'bar'
46
- `,
47
- }, {
48
- code: dedent`
49
- export const foo = 42
50
- export {bar} from 'baz'
51
- `,
52
- }, {
53
- code: dedent`
54
- function foo() {}
55
- export {foo}
56
- export * from 'bar'
57
- `,
58
- }, {
59
- code: dedent`
60
- export * from 'bbb'
61
- export {a} from 'aaa'
62
- `,
63
- }, {
64
- code: dedent`
65
- export const z = 1
66
- export {a} from 'bar'
67
- export function foo() {}
68
- export {b} from 'baz'
69
- export class Bar {}
70
- `,
71
- }, {
72
- code: dedent`
73
- export class Child extends Parent {}
74
- export class Parent {}
75
- export {child} from 'child-module'
76
- `,
77
- }, {
78
- code: dedent`
79
- export {a} from 'aaa'
80
- export const c = 3
81
- export {x} from 'xxx'
82
- export const b = 2
83
- export {z} from 'zzz'
84
- `,
85
- }, {
86
- code: '',
87
- }, {
88
- code: 'const x = 1',
89
- }],
90
- invalid: [{
91
- code: dedent`
92
- export {c, a, b} from 'bar'
93
- `,
94
- errors: [{messageId: 'sortedNames'}],
95
- output: dedent`
96
- export {a, b, c} from 'bar'
97
- `,
98
- }, {
99
- code: dedent`
100
- export {b} from 'b'
101
- const x = 1
102
- export {c} from 'c'
103
- export {a} from 'a'
104
- `,
105
- errors: [{messageId: 'sortedReExports'}, {messageId: 'sortedReExports'}],
106
- output: dedent`
107
- export {b} from 'b'
108
- const x = 1
109
- export {a} from 'a'
110
- export {c} from 'c'
111
- `,
112
- }, {
113
- code: dedent`
114
- export {b} from 'b'
115
- export {a} from 'a'
116
- const x = 1
117
- export {d} from 'd'
118
- export {c} from 'c'
119
- const y = 2
120
- export {f} from 'f'
121
- export {e} from 'e'
122
- `,
123
- errors: [
124
- {messageId: 'sortedReExports'},
125
- {messageId: 'sortedReExports'},
126
- {messageId: 'sortedReExports'},
127
- {messageId: 'sortedReExports'},
128
- {messageId: 'sortedReExports'},
129
- {messageId: 'sortedReExports'},
130
- ],
131
- output: dedent`
132
- export {a} from 'a'
133
- export {b} from 'b'
134
- const x = 1
135
- export {c} from 'c'
136
- export {d} from 'd'
137
- const y = 2
138
- export {e} from 'e'
139
- export {f} from 'f'
140
- `,
141
- }, {
142
- code: dedent`
143
- export {z, a} from 'bar'
144
- `,
145
- errors: [{messageId: 'sortedNames'}],
146
- output: dedent`
147
- export {a, z} from 'bar'
148
- `,
149
- }, {
150
- code: dedent`
151
- export * from 'bbb'
152
- export * from 'aaa'
153
- `,
154
- errors: [{messageId: 'sortedReExports'}, {messageId: 'sortedReExports'}],
155
- output: dedent`
156
- export * from 'aaa'
157
- export * from 'bbb'
158
- `,
159
- }, {
160
- code: dedent`
161
- export type {Y} from 'yyy'
162
- export type {X} from 'xxx'
163
- `,
164
- errors: [{messageId: 'sortedReExports'}, {messageId: 'sortedReExports'}],
165
- output: dedent`
166
- export type {X} from 'xxx'
167
- export type {Y} from 'yyy'
168
- `,
169
- }, {
170
- code: dedent`
171
- export {a} from 'bar'
172
- export * from 'aaa'
173
- `,
174
- errors: [{messageId: 'wrongGroup'}],
175
- output: dedent`
176
- export * from 'aaa'
177
- export {a} from 'bar'
178
- `,
179
- }, {
180
- code: dedent`
181
- export {b, a} from 'bar'
182
- export * from 'aaa'
183
- `,
184
- errors: [{messageId: 'sortedNames'}, {messageId: 'wrongGroup'}],
185
- output: dedent`
186
- export * from 'aaa'
187
- export {a, b} from 'bar'
188
- `,
189
- }, {
190
- code: dedent`
191
- export {existsSync} from 'fs'
192
- export {basename} from 'path'
193
- `,
194
- errors: [{messageId: 'sortedReExports'}, {messageId: 'sortedReExports'}],
195
- output: dedent`
196
- export {basename} from 'path'
197
- export {existsSync} from 'fs'
198
- `,
199
- }, {
200
- code: dedent`
201
- export * as path from 'path'
202
- export * as fs from 'fs'
203
- `,
204
- errors: [{messageId: 'sortedReExports'}, {messageId: 'sortedReExports'}],
205
- output: dedent`
206
- export * as fs from 'fs'
207
- export * as path from 'path'
208
- `,
209
- }, {
210
- code: dedent`
211
- export {foo} from 'bar'
212
- export * as fs from 'fs'
213
- `,
214
- errors: [{messageId: 'wrongGroup'}],
215
- output: dedent`
216
- export * as fs from 'fs'
217
- export {foo} from 'bar'
218
- `,
219
- }],
220
- })
@@ -1,8 +0,0 @@
1
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export interface CategorizedStatements {
5
- imports: TSESTree.ImportDeclaration[]
6
- reExports: ReExportDeclaration[]
7
- other: TSESTree.Statement[]
8
- }
@@ -1,5 +0,0 @@
1
- export interface StatementIndices {
2
- firstRegularStatement: number
3
- lastImport: number
4
- lastReExport: number
5
- }
@@ -1,28 +0,0 @@
1
- import {getStatementType} from './getStatementType'
2
- import {isImportDeclaration} from './isImportDeclaration'
3
- import {isReExport} from './isReExport'
4
- import type {CategorizedStatements} from './CategorizedStatements'
5
- import type {TSESTree} from '@typescript-eslint/types'
6
-
7
- export function categorizeStatements(
8
- statements: TSESTree.ProgramStatement[],
9
- ): CategorizedStatements {
10
- const result: CategorizedStatements = {
11
- imports: [],
12
- reExports: [],
13
- other: [],
14
- }
15
-
16
- for (const statement of statements) {
17
- const type = getStatementType(statement)
18
-
19
- if (type === 'import' && isImportDeclaration(statement))
20
- result.imports.push(statement)
21
- else if (type === 're-export' && isReExport(statement))
22
- result.reExports.push(statement)
23
- else
24
- result.other.push(statement)
25
- }
26
-
27
- return result
28
- }
@@ -1,25 +0,0 @@
1
- import {getStatementType} from './getStatementType'
2
- import type {StatementIndices} from './StatementIndices'
3
- import type {StatementType} from './statementType'
4
- import type {TSESTree} from '@typescript-eslint/types'
5
-
6
- export function findStatementIndices(
7
- statements: TSESTree.Statement[],
8
- ): StatementIndices {
9
- let firstRegularStatement = -1
10
- let lastImport = -1
11
- let lastReExport = -1
12
-
13
- for (let i = 0; i < statements.length; i++) {
14
- const type: StatementType = getStatementType(statements[i])
15
-
16
- if (type === 'import')
17
- lastImport = i
18
- else if (type === 're-export')
19
- lastReExport = i
20
- else if (type === 'other' && firstRegularStatement === -1)
21
- firstRegularStatement = i
22
- }
23
-
24
- return {firstRegularStatement, lastImport, lastReExport}
25
- }
@@ -1,16 +0,0 @@
1
- import type {CategorizedStatements} from './CategorizedStatements'
2
- import type {TSESLint} from '@typescript-eslint/utils'
3
-
4
- export function generateSortedText(
5
- context: TSESLint.RuleContext<'importsAndReExportsAtTop', []>,
6
- categories: CategorizedStatements,
7
- ): string {
8
- const allStatements = [
9
- ...categories.imports,
10
- ...categories.reExports,
11
- ...categories.other,
12
- ]
13
- return allStatements.map(
14
- node => context.sourceCode.getText(node),
15
- ).join('\n')
16
- }
@@ -1,17 +0,0 @@
1
- import type {StatementType} from './statementType'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export function getStatementType(statement: TSESTree.Statement): StatementType {
5
- if (statement.type === 'ImportDeclaration')
6
- return 'import'
7
-
8
- if (statement.type === 'ExportAllDeclaration')
9
- return 're-export'
10
-
11
- if (statement.type === 'ExportNamedDeclaration') {
12
- if (statement.source !== null)
13
- return 're-export'
14
- }
15
-
16
- return 'other'
17
- }
@@ -1,25 +0,0 @@
1
- import type {CategorizedStatements} from './CategorizedStatements'
2
- import type {StatementIndices} from './StatementIndices'
3
-
4
- export function hasViolation(
5
- indices: StatementIndices,
6
- categories: CategorizedStatements,
7
- ): boolean {
8
- const {firstRegularStatement, lastImport, lastReExport} = indices
9
-
10
- if (categories.imports.length === 0 && categories.reExports.length === 0)
11
- return false
12
-
13
- const hasImportAfterRegularStatement = (
14
- categories.imports.length > 0
15
- && firstRegularStatement !== -1
16
- && lastImport > firstRegularStatement
17
- )
18
- const hasReExportAfterRegularStatement = (
19
- categories.reExports.length > 0
20
- && firstRegularStatement !== -1
21
- && lastReExport > firstRegularStatement
22
- )
23
-
24
- return hasImportAfterRegularStatement || hasReExportAfterRegularStatement
25
- }
@@ -1,45 +0,0 @@
1
- import {categorizeStatements} from './categorizeStatements'
2
- import {findStatementIndices} from './findStatementIndices'
3
- import {generateSortedText} from './generateSortedText'
4
- import {hasViolation} from './hasViolation'
5
- import type {TSESLint} from '@typescript-eslint/utils'
6
-
7
- type MessageIds = 'importsAndReExportsAtTop'
8
-
9
- export const importsAndReExportsAtTop: TSESLint.RuleModule<MessageIds, []> = {
10
- meta: {
11
- type: 'suggestion',
12
- docs: {
13
- description: 'Enforce imports and re-exports at the top of the file',
14
- },
15
- fixable: 'code',
16
- messages: {
17
- importsAndReExportsAtTop:
18
- 'Imports and re-exports should be at the top of the file.',
19
- },
20
- schema: [],
21
- },
22
-
23
- create(context) {
24
- return {
25
- Program(node) {
26
- const statements = node.body
27
- const categories = categorizeStatements(statements)
28
- const indices = findStatementIndices(statements)
29
-
30
- if (!hasViolation(indices, categories))
31
- return
32
-
33
- context.report({
34
- node,
35
- messageId: 'importsAndReExportsAtTop',
36
-
37
- fix(fixer) {
38
- const sortedText = generateSortedText(context, categories)
39
- return fixer.replaceText(node, sortedText)
40
- },
41
- })
42
- },
43
- }
44
- },
45
- }
@@ -1,7 +0,0 @@
1
- import type {TSESTree} from '@typescript-eslint/types'
2
-
3
- export function isImportDeclaration(
4
- statement: TSESTree.ProgramStatement,
5
- ): statement is TSESTree.ImportDeclaration {
6
- return statement.type === 'ImportDeclaration'
7
- }
@@ -1,12 +0,0 @@
1
- import type {ReExportDeclaration} from '@lib/ReExportDeclaration'
2
- import type {TSESTree} from '@typescript-eslint/types'
3
-
4
- export function isReExport(
5
- statement: TSESTree.ProgramStatement,
6
- ): statement is ReExportDeclaration {
7
- if (statement.type === 'ExportAllDeclaration')
8
- return true
9
- if (statement.type === 'ExportNamedDeclaration')
10
- return statement.source !== null
11
- return false
12
- }
@@ -1,4 +0,0 @@
1
- export type StatementType =
2
- | 'import'
3
- | 'other'
4
- | 're-export'
@@ -1,38 +0,0 @@
1
- import type {TSESLint} from '@typescript-eslint/utils'
2
-
3
- type MessageIds = 'individualImports'
4
-
5
- export const individualImports: TSESLint.RuleModule<MessageIds, []> = {
6
- meta: {
7
- docs: {
8
- description: 'Enforce individual imports instead of grouped imports',
9
- },
10
- fixable: 'code',
11
- messages: {
12
- individualImports: 'Use individual imports instead of grouped imports.',
13
- },
14
- schema: [],
15
- type: 'suggestion',
16
- },
17
- create(context) {
18
- return {
19
- ImportDeclaration(node) {
20
- if (node.specifiers.length <= 1)
21
- return
22
-
23
- context.report({
24
- node,
25
- messageId: 'individualImports',
26
- fix(fixer) {
27
- const source = node.source.raw
28
- const specifiers = node.specifiers
29
- .filter(s => s.type === 'ImportSpecifier')
30
- .map(s => `import {${s.local.name}} from ${source}`)
31
- .join('\n')
32
- return fixer.replaceText(node, specifiers)
33
- },
34
- })
35
- },
36
- }
37
- },
38
- }
@@ -1,51 +0,0 @@
1
- import type {TSESLint} from '@typescript-eslint/utils'
2
-
3
- type MessageIds = 'individualReExports'
4
-
5
- export const individualReExports: TSESLint.RuleModule<MessageIds, []> = {
6
- meta: {
7
- docs: {
8
- description: 'Enforce individual exports instead of grouped exports',
9
- },
10
- fixable: 'code',
11
- messages: {
12
- individualReExports: 'Use individual exports instead of grouped exports.',
13
- },
14
- schema: [],
15
- type: 'suggestion',
16
- },
17
- create(context) {
18
- return {
19
- ExportNamedDeclaration(node) {
20
- if (!node.source || node.specifiers.length <= 1)
21
- return
22
-
23
- context.report({
24
- node,
25
- messageId: 'individualReExports',
26
- fix(fixer) {
27
- const source = node.source.value
28
- const typeKeyword = node.exportKind === 'type'
29
- ? 'type '
30
- : ''
31
- const specifiers = node.specifiers
32
- .map(s => {
33
- const localName = s.local.type === 'Identifier'
34
- ? s.local.name
35
- : s.local.value
36
- const exportedName = s.exported.type === 'Identifier'
37
- ? s.exported.name
38
- : s.exported.value
39
- const name = localName === exportedName
40
- ? localName
41
- : `${localName} as ${exportedName}`
42
- return `export ${typeKeyword}{${name}} from '${source}'`
43
- })
44
- .join('\n')
45
- return fixer.replaceText(node, specifiers)
46
- },
47
- })
48
- },
49
- }
50
- },
51
- }
@@ -1,13 +0,0 @@
1
- import type {TSESLint} from '@typescript-eslint/utils'
2
- import type {TSESTree} from '@typescript-eslint/utils'
3
-
4
- export function createFix(
5
- fixer: TSESLint.RuleFixer,
6
- node: TSESTree.TSUnionType,
7
- sourceCode: TSESLint.SourceCode,
8
- ): TSESLint.RuleFix {
9
- const types = node.types.map(t => sourceCode.getText(t))
10
- const formattedTypes = types.map(t => ` | ${t}`).join('\n')
11
- const result = `\n${formattedTypes}`
12
- return fixer.replaceText(node, result)
13
- }
@@ -1,52 +0,0 @@
1
- import {createFix} from './createFix'
2
- import {isMultiline} from './isMultiline'
3
- import type {TSESLint} from '@typescript-eslint/utils'
4
-
5
- type MessageIds =
6
- | 'singleLine'
7
- | 'missingPipes'
8
-
9
- export const multilineUnionTypes: TSESLint.RuleModule<MessageIds, []> = {
10
- meta: {
11
- docs: {
12
- description: 'Enforce union types with multiple members to be on multiple lines',
13
- },
14
- fixable: 'code',
15
- messages: {
16
- singleLine: 'Union types with multiple members should be on multiple lines',
17
- missingPipes: 'Multiline union types should have leading pipes on each member',
18
- },
19
- schema: [],
20
- type: 'layout',
21
- },
22
-
23
- create(context) {
24
- return {
25
- TSUnionType(node) {
26
- if (node.types.length < 2)
27
- return
28
-
29
- const sourceCode = context.sourceCode
30
- const text = sourceCode.getText(node)
31
-
32
- if (text.trim().startsWith('|'))
33
- return
34
-
35
- if (!isMultiline(node)) {
36
- context.report({
37
- node,
38
- messageId: 'singleLine',
39
- fix: fixer => createFix(fixer, node, sourceCode),
40
- })
41
- return
42
- }
43
-
44
- context.report({
45
- node,
46
- messageId: 'missingPipes',
47
- fix: fixer => createFix(fixer, node, sourceCode),
48
- })
49
- },
50
- }
51
- },
52
- }
@@ -1,6 +0,0 @@
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
- }
@@ -1,23 +0,0 @@
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
- }
@@ -1,20 +0,0 @@
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
- }
@@ -1,9 +0,0 @@
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
- }
@@ -1,32 +0,0 @@
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
- }