Skip to content

Commit

Permalink
feat: support sorting by type in fallback sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
hugop95 authored Feb 28, 2025
1 parent f42f24f commit 79d0441
Show file tree
Hide file tree
Showing 17 changed files with 568 additions and 55 deletions.
5 changes: 3 additions & 2 deletions docs/content/rules/sort-interfaces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ Determines whether the sorted items should be in ascending or descending order.
{
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
order?: 'asc' | 'desc'
sortBy?: 'name' | 'value'
}
```
</sub>
Expand Down Expand Up @@ -560,7 +561,7 @@ interface CustomGroupDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
sortBy?: 'name' | 'value'
newlinesInside?: 'always' | 'never'
selector?: string
Expand All @@ -579,7 +580,7 @@ interface CustomGroupAnyOfDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
sortBy?: 'name' | 'value'
newlinesInside?: 'always' | 'never'
anyOf: Array<{
Expand Down
5 changes: 3 additions & 2 deletions docs/content/rules/sort-object-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Determines whether the sorted items should be in ascending or descending order.
{
type: 'alphabetical' | 'natural' | 'line-length' | 'custom' | 'unsorted'
order?: 'asc' | 'desc'
sortBy?: 'name' | 'value'
}
```
</sub>
Expand Down Expand Up @@ -507,7 +508,7 @@ interface CustomGroupDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
sortBy?: 'name' | 'value'
newlinesInside?: 'always' | 'never'
selector?: string
Expand All @@ -526,7 +527,7 @@ interface CustomGroupAnyOfDefinition {
groupName: string
type?: 'alphabetical' | 'natural' | 'line-length' | 'unsorted'
order?: 'asc' | 'desc'
fallbackSort?: { type: string; order?: 'asc' | 'desc' }
fallbackSort?: { type: string; order?: 'asc' | 'desc'; sortBy?: 'name' | 'value' }
sortBy?: 'name' | 'value'
newlinesInside?: 'always' | 'never'
anyOf: Array<{
Expand Down
23 changes: 17 additions & 6 deletions rules/sort-object-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
partitionByNewLineJsonSchema,
newlinesBetweenJsonSchema,
customGroupsJsonSchema,
commonJsonSchemas,
buildCommonJsonSchemas,
groupsJsonSchema,
regexJsonSchema,
} from '../utils/common-json-schemas'
Expand Down Expand Up @@ -68,7 +68,7 @@ type MESSAGE_ID =
| 'unexpectedObjectTypesOrder'

let defaultOptions: Required<Options[0]> = {
fallbackSort: { type: 'unsorted' },
fallbackSort: { type: 'unsorted', sortBy: 'name' },
partitionByComment: false,
partitionByNewLine: false,
newlinesBetween: 'ignore',
Expand All @@ -89,11 +89,18 @@ let defaultOptions: Required<Options[0]> = {
export let jsonSchema: JSONSchema4 = {
items: {
properties: {
...commonJsonSchemas,
...buildCommonJsonSchemas({
additionalFallbackSortProperties: {
sortBy: sortByJsonSchema,
},
}),
customGroups: {
oneOf: [
customGroupsJsonSchema,
buildCustomGroupsArrayJsonSchema({ singleCustomGroupJsonSchema }),
buildCustomGroupsArrayJsonSchema({
additionalFallbackSortProperties: { sortBy: sortByJsonSchema },
singleCustomGroupJsonSchema,
}),
],
},
useConfigurationIf: buildUseConfigurationIfJsonSchema({
Expand Down Expand Up @@ -363,13 +370,17 @@ export let sortObjectTypeElements = <MessageIds extends string>({
filteredGroupKindNodes.flatMap(groupedNodes =>
sortNodesByGroups({
getOptionsByGroupNumber: groupNumber => {
let { options: overriddenOptions, nodeValueGetter } =
getCustomGroupsCompareOptions(options, groupNumber)
let {
fallbackSortNodeValueGetter,
options: overriddenOptions,
nodeValueGetter,
} = getCustomGroupsCompareOptions(options, groupNumber)
return {
options: {
...options,
...overriddenOptions,
},
fallbackSortNodeValueGetter,
nodeValueGetter,
}
},
Expand Down
18 changes: 15 additions & 3 deletions rules/sort-object-types/get-custom-groups-compare-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,43 @@ export let getCustomGroupsCompareOptions = (
Required<Options[0]>,
'fallbackSort' | 'sortBy' | 'order' | 'type'
>
fallbackSortNodeValueGetter?: NodeValueGetterFunction<SortObjectTypesSortingNode> | null
nodeValueGetter?: NodeValueGetterFunction<SortObjectTypesSortingNode> | null
} => {
let baseCompareOptions = baseGetCustomGroupsCompareOptions(
options,
groupNumber,
)

let { customGroups, sortBy, groups } = options
let { fallbackSort, customGroups, sortBy, groups } = options
let fallbackSortBy = fallbackSort.sortBy
if (Array.isArray(customGroups)) {
let group = groups[groupNumber]
let customGroup =
typeof group === 'string'
? customGroups.find(currentGroup => group === currentGroup.groupName)
: null

if (customGroup && 'sortBy' in customGroup && customGroup.sortBy) {
;({ sortBy } = customGroup)
if (customGroup) {
fallbackSortBy = customGroup.fallbackSort?.sortBy ?? fallbackSortBy
if ('sortBy' in customGroup && customGroup.sortBy) {
;({ sortBy } = customGroup)
}
}
}

return {
options: {
...baseCompareOptions,
fallbackSort: {
...baseCompareOptions.fallbackSort,
sortBy: fallbackSortBy,
},
sortBy,
},
fallbackSortNodeValueGetter: fallbackSortBy
? buildNodeValueGetter(fallbackSortBy)
: null,
nodeValueGetter: buildNodeValueGetter(sortBy),
}
}
15 changes: 11 additions & 4 deletions rules/sort-object-types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
PartitionByCommentOption,
NewlinesBetweenOption,
CustomGroupsOption,
FallbackSortOption,
CommonOptions,
GroupsOptions,
RegexOption,
Expand All @@ -21,13 +22,19 @@ import {

export type Options = Partial<
{
customGroups:
| CustomGroupsOption<
SingleCustomGroup,
{
fallbackSort?: { sortBy?: 'value' | 'name' } & FallbackSortOption
}
>
| DeprecatedCustomGroupsOption
useConfigurationIf: {
declarationMatchesPattern?: RegexOption
allNamesMatchPattern?: RegexOption
}
customGroups:
| CustomGroupsOption<SingleCustomGroup>
| DeprecatedCustomGroupsOption
fallbackSort: { sortBy?: 'value' | 'name' } & FallbackSortOption
/**
* @deprecated for {@link `groups`}
*/
Expand All @@ -41,7 +48,7 @@ export type Options = Partial<
*/
ignorePattern: RegexOption
sortBy: 'value' | 'name'
} & CommonOptions
} & Omit<CommonOptions, 'fallbackSort'>
>[]

export type SingleCustomGroup = (
Expand Down
75 changes: 75 additions & 0 deletions test/rules/sort-interfaces.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,47 @@ describe(ruleName, () => {
}
`,
},
{
options: [
{
customGroups: [
{
fallbackSort: {
type: 'alphabetical',
sortBy: 'value',
},
elementValuePattern: '^foo',
type: 'line-length',
groupName: 'foo',
},
],
type: 'alphabetical',
groups: ['foo'],
order: 'asc',
},
],
errors: [
{
data: {
right: 'b',
left: 'a',
},
messageId: 'unexpectedInterfacePropertiesOrder',
},
],
output: dedent`
interface Interface {
b: fooBar
a: fooZar
}
`,
code: dedent`
interface Interface {
a: fooZar
b: fooBar
}
`,
},
],
valid: [],
},
Expand Down Expand Up @@ -5048,6 +5089,40 @@ describe(ruleName, () => {
}
`,
},
{
errors: [
{
data: {
right: 'bb',
left: 'c',
},
messageId: 'unexpectedInterfacePropertiesOrder',
},
],
options: [
{
...options,
fallbackSort: {
type: 'alphabetical',
sortBy: 'value',
},
},
],
output: dedent`
interface Interface {
bb: string;
c: boolean;
a: number;
}
`,
code: dedent`
interface Interface {
c: boolean;
bb: string;
a: number;
}
`,
},
],
valid: [],
},
Expand Down
75 changes: 75 additions & 0 deletions test/rules/sort-object-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,47 @@ describe(ruleName, () => {
}
`,
},
{
options: [
{
customGroups: [
{
fallbackSort: {
type: 'alphabetical',
sortBy: 'value',
},
elementValuePattern: '^foo',
type: 'line-length',
groupName: 'foo',
},
],
type: 'alphabetical',
groups: ['foo'],
order: 'asc',
},
],
errors: [
{
data: {
right: 'b',
left: 'a',
},
messageId: 'unexpectedObjectTypesOrder',
},
],
output: dedent`
type Type = {
b: fooBar
a: fooZar
}
`,
code: dedent`
type Type = {
a: fooZar
b: fooBar
}
`,
},
],
valid: [],
},
Expand Down Expand Up @@ -4328,6 +4369,40 @@ describe(ruleName, () => {
}
`,
},
{
errors: [
{
data: {
right: 'bb',
left: 'c',
},
messageId: 'unexpectedObjectTypesOrder',
},
],
options: [
{
...options,
fallbackSort: {
type: 'alphabetical',
sortBy: 'value',
},
},
],
output: dedent`
type Type = {
bb: string;
c: boolean;
a: number;
}
`,
code: dedent`
type Type = {
c: boolean;
bb: string;
a: number;
}
`,
},
],
valid: [],
},
Expand Down
Loading

0 comments on commit 79d0441

Please sign in to comment.