Skip to content

Commit

Permalink
feat: allow separating object properties into logical parts
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Jun 16, 2023
1 parent 8703209 commit 933b621
Show file tree
Hide file tree
Showing 8 changed files with 532 additions and 18 deletions.
15 changes: 14 additions & 1 deletion docs/rules/sort-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ interface Options {
order?: 'asc' | 'desc'
'ignore-case'?: boolean
'always-on-top'?: string[]
'partition-by-comment': string[] | string | boolean
}
```

Expand Down Expand Up @@ -114,6 +115,14 @@ Only affects alphabetical and natural sorting. When `true` the rule ignores the

You can set a list of key names that will always go at the beginning of the object. For example: `['id', 'name']`

### partition-by-comment

<sub>(default: `false`)</sub>

You can set comments that would separate the properties of objects into logical parts. If set to `true`, all object property comments will be treated as delimiters.

The [minimatch](https://github.com/isaacs/minimatch) library is used for pattern matching.

## ⚙️ Usage

::: code-group
Expand All @@ -127,7 +136,9 @@ You can set a list of key names that will always go at the beginning of the obje
"error",
{
"type": "natural",
"order": "asc"
"order": "asc",
"always-on-top": ["id", "name"],
"partition-by-comment": "Part:**"
}
]
}
Expand All @@ -149,6 +160,8 @@ export default [
{
type: 'natural',
order: 'asc',
'always-on-top': ['id', 'name'],
'partition-by-comment': 'Part:**',
},
],
},
Expand Down
15 changes: 8 additions & 7 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,25 @@ let createConfigWithOptions = (options: {
callback: 'ignore',
},
],
[sortArrayIncludesName]: [
[sortObjectsName]: [
'error',
{
'spread-last': true,
'partition-by-comment': false,
'always-on-top': [],
},
],
[sortObjectsName]: [
[sortArrayIncludesName]: [
'error',
{
'always-on-top': [],
'spread-last': true,
},
],
[sortNamedImportsName]: ['error'],
[sortNamedExportsName]: ['error'],
[sortObjectTypesName]: ['error'],
[sortNamedImportsName]: ['error'],
[sortMapElementsName]: ['error'],
[sortUnionTypesName]: ['error'],
[sortObjectTypesName]: ['error'],
[sortInterfacesName]: ['error'],
[sortUnionTypesName]: ['error'],
[sortExportsName]: ['error'],
[sortEnumsName]: ['error'],
}
Expand Down
33 changes: 28 additions & 5 deletions rules/sort-objects.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import type { TSESLint } from '@typescript-eslint/utils'
import type { TSESTree } from '@typescript-eslint/types'
import type { TSESLint } from '@typescript-eslint/utils'

import { AST_NODE_TYPES } from '@typescript-eslint/types'

import type { SortingNode } from '../typings'
import type { PartitionComment, SortingNode } from '../typings'

import { isPartitionComment } from '../utils/is-partition-comment'
import { getCommentBefore } from '../utils/get-comment-before'
import { createEslintRule } from '../utils/create-eslint-rule'
import { toSingleLine } from '../utils/to-single-line'
import { rangeToDiff } from '../utils/range-to-diff'
import { SortOrder, SortType } from '../typings'
import { sortNodes } from '../utils/sort-nodes'
import { makeFixes } from '../utils/make-fixes'
import { pairwise } from '../utils/pairwise'
import { sortNodes } from '../utils/sort-nodes'
import { complete } from '../utils/complete'
import { pairwise } from '../utils/pairwise'
import { groupBy } from '../utils/group-by'
import { compare } from '../utils/compare'

Expand All @@ -29,6 +31,7 @@ type SortingNodeWithPosition = SortingNode & {

type Options = [
Partial<{
'partition-by-comment': PartitionComment
'always-on-top': string[]
'ignore-case': boolean
order: SortOrder
Expand All @@ -51,6 +54,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
{
type: 'object',
properties: {
'partition-by-comment': {
type: ['boolean', 'string', 'array'],
default: false,
},
type: {
enum: [
SortType.alphabetical,
Expand Down Expand Up @@ -91,6 +98,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
) => {
if (node.properties.length > 1) {
let options = complete(context.options.at(0), {
'partition-by-comment': false,
type: SortType.alphabetical,
'ignore-case': false,
order: SortOrder.asc,
Expand All @@ -116,6 +124,19 @@ export default createEslintRule<Options, MESSAGE_ID>({
return accumulator
}

let comment = getCommentBefore(prop, source)

if (
options['partition-by-comment'] &&
comment &&
isPartitionComment(
options['partition-by-comment'],
comment.value,
)
) {
accumulator.push([])
}

let name: string
let position: Position = Position.ignore
let dependencies: string[] = []
Expand Down Expand Up @@ -230,7 +251,9 @@ export default createEslintRule<Options, MESSAGE_ID>({
sortNodes(getGroup(Position.ignore), options),
].flat()

return makeFixes(fixer, nodes, sortedNodes, source)
return makeFixes(fixer, nodes, sortedNodes, source, {
partitionComment: options['partition-by-comment'],
})
}

context.report({
Expand Down
Loading

0 comments on commit 933b621

Please sign in to comment.