Skip to content

Commit

Permalink
feat(sort-objects): add object declarations and destructured objects …
Browse files Browse the repository at this point in the history
…options
  • Loading branch information
hugop95 authored Nov 24, 2024
1 parent ccb8baf commit 5606fad
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 22 deletions.
22 changes: 20 additions & 2 deletions docs/content/rules/sort-objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,29 @@ Allows you to specify names or patterns for object types that should be ignored

You can specify their names or a regexp pattern to ignore, for example: `'^User.+'` to ignore all object types whose names begin with the word “User”.

### destructureOnly
### [DEPRECATED] destructureOnly

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

Allows you to sort only objects that are part of a destructuring pattern. When set to `true`, the rule will apply sorting exclusively to destructured objects, leaving other object declarations unchanged.
Use the [objectDeclarations](#objectdeclarations) and [destructuredObjects](#destructuredobjects) options instead.

Allows you to only sort objects that are part of a destructuring pattern. When set to `true`, the rule will apply sorting exclusively to destructured objects, leaving other object declarations unchanged.

### objectDeclarations

<sub>default: `true`</sub>

Allows you to choose whether to sort standard object declarations.

### destructuredObjects

<sub>
type: `boolean | { groups: boolean }`
</sub>
<sub>default: `true`</sub>

Allows you to choose whether to sort destructured objects.
The `groups` attribute allows you to specify whether to use groups to sort destructured objects.

### groups

Expand Down
79 changes: 60 additions & 19 deletions rules/sort-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ import { getSettings } from '../utils/get-settings'
import { isSortable } from '../utils/is-sortable'
import { useGroups } from '../utils/use-groups'
import { makeFixes } from '../utils/make-fixes'
import { sortNodes } from '../utils/sort-nodes'
import { complete } from '../utils/complete'
import { pairwise } from '../utils/pairwise'
import { matches } from '../utils/matches'

type Options = [
Partial<{
destructuredObjects: { groups: boolean } | boolean
type: 'alphabetical' | 'line-length' | 'natural'
customGroups: Record<string, string[] | string>
partitionByComment: string[] | boolean | string
Expand All @@ -51,7 +53,11 @@ type Options = [
locales: NonNullable<Intl.LocalesArgument>
groups: (Group[] | Group)[]
partitionByNewLine: boolean
objectDeclarations: boolean
styledComponents: boolean
/**
* @deprecated for {@link `destructuredObjects`} and {@link `objectDeclarations`}
*/
destructureOnly: boolean
ignorePattern: string[]
order: 'desc' | 'asc'
Expand All @@ -73,6 +79,8 @@ let defaultOptions: Required<Options[0]> = {
partitionByComment: false,
newlinesBetween: 'ignore',
specialCharacters: 'keep',
destructuredObjects: true,
objectDeclarations: true,
styledComponents: true,
destructureOnly: false,
type: 'alphabetical',
Expand All @@ -87,8 +95,12 @@ let defaultOptions: Required<Options[0]> = {
export default createEslintRule<Options, MESSAGE_ID>({
create: context => {
let sortObject = (
node: TSESTree.ObjectExpression | TSESTree.ObjectPattern,
nodeObject: TSESTree.ObjectExpression | TSESTree.ObjectPattern,
): void => {
if (!isSortable(nodeObject.properties)) {
return
}

let settings = getSettings(context.settings)

let options = complete(context.options.at(0), settings, defaultOptions)
Expand All @@ -100,14 +112,17 @@ export default createEslintRule<Options, MESSAGE_ID>({
)
validateNewlinesAndPartitionConfiguration(options)

let shouldIgnore = false

if (options.destructureOnly) {
shouldIgnore = node.type !== 'ObjectPattern'
let isDestructuredObject = nodeObject.type === 'ObjectPattern'
if (isDestructuredObject) {
if (!options.destructuredObjects) {
return
}
} else if (options.destructureOnly || !options.objectDeclarations) {
return
}

if (!shouldIgnore && options.ignorePattern.length) {
let variableParent = getNodeParent(node, [
if (options.ignorePattern.length) {
let variableParent = getNodeParent(nodeObject, [
'VariableDeclarator',
'Property',
])
Expand All @@ -126,23 +141,20 @@ export default createEslintRule<Options, MESSAGE_ID>({
typeof variableIdentifier === 'string' &&
checkMatch(variableIdentifier)
) {
shouldIgnore = true
return
}

let callParent = getNodeParent(node, ['CallExpression'])
let callParent = getNodeParent(nodeObject, ['CallExpression'])
let callIdentifier =
callParent?.type === 'CallExpression' &&
callParent.callee.type === 'Identifier'
? callParent.callee.name
: null

if (callIdentifier && checkMatch(callIdentifier)) {
shouldIgnore = true
return
}
}
if (shouldIgnore || !isSortable(node.properties)) {
return
}

let isStyledCallExpression = (identifier: TSESTree.Expression): boolean =>
identifier.type === 'Identifier' && identifier.name === 'styled'
Expand All @@ -163,9 +175,9 @@ export default createEslintRule<Options, MESSAGE_ID>({
styledNode.parent.name.name === 'style'))
if (
!options.styledComponents &&
(isStyledComponents(node.parent) ||
(node.parent.type === 'ArrowFunctionExpression' &&
isStyledComponents(node.parent.parent)))
(isStyledComponents(nodeObject.parent) ||
(nodeObject.parent.type === 'ArrowFunctionExpression' &&
isStyledComponents(nodeObject.parent.parent)))
) {
return
}
Expand Down Expand Up @@ -352,14 +364,20 @@ export default createEslintRule<Options, MESSAGE_ID>({
},
[[]],
)
let formattedMembers = formatProperties(node.properties)

let formattedMembers = formatProperties(nodeObject.properties)

let nodesSortingFunction =
isDestructuredObject &&
typeof options.destructuredObjects === 'object' &&
!options.destructuredObjects.groups
? sortNodes
: sortNodesByGroups
let sortNodesIgnoringEslintDisabledNodes = (
ignoreEslintDisabledNodes: boolean,
): SortingNodeWithDependencies[] =>
sortNodesByDependencies(
formattedMembers.flatMap(nodes =>
sortNodesByGroups(nodes, options, {
nodesSortingFunction(nodes, options, {
ignoreEslintDisabledNodes,
}),
),
Expand Down Expand Up @@ -460,6 +478,25 @@ export default createEslintRule<Options, MESSAGE_ID>({
schema: [
{
properties: {
destructuredObjects: {
oneOf: [
{
type: 'boolean',
},
{
properties: {
groups: {
description:
'Controls whether to use groups to sort destructured objects.',
type: 'boolean',
},
},
additionalProperties: false,
type: 'object',
},
],
description: 'Controls whether to sort destructured objects.',
},
ignorePattern: {
description:
'Specifies names or patterns for nodes that should be ignored by rule.',
Expand All @@ -477,6 +514,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
description: 'Controls whether to sort only destructured objects.',
type: 'boolean',
},
objectDeclarations: {
description: 'Controls whether to sort object declarations.',
type: 'boolean',
},
styledComponents: {
description: 'Controls whether to sort styled components.',
type: 'boolean',
Expand Down
Loading

0 comments on commit 5606fad

Please sign in to comment.