Skip to content

Commit 1a02538

Browse files
authored
feat: enforce group comments
1 parent 47b3510 commit 1a02538

26 files changed

+1168
-92
lines changed

docs/content/rules/sort-exports.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,30 @@ This feature is only applicable when [`partitionByNewLine`](#partitionbynewline)
277277
}
278278
```
279279

280+
#### Comment above groups
281+
282+
You may place `commentAbove` objects between above your groups to enforce the presence of a comment containing the
283+
content of `commentAbove`.
284+
285+
`newlinesBetween` and `commentAbove` objects can be combined together.
286+
287+
```ts
288+
{
289+
groups: [
290+
{ commentAbove: 'Type exports' },
291+
'type-export',
292+
{ commentAbove: 'Value exports' },
293+
'value-export',
294+
]
295+
}
296+
```
297+
298+
- An error will be raised if no comment containing the content of `commentAbove` is found above the top element of the
299+
group.
300+
- Auto-fixing will add a comment containing the content of `commentAbove` above the top element of the group.
301+
- Auto-fixing will also remove invalid auto-added comments (only comments existing in `commentAbove`
302+
objects are considered as auto-removable).
303+
280304
### customGroups
281305

282306
<sub>

docs/content/rules/sort-imports.mdx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,30 @@ This feature is only applicable when [`partitionByNewLine`](#partitionbynewline)
465465
}
466466
```
467467

468+
#### Comment above groups
469+
470+
You may place `commentAbove` objects between above your groups to enforce the presence of a comment containing the
471+
content of `commentAbove`.
472+
473+
`newlinesBetween` and `commentAbove` objects can be combined together.
474+
475+
```ts
476+
{
477+
groups: [
478+
{ commentAbove: 'Internal imports' },
479+
'internal',
480+
{ commentAbove: 'External imports' },
481+
'external',
482+
]
483+
}
484+
```
485+
486+
- An error will be raised if no comment containing the content of `commentAbove` is found above the top element of the
487+
group.
488+
- Auto-fixing will add a comment containing the content of `commentAbove` above the top element of the group.
489+
- Auto-fixing will also remove invalid auto-added comments (only comments existing in `commentAbove`
490+
objects are considered as auto-removable).
491+
468492
### customGroups
469493

470494
<Important title="Migrating from the old API">

