Skip to content

Commit 79d0441

Browse files
authored
feat: support sorting by type in fallback sorting
1 parent f42f24f commit 79d0441

17 files changed

+568
-55
lines changed

docs/content/rules/sort-interfaces.mdx

+3-2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ Determines whether the sorted items should be in ascending or descending order.
162162
{
163163
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
164164
order?: 'asc' | 'desc'
165+
sortBy?: 'name' | 'value'
165166
}
166167
```
167168
</sub>
@@ -560,7 +561,7 @@ interface CustomGroupDefinition {
560561
groupName: string
561562
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
562563
order?: 'asc' | 'desc'
563-
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
564+
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
564565
sortBy?: 'name' | 'value'
565566
newlinesInside?: 'always' | 'never'
566567
selector?: string
@@ -579,7 +580,7 @@ interface CustomGroupAnyOfDefinition {
579580
groupName: string
580581
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
581582
order?: 'asc' | 'desc'
582-
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
583+
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
583584
sortBy?: 'name' | 'value'
584585
newlinesInside?: 'always' | 'never'
585586
anyOf: Array<{

docs/content/rules/sort-object-types.mdx

+3-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ Determines whether the sorted items should be in ascending or descending order.
124124
{
125125
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
126126
order?: 'asc' | 'desc'
127+
sortBy?: 'name' | 'value'
127128
}
128129
```
129130
</sub>
@@ -507,7 +508,7 @@ interface CustomGroupDefinition {
507508
groupName: string
508509
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
509510
order?: 'asc' | 'desc'
510-
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
511+
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
511512
sortBy?: 'name' | 'value'
512513
newlinesInside?: 'always' | 'never'
513514
selector?: string
@@ -526,7 +527,7 @@ interface CustomGroupAnyOfDefinition {
526527
groupName: string
527528
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
528529
order?: 'asc' | 'desc'
529-
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
530+
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
530531
sortBy?: 'name' | 'value'
531532
newlinesInside?: 'always' | 'never'
532533
anyOf: Array<{

rules/sort-object-types.ts

+17-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
partitionByNewLineJsonSchema,
1818
newlinesBetweenJsonSchema,
1919
customGroupsJsonSchema,
20-
commonJsonSchemas,
20+
buildCommonJsonSchemas,
2121
groupsJsonSchema,
2222
regexJsonSchema,
2323
} from '../utils/common-json-schemas'
@@ -68,7 +68,7 @@ type MESSAGE_ID =
6868
| 'unexpectedObjectTypesOrder'
6969

7070
let defaultOptions: Required<Options[0]> = {
71-
fallbackSort: { type: 'unsorted' },
71+
fallbackSort: { type: 'unsorted', sortBy: 'name' },
7272
partitionByComment: false,
7373
partitionByNewLine: false,
7474
newlinesBetween: 'ignore',
@@ -89,11 +89,18 @@ let defaultOptions: Required<Options[0]> = {
8989
export let jsonSchema: JSONSchema4 = {
9090
items: {
9191
properties: {
92-
...commonJsonSchemas,
92+
...buildCommonJsonSchemas({
93+
additionalFallbackSortProperties: {
94+
sortBy: sortByJsonSchema,
95+
},
96+
}),
9397
customGroups: {
9498
oneOf: [
9599
customGroupsJsonSchema,
96-
buildCustomGroupsArrayJsonSchema({ singleCustomGroupJsonSchema }),
100+
buildCustomGroupsArrayJsonSchema({
101+
additionalFallbackSortProperties: { sortBy: sortByJsonSchema },
102+
singleCustomGroupJsonSchema,
103+
}),
97104
],
98105
},
99106
useConfigurationIf: buildUseConfigurationIfJsonSchema({
@@ -363,13 +370,17 @@ export let sortObjectTypeElements = <MessageIds extends string>({
363370
filteredGroupKindNodes.flatMap(groupedNodes =>
364371
sortNodesByGroups({
365372
getOptionsByGroupNumber: groupNumber => {
366-
let { options: overriddenOptions, nodeValueGetter } =
367-
getCustomGroupsCompareOptions(options, groupNumber)
373+
let {
374+
fallbackSortNodeValueGetter,
375+
options: overriddenOptions,
376+
nodeValueGetter,
377+
} = getCustomGroupsCompareOptions(options, groupNumber)
368378
return {
369379
options: {
370380
...options,
371381
...overriddenOptions,
372382
},
383+
fallbackSortNodeValueGetter,
373384
nodeValueGetter,
374385
}
375386
},

rules/sort-object-types/get-custom-groups-compare-options.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,43 @@ export let getCustomGroupsCompareOptions = (
1717
Required<Options[0]>,
1818
'fallbackSort' | 'sortBy' | 'order' | 'type'
1919
>
20+
fallbackSortNodeValueGetter?: NodeValueGetterFunction<SortObjectTypesSortingNode> | null
2021
nodeValueGetter?: NodeValueGetterFunction<SortObjectTypesSortingNode> | null
2122
} => {
2223
let baseCompareOptions = baseGetCustomGroupsCompareOptions(
2324
options,
2425
groupNumber,
2526
)
2627

27-
let { customGroups, sortBy, groups } = options
28+
let { fallbackSort, customGroups, sortBy, groups } = options
29+
let fallbackSortBy = fallbackSort.sortBy
2830
if (Array.isArray(customGroups)) {
2931
let group = groups[groupNumber]
3032
let customGroup =
3133
typeof group === 'string'
3234
? customGroups.find(currentGroup => group === currentGroup.groupName)
3335
: null
3436

35-
if (customGroup && 'sortBy' in customGroup && customGroup.sortBy) {
36-
;({ sortBy } = customGroup)
37+
if (customGroup) {
38+
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy
39+
if ('sortBy' in customGroup && customGroup.sortBy) {
40+
;({ sortBy } = customGroup)
41+
}
3742
}
3843
}
3944

4045
return {
4146
options: {
4247
...baseCompareOptions,
48+
fallbackSort: {
49+
...baseCompareOptions.fallbackSort,
50+
sortBy: fallbackSortBy,
51+
},
4352
sortBy,
4453
},
54+
fallbackSortNodeValueGetter: fallbackSortBy
55+
? buildNodeValueGetter(fallbackSortBy)
56+
: null,
4557
nodeValueGetter: buildNodeValueGetter(sortBy),
4658
}
4759
}

rules/sort-object-types/types.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
PartitionByCommentOption,
77
NewlinesBetweenOption,
88
CustomGroupsOption,
9+
FallbackSortOption,
910
CommonOptions,
1011
GroupsOptions,
1112
RegexOption,
@@ -21,13 +22,19 @@ import {
2122

2223
export type Options = Partial<
2324
{
25+
customGroups:
26+
| CustomGroupsOption<
27+
SingleCustomGroup,
28+
{
29+
fallbackSort?: { sortBy?: 'value' | 'name' } & FallbackSortOption
30+
}
31+
>
32+
| DeprecatedCustomGroupsOption
2433
useConfigurationIf: {
2534
declarationMatchesPattern?: RegexOption
2635
allNamesMatchPattern?: RegexOption
2736
}
28-
customGroups:
29-
| CustomGroupsOption<SingleCustomGroup>
30-
| DeprecatedCustomGroupsOption
37+
fallbackSort: { sortBy?: 'value' | 'name' } & FallbackSortOption
3138
/**
3239
* @deprecated for {@link `groups`}
3340
*/
@@ -41,7 +48,7 @@ export type Options = Partial<
4148
*/
4249
ignorePattern: RegexOption
4350
sortBy: 'value' | 'name'
44-
} & CommonOptions
51+
} & Omit<CommonOptions, 'fallbackSort'>
4552
>[]
4653

4754
export type SingleCustomGroup = (

test/rules/sort-interfaces.test.ts

+75
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,47 @@ describe(ruleName, () => {
13031303
}
13041304
`,
13051305
},
1306+
{
1307+
options: [
1308+
{
1309+
customGroups: [
1310+
{
1311+
fallbackSort: {
1312+
type: 'alphabetical',
1313+
sortBy: 'value',
1314+
},
1315+
elementValuePattern: '^foo',
1316+
type: 'line-length',
1317+
groupName: 'foo',
1318+
},
1319+
],
1320+
type: 'alphabetical',
1321+
groups: ['foo'],
1322+
order: 'asc',
1323+
},
1324+
],
1325+
errors: [
1326+
{
1327+
data: {
1328+
right: 'b',
1329+
left: 'a',
1330+
},
1331+
messageId: 'unexpectedInterfacePropertiesOrder',
1332+
},
1333+
],
1334+
output: dedent`
1335+
interface Interface {
1336+
b: fooBar
1337+
a: fooZar
1338+
}
1339+
`,
1340+
code: dedent`
1341+
interface Interface {
1342+
a: fooZar
1343+
b: fooBar
1344+
}
1345+
`,
1346+
},
13061347
],
13071348
valid: [],
13081349
},
@@ -5048,6 +5089,40 @@ describe(ruleName, () => {
50485089
}
50495090
`,
50505091
},
5092+
{
5093+
errors: [
5094+
{
5095+
data: {
5096+
right: 'bb',
5097+
left: 'c',
5098+
},
5099+
messageId: 'unexpectedInterfacePropertiesOrder',
5100+
},
5101+
],
5102+
options: [
5103+
{
5104+
...options,
5105+
fallbackSort: {
5106+
type: 'alphabetical',
5107+
sortBy: 'value',
5108+
},
5109+
},
5110+
],
5111+
output: dedent`
5112+
interface Interface {
5113+
bb: string;
5114+
c: boolean;
5115+
a: number;
5116+
}
5117+
`,
5118+
code: dedent`
5119+
interface Interface {
5120+
c: boolean;
5121+
bb: string;
5122+
a: number;
5123+
}
5124+
`,
5125+
},
50515126
],
50525127
valid: [],
50535128
},

test/rules/sort-object-types.test.ts

+75
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,47 @@ describe(ruleName, () => {
10441044
}
10451045
`,
10461046
},
1047+
{
1048+
options: [
1049+
{
1050+
customGroups: [
1051+
{
1052+
fallbackSort: {
1053+
type: 'alphabetical',
1054+
sortBy: 'value',
1055+
},
1056+
elementValuePattern: '^foo',
1057+
type: 'line-length',
1058+
groupName: 'foo',
1059+
},
1060+
],
1061+
type: 'alphabetical',
1062+
groups: ['foo'],
1063+
order: 'asc',
1064+
},
1065+
],
1066+
errors: [
1067+
{
1068+
data: {
1069+
right: 'b',
1070+
left: 'a',
1071+
},
1072+
messageId: 'unexpectedObjectTypesOrder',
1073+
},
1074+
],
1075+
output: dedent`
1076+
type Type = {
1077+
b: fooBar
1078+
a: fooZar
1079+
}
1080+
`,
1081+
code: dedent`
1082+
type Type = {
1083+
a: fooZar
1084+
b: fooBar
1085+
}
1086+
`,
1087+
},
10471088
],
10481089
valid: [],
10491090
},
@@ -4328,6 +4369,40 @@ describe(ruleName, () => {
43284369
}
43294370
`,
43304371
},
4372+
{
4373+
errors: [
4374+
{
4375+
data: {
4376+
right: 'bb',
4377+
left: 'c',
4378+
},
4379+
messageId: 'unexpectedObjectTypesOrder',
4380+
},
4381+
],
4382+
options: [
4383+
{
4384+
...options,
4385+
fallbackSort: {
4386+
type: 'alphabetical',
4387+
sortBy: 'value',
4388+
},
4389+
},
4390+
],
4391+
output: dedent`
4392+
type Type = {
4393+
bb: string;
4394+
c: boolean;
4395+
a: number;
4396+
}
4397+
`,
4398+
code: dedent`
4399+
type Type = {
4400+
c: boolean;
4401+
bb: string;
4402+
a: number;
4403+
}
4404+
`,
4405+
},
43314406
],
43324407
valid: [],
43334408
},

0 commit comments

Comments
 (0)