Skip to content

Commit 911e6fa

Browse files
authored
feat(sort-variable-declarations): add groups and custom groups
1 parent b57cf4f commit 911e6fa

File tree

8 files changed

+1985
-735
lines changed

8 files changed

+1985
-735
lines changed

docs/content/rules/sort-variable-declarations.mdx

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Specifies the sorting method.
8888
- `'natural'` — Sort items in a [natural](https://github.com/yobacca/natural-orderby) order (e.g., “item2” < “item10”).
8989
- `'line-length'` — Sort items by code line length (shorter lines first).
9090
- `'custom'` — Sort items using the alphabet specified in the [`alphabet`](#alphabet) option.
91-
- `'unsorted'` — Do not sort items.
91+
- `'unsorted'` — Do not sort items. [`grouping`](#groups) and [`newlines behavior`](#newlinesbetween) are still enforced.
9292

9393
### order
9494

@@ -196,6 +196,125 @@ const
196196

197197
Each group of variables (separated by empty lines) is treated independently, and the order within each group is preserved.
198198

199+
### newlinesBetween
200+
201+
<sub>default: `'ignore'`</sub>
202+
203+
Specifies how to handle new lines between groups.
204+
205+
- `ignore` — Do not report errors related to new lines.
206+
- `always` — Enforce one new line between each group, and forbid new lines inside a group.
207+
- `never` — No new lines are allowed.
208+
209+
You can also enforce the newline behavior between two specific groups through the `groups` options.
210+
211+
See the [`groups`](#newlines-between-groups) option.
212+
213+
This option is only applicable when [`partitionByNewLine`](#partitionbynewline) is `false`.
214+
215+
### groups
216+
217+
<sub>
218+
type: `Array<string | string[]>`
219+
</sub>
220+
<sub>default: `[]`</sub>
221+
222+
Specifies a list of groups for sorting. Groups help organize elements into categories.
223+
224+
Each element will be assigned a single group specified in the `groups` option (or the `unknown` group if no match is found).
225+
The order of items in the `groups` option determines how groups are ordered.
226+
227+
Within a given group, members will be sorted according to the `type`, `order`, `ignoreCase`, etc. options.
228+
229+
Individual groups can be combined together by placing them in an array. The order of groups in that array does not matter.
230+
All members of the groups in the array will be sorted together as if they were part of a single group.
231+
232+
Predefined groups are characterized by a selector.
233+
234+
##### List of selectors
235+
236+
- `initialized` — Initialized declarations.
237+
- `uninitialized` — Uninitialized declarations.
238+
239+
#### Newlines between groups
240+
241+
You may place `newlinesBetween` objects between your groups to enforce the newline behavior between two specific groups.
242+
243+
See the [`newlinesBetween`](#newlinesbetween) option.
244+
245+
This feature is only applicable when [`partitionByNewLine`](#partitionbynewline) is `false`.
246+
247+
```ts
248+
{
249+
newlinesBetween: 'always',
250+
groups: [
251+
'a',
252+
{ newlinesBetween: 'never' }, // Overrides the global newlinesBetween option
253+
'b',
254+
]
255+
}
256+
```
257+
258+
### customGroups
259+
260+
<sub>
261+
type: `Array<CustomGroupDefinition | CustomGroupAnyOfDefinition>`
262+
</sub>
263+
<sub>default: `[]`</sub>
264+
265+
Defines custom groups to match specific object type members.
266+
267+
A custom group definition may follow one of the two following interfaces:
268+
269+
```ts
270+
interface CustomGroupDefinition {
271+
groupName: string
272+
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
273+
order?: 'asc' | 'desc'
274+
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
275+
newlinesInside?: 'always' | 'never'
276+
selector?: string
277+
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
278+
}
279+
280+
```
281+
A declaration will match a `CustomGroupDefinition` group if it matches all the filters of the custom group's definition.
282+
283+
or:
284+
285+
```ts
286+
interface CustomGroupAnyOfDefinition {
287+
groupName: string
288+
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
289+
order?: 'asc' | 'desc'
290+
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
291+
newlinesInside?: 'always' | 'never'
292+
anyOf: Array<{
293+
selector?: string
294+
elementNamePattern?: string | string[] | { pattern: string; flags?: string } | { pattern: string; flags?: string }[]
295+
}>
296+
}
297+
```
298+
299+
A declaration will match a `CustomGroupAnyOfDefinition` group if it matches all the filters of at least one of the `anyOf` items.
300+
301+
#### Attributes
302+
303+
- `groupName` — The group's name, which needs to be put in the [`groups`](#groups) option.
304+
- `selector` — Filter on the `selector` of the element.
305+
- `elementNamePattern` — If entered, will check that the name of the element matches the pattern entered.
306+
- `type` — Overrides the [`type`](#type) option for that custom group. `unsorted` will not sort the group.
307+
- `order` — Overrides the [`order`](#order) option for that custom group.
308+
- `fallbackSort` — Overrides the [`fallbackSort`](#fallbacksort) option for that custom group.
309+
- `newlinesInside` — Enforces a specific newline behavior between elements of the group.
310+
311+
#### Match importance
312+
313+
The `customGroups` list is ordered:
314+
The first custom group definition that matches an element will be used.
315+
316+
Custom groups have a higher priority than any predefined group.
317+
199318
## Usage
200319

201320
<CodeTabs
@@ -221,6 +340,9 @@ Each group of variables (separated by empty lines) is treated independently, and
221340
specialCharacters: 'keep',
222341
partitionByNewLine: false,
223342
partitionByComment: false,
343+
newlinesBetween: 'ignore',
344+
groups: [],
345+
customGroups: [],
224346
},
225347
],
226348
},
@@ -248,6 +370,9 @@ Each group of variables (separated by empty lines) is treated independently, and
248370
specialCharacters: 'keep',
249371
partitionByNewLine: false,
250372
partitionByComment: false,
373+
newlinesBetween: 'ignore',
374+
groups: [],
375+
customGroups: [],
251376
},
252377
],
253378
},

rules/sort-intersection-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
4545
description: 'Enforce sorted intersection types.',
4646
recommended: true,
4747
},
48-
schema: [jsonSchema],
48+
schema: jsonSchema,
4949
type: 'suggestion',
5050
fixable: 'code',
5151
},

rules/sort-union-types.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,22 @@ let defaultOptions: Required<Options[0]> = {
6565
}
6666

6767
export let jsonSchema: JSONSchema4 = {
68-
properties: {
69-
...commonJsonSchemas,
70-
customGroups: buildCustomGroupsArrayJsonSchema({
71-
singleCustomGroupJsonSchema,
72-
}),
73-
partitionByComment: partitionByCommentJsonSchema,
74-
partitionByNewLine: partitionByNewLineJsonSchema,
75-
newlinesBetween: newlinesBetweenJsonSchema,
76-
groups: groupsJsonSchema,
68+
items: {
69+
properties: {
70+
...commonJsonSchemas,
71+
customGroups: buildCustomGroupsArrayJsonSchema({
72+
singleCustomGroupJsonSchema,
73+
}),
74+
partitionByComment: partitionByCommentJsonSchema,
75+
partitionByNewLine: partitionByNewLineJsonSchema,
76+
newlinesBetween: newlinesBetweenJsonSchema,
77+
groups: groupsJsonSchema,
78+
},
79+
additionalProperties: false,
80+
type: 'object',
7781
},
78-
additionalProperties: false,
79-
type: 'object',
82+
uniqueItems: true,
83+
type: 'array',
8084
}
8185

8286
export default createEslintRule<Options, MESSAGE_ID>({
@@ -107,7 +111,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
107111
description: 'Enforce sorted union types.',
108112
recommended: true,
109113
},
110-
schema: [jsonSchema],
114+
schema: jsonSchema,
111115
type: 'suggestion',
112116
fixable: 'code',
113117
},

rules/sort-union-types/types.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,15 @@ import {
1414
regexJsonSchema,
1515
} from '../../utils/common-json-schemas'
1616

17-
export type Options = [
18-
Partial<
19-
{
20-
customGroups: CustomGroupsOption<SingleCustomGroup>
21-
partitionByComment: PartitionByCommentOption
22-
newlinesBetween: NewlinesBetweenOption
23-
groups: GroupsOptions<Group>
24-
partitionByNewLine: boolean
25-
} & CommonOptions
26-
>,
27-
]
17+
export type Options = Partial<
18+
{
19+
customGroups: CustomGroupsOption<SingleCustomGroup>
20+
partitionByComment: PartitionByCommentOption
21+
newlinesBetween: NewlinesBetweenOption
22+
groups: GroupsOptions<Group>
23+
partitionByNewLine: boolean
24+
} & CommonOptions
25+
>[]
2826

2927
export type Selector =
3028
| IntersectionSelector

0 commit comments

Comments
 (0)