rules/sort-exports.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
groupsJsonSchema,
1313
} from '../utils/common-json-schemas'
1414
import {
15+
MISSED_COMMENT_ABOVE_ERROR,
1516
MISSED_SPACING_ERROR,
1617
EXTRA_SPACING_ERROR,
1718
GROUP_ORDER_ERROR,
@@ -41,19 +42,20 @@ import { complete } from '../utils/complete'
4142
*/
4243
let cachedGroupsByModifiersAndSelectors = new Map<string, string[]>()
4344

45+
type MESSAGE_ID =
46+
| 'unexpectedExportsGroupOrder'
47+
| 'missedSpacingBetweenExports'
48+
| 'extraSpacingBetweenExports'
49+
| 'missedCommentAboveExport'
50+
| 'unexpectedExportsOrder'
51+
4452
interface SortExportsSortingNode
4553
extends SortingNode<
4654
TSESTree.ExportNamedDeclarationWithSource | TSESTree.ExportAllDeclaration
4755
> {
4856
groupKind: 'value' | 'type'
4957
}
5058

51-
type MESSAGE_ID =
52-
| 'unexpectedExportsGroupOrder'
53-
| 'missedSpacingBetweenExports'
54-
| 'extraSpacingBetweenExports'
55-
| 'unexpectedExportsOrder'
56-
5759
let defaultOptions: Required<Options[0]> = {
5860
fallbackSort: { type: 'unsorted' },
5961
specialCharacters: 'keep',
@@ -184,6 +186,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
184186
missedSpacingBetweenMembers: 'missedSpacingBetweenExports',
185187
extraSpacingBetweenMembers: 'extraSpacingBetweenExports',
186188
unexpectedGroupOrder: 'unexpectedExportsGroupOrder',
189+
missedCommentAbove: 'missedCommentAboveExport',
187190
unexpectedOrder: 'unexpectedExportsOrder',
188191
},
189192
sortNodesExcludingEslintDisabled,
@@ -227,6 +230,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
227230
type: 'array',
228231
},
229232
messages: {
233+
missedCommentAboveExport: MISSED_COMMENT_ABOVE_ERROR,
230234
missedSpacingBetweenExports: MISSED_SPACING_ERROR,
231235
extraSpacingBetweenExports: EXTRA_SPACING_ERROR,
232236
unexpectedExportsGroupOrder: GROUP_ORDER_ERROR,

rules/sort-imports.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
regexJsonSchema,
2525
} from '../utils/common-json-schemas'
2626
import {
27+
MISSED_COMMENT_ABOVE_ERROR,
2728
DEPENDENCY_ORDER_ERROR,
2829
MISSED_SPACING_ERROR,
2930
EXTRA_SPACING_ERROR,
@@ -67,6 +68,7 @@ export type MESSAGE_ID =
6768
| 'missedSpacingBetweenImports'
6869
| 'unexpectedImportsGroupOrder'
6970
| 'extraSpacingBetweenImports'
71+
| 'missedCommentAboveImport'
7072
| 'unexpectedImportsOrder'
7173

7274
let defaultOptions: Required<
@@ -390,6 +392,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
390392
missedSpacingBetweenMembers: 'missedSpacingBetweenImports',
391393
extraSpacingBetweenMembers: 'extraSpacingBetweenImports',
392394
unexpectedGroupOrder: 'unexpectedImportsGroupOrder',
395+
missedCommentAbove: 'missedCommentAboveImport',
393396
unexpectedOrder: 'unexpectedImportsOrder',
394397
},
395398
options: {
@@ -494,6 +497,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
494497
},
495498
messages: {
496499
unexpectedImportsDependencyOrder: DEPENDENCY_ORDER_ERROR,
500+
missedCommentAboveImport: MISSED_COMMENT_ABOVE_ERROR,
497501
missedSpacingBetweenImports: MISSED_SPACING_ERROR,
498502
extraSpacingBetweenImports: EXTRA_SPACING_ERROR,
499503
unexpectedImportsGroupOrder: GROUP_ORDER_ERROR,

rules/sort-imports/is-side-effect-only-group.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { GroupsOptions } from '../../types/common-options'
22

33
import { isNewlinesBetweenOption } from '../../utils/is-newlines-between-option'
4+
import { isCommentAboveOption } from '../../utils/is-comment-above-option'
45

56
export let isSideEffectOnlyGroup = (
67
group: GroupsOptions<string>[0],
78
): boolean => {
8-
if (isNewlinesBetweenOption(group)) {
9+
if (isNewlinesBetweenOption(group) || isCommentAboveOption(group)) {
910
return false
1011
}
1112
if (typeof group === 'string') {

rules/sort-switch-case.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
9797
let nodeIndexMap = createNodeIndexMap(sortedCaseNameSortingNodes)
9898

9999
pairwise(caseNodesSortingNodeGroup, (left, right) => {
100+
if (!left) {
101+
return
102+
}
103+
100104
let leftIndex = nodeIndexMap.get(left)!
101105
let rightIndex = nodeIndexMap.get(right)!
102106

@@ -230,6 +234,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
230234
let sortingNodeGroupsForBlockSortFlat =
231235
sortingNodeGroupsForBlockSort.flat()
232236
pairwise(sortingNodeGroupsForBlockSortFlat, (left, right) => {
237+
if (!left) {
238+
return
239+
}
240+
233241
let indexOfLeft = sortedSortingNodeGroupsForBlockSort.indexOf(left)
234242
let indexOfRight = sortedSortingNodeGroupsForBlockSort.indexOf(right)
235243
if (indexOfLeft < indexOfRight) {
@@ -242,6 +250,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
242250
: makeFixes({
243251
sortedNodes: sortedSortingNodeGroupsForBlockSort,
244252
nodes: sortingNodeGroupsForBlockSortFlat,
253+
hasCommentAboveMissing: false,
245254
sourceCode,
246255
fixer,
247256
}),

0 commit comments

Comments
 (0)