eslint-plugin-perfectionist 5.5.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/package.json.js +1 -1
  2. package/dist/rules/sort-array-includes/compute-array-elements.d.ts +11 -0
  3. package/dist/rules/sort-array-includes/compute-array-elements.js +20 -0
  4. package/dist/rules/sort-array-includes/compute-matched-context-options.d.ts +25 -0
  5. package/dist/rules/sort-array-includes/compute-matched-context-options.js +33 -0
  6. package/dist/rules/sort-array-includes/compute-node-name.d.ts +17 -0
  7. package/dist/rules/sort-array-includes/compute-node-name.js +7 -0
  8. package/dist/rules/sort-array-includes/sort-array.d.ts +23 -0
  9. package/dist/rules/sort-array-includes/sort-array.js +131 -0
  10. package/dist/rules/sort-array-includes/types.d.ts +5 -2
  11. package/dist/rules/sort-array-includes.d.ts +5 -20
  12. package/dist/rules/sort-array-includes.js +50 -150
  13. package/dist/rules/sort-classes/compute-dependencies-by-sorting-node.d.ts +0 -7
  14. package/dist/rules/sort-classes/compute-dependencies-by-sorting-node.js +15 -18
  15. package/dist/rules/sort-classes/compute-matched-context-options.d.ts +23 -0
  16. package/dist/rules/sort-classes/compute-matched-context-options.js +39 -0
  17. package/dist/rules/sort-classes/is-known-class-element.d.ts +13 -0
  18. package/dist/rules/sort-classes/is-known-class-element.js +17 -0
  19. package/dist/rules/sort-classes/sort-class.d.ts +13 -0
  20. package/dist/rules/sort-classes/sort-class.js +313 -0
  21. package/dist/rules/sort-classes/types.d.ts +40 -16
  22. package/dist/rules/sort-classes/types.js +10 -0
  23. package/dist/rules/sort-classes.d.ts +4 -13
  24. package/dist/rules/sort-classes.js +28 -316
  25. package/dist/rules/sort-decorators.d.ts +3 -1
  26. package/dist/rules/sort-enums/compute-expression-number-value.d.ts +13 -0
  27. package/dist/rules/sort-enums/compute-expression-number-value.js +76 -0
  28. package/dist/rules/sort-enums/compute-matched-context-options.d.ts +24 -0
  29. package/dist/rules/sort-enums/compute-matched-context-options.js +31 -0
  30. package/dist/rules/sort-enums/compute-node-name.d.ts +17 -0
  31. package/dist/rules/sort-enums/compute-node-name.js +7 -0
  32. package/dist/rules/sort-enums/sort-enum.d.ts +13 -0
  33. package/dist/rules/sort-enums/sort-enum.js +174 -0
  34. package/dist/rules/sort-enums/types.d.ts +27 -0
  35. package/dist/rules/sort-enums/types.js +13 -1
  36. package/dist/rules/sort-enums.d.ts +4 -13
  37. package/dist/rules/sort-enums.js +32 -252
  38. package/dist/rules/sort-export-attributes.d.ts +7 -6
  39. package/dist/rules/sort-export-attributes.js +24 -132
  40. package/dist/rules/sort-exports.d.ts +3 -1
  41. package/dist/rules/sort-heritage-clauses/compute-matched-context-options.d.ts +24 -0
  42. package/dist/rules/sort-heritage-clauses/compute-matched-context-options.js +31 -0
  43. package/dist/rules/sort-heritage-clauses/compute-node-name.d.ts +13 -0
  44. package/dist/rules/sort-heritage-clauses/compute-node-name.js +13 -0
  45. package/dist/rules/sort-heritage-clauses/sort-heritage-clause.d.ts +13 -0
  46. package/dist/rules/sort-heritage-clauses/sort-heritage-clause.js +135 -0
  47. package/dist/rules/sort-heritage-clauses/types.d.ts +34 -2
  48. package/dist/rules/sort-heritage-clauses/types.js +10 -0
  49. package/dist/rules/sort-heritage-clauses.d.ts +4 -11
  50. package/dist/rules/sort-heritage-clauses.js +30 -139
  51. package/dist/rules/sort-import-attributes/compute-matched-context-options.d.ts +26 -0
  52. package/dist/rules/sort-import-attributes/compute-matched-context-options.js +31 -0
  53. package/dist/rules/sort-import-attributes/compute-node-name.d.ts +16 -0
  54. package/dist/rules/sort-import-attributes/compute-node-name.js +15 -0
  55. package/dist/rules/sort-import-attributes/sort-import-or-export-attributes.d.ts +23 -0
  56. package/dist/rules/sort-import-attributes/sort-import-or-export-attributes.js +109 -0
  57. package/dist/rules/sort-import-attributes/types.d.ts +22 -2
  58. package/dist/rules/sort-import-attributes.d.ts +7 -4
  59. package/dist/rules/sort-import-attributes.js +48 -128
  60. package/dist/rules/sort-imports.d.ts +3 -1
  61. package/dist/rules/sort-interfaces.d.ts +3 -1
  62. package/dist/rules/sort-interfaces.js +24 -19
  63. package/dist/rules/sort-intersection-types.d.ts +3 -1
  64. package/dist/rules/sort-intersection-types.js +28 -16
  65. package/dist/rules/sort-jsx-props/compute-matched-context-options.d.ts +24 -0
  66. package/dist/rules/sort-jsx-props/compute-matched-context-options.js +64 -0
  67. package/dist/rules/sort-jsx-props/compute-node-name.d.ts +8 -0
  68. package/dist/rules/sort-jsx-props/compute-node-name.js +14 -0
  69. package/dist/rules/sort-jsx-props/sort-jsx-object.d.ts +13 -0
  70. package/dist/rules/sort-jsx-props/sort-jsx-object.js +164 -0
  71. package/dist/rules/sort-jsx-props/types.d.ts +15 -0
  72. package/dist/rules/sort-jsx-props/types.js +8 -0
  73. package/dist/rules/sort-jsx-props.d.ts +6 -14
  74. package/dist/rules/sort-jsx-props.js +20 -189
  75. package/dist/rules/sort-maps/compute-matched-context-options.d.ts +23 -0
  76. package/dist/rules/sort-maps/compute-matched-context-options.js +37 -0
  77. package/dist/rules/sort-maps/compute-node-name.d.ts +21 -0
  78. package/dist/rules/sort-maps/compute-node-name.js +14 -0
  79. package/dist/rules/sort-maps/sort-potential-map.d.ts +13 -0
  80. package/dist/rules/sort-maps/sort-potential-map.js +153 -0
  81. package/dist/rules/sort-maps/types.d.ts +16 -0
  82. package/dist/rules/sort-maps/types.js +10 -0
  83. package/dist/rules/sort-maps.d.ts +6 -14
  84. package/dist/rules/sort-maps.js +27 -178
  85. package/dist/rules/sort-modules.d.ts +3 -1
  86. package/dist/rules/sort-named-exports/compute-export-kind-modifier.d.ts +4 -0
  87. package/dist/rules/sort-named-exports/compute-export-kind-modifier.js +15 -0
  88. package/dist/rules/sort-named-exports/compute-matched-context-options.d.ts +25 -0
  89. package/dist/rules/sort-named-exports/compute-matched-context-options.js +27 -0
  90. package/dist/rules/sort-named-exports/sort-named-export.d.ts +13 -0
  91. package/dist/rules/sort-named-exports/sort-named-export.js +140 -0
  92. package/dist/rules/sort-named-exports/types.d.ts +25 -1
  93. package/dist/rules/sort-named-exports/types.js +8 -0
  94. package/dist/rules/sort-named-exports.d.ts +4 -11
  95. package/dist/rules/sort-named-exports.js +29 -153
  96. package/dist/rules/sort-named-imports/compute-import-kind-modifier.d.ts +4 -0
  97. package/dist/rules/sort-named-imports/compute-import-kind-modifier.js +15 -0
  98. package/dist/rules/sort-named-imports/compute-matched-context-options.d.ts +25 -0
  99. package/dist/rules/sort-named-imports/compute-matched-context-options.js +28 -0
  100. package/dist/rules/sort-named-imports/sort-named-import.d.ts +13 -0
  101. package/dist/rules/sort-named-imports/sort-named-import.js +144 -0
  102. package/dist/rules/sort-named-imports/types.d.ts +25 -1
  103. package/dist/rules/sort-named-imports/types.js +8 -0
  104. package/dist/rules/sort-named-imports.d.ts +4 -11
  105. package/dist/rules/sort-named-imports.js +28 -156
  106. package/dist/rules/sort-object-types/compute-matched-context-options.d.ts +2 -0
  107. package/dist/rules/sort-object-types/compute-matched-context-options.js +43 -33
  108. package/dist/rules/sort-object-types/sort-object-type-elements.d.ts +21 -0
  109. package/dist/rules/sort-object-types/sort-object-type-elements.js +176 -0
  110. package/dist/rules/sort-object-types/types.d.ts +5 -0
  111. package/dist/rules/sort-object-types.d.ts +4 -20
  112. package/dist/rules/sort-object-types.js +26 -192
  113. package/dist/rules/sort-objects/compute-dependency-names.d.ts +2 -0
  114. package/dist/rules/sort-objects/compute-dependency-names.js +38 -0
  115. package/dist/rules/sort-objects/compute-matched-context-options.d.ts +4 -0
  116. package/dist/rules/sort-objects/compute-matched-context-options.js +25 -14
  117. package/dist/rules/sort-objects/compute-node-value.d.ts +11 -0
  118. package/dist/rules/sort-objects/compute-node-value.js +19 -0
  119. package/dist/rules/sort-objects/passes-declaration-comment-matches-filter.js +10 -2
  120. package/dist/rules/sort-objects/sort-object.d.ts +13 -0
  121. package/dist/rules/sort-objects/sort-object.js +219 -0
  122. package/dist/rules/sort-objects/types.d.ts +9 -0
  123. package/dist/rules/sort-objects.d.ts +5 -4
  124. package/dist/rules/sort-objects.js +18 -261
  125. package/dist/rules/sort-sets.d.ts +3 -1
  126. package/dist/rules/sort-sets.js +43 -29
  127. package/dist/rules/sort-switch-case.d.ts +3 -1
  128. package/dist/rules/sort-union-types/compute-matched-context-options.d.ts +25 -0
  129. package/dist/rules/sort-union-types/compute-matched-context-options.js +31 -0
  130. package/dist/rules/sort-union-types/compute-node-name.d.ts +21 -0
  131. package/dist/rules/sort-union-types/compute-node-name.js +12 -0
  132. package/dist/rules/sort-union-types/sort-union-or-intersection-types.d.ts +27 -0
  133. package/dist/rules/sort-union-types/sort-union-or-intersection-types.js +181 -0
  134. package/dist/rules/sort-union-types/types.d.ts +22 -2
  135. package/dist/rules/sort-union-types.d.ts +3 -21
  136. package/dist/rules/sort-union-types.js +35 -184
  137. package/dist/rules/sort-variable-declarations/compute-matched-context-options.d.ts +29 -0
  138. package/dist/rules/sort-variable-declarations/compute-matched-context-options.js +32 -0
  139. package/dist/rules/sort-variable-declarations/sort-variable-declaration.d.ts +13 -0
  140. package/dist/rules/sort-variable-declarations/sort-variable-declaration.js +171 -0
  141. package/dist/rules/sort-variable-declarations/types.d.ts +30 -1
  142. package/dist/rules/sort-variable-declarations/types.js +16 -1
  143. package/dist/rules/sort-variable-declarations.d.ts +4 -16
  144. package/dist/rules/sort-variable-declarations.js +35 -174
  145. package/dist/utils/build-ast-listeners.d.ts +46 -0
  146. package/dist/utils/build-ast-listeners.js +57 -0
  147. package/dist/utils/compute-group.d.ts +2 -4
  148. package/dist/utils/context-matching/passes-all-names-match-pattern-filter.d.ts +18 -0
  149. package/dist/utils/context-matching/passes-all-names-match-pattern-filter.js +8 -0
  150. package/dist/utils/context-matching/passes-ast-selector-filter.d.ts +17 -0
  151. package/dist/utils/context-matching/passes-ast-selector-filter.js +7 -0
  152. package/dist/utils/create-eslint-rule.d.ts +16 -18
  153. package/dist/utils/does-custom-group-match.d.ts +1 -1
  154. package/dist/utils/get-eslint-disabled-rules.d.ts +1 -1
  155. package/dist/utils/get-settings.d.ts +1 -1
  156. package/dist/utils/get-settings.js +1 -1
  157. package/dist/utils/json-schemas/common-json-schemas.d.ts +1 -0
  158. package/dist/utils/json-schemas/common-json-schemas.js +6 -0
  159. package/dist/utils/report-all-errors.d.ts +0 -3
  160. package/package.json +3 -3
  161. package/dist/rules/sort-export-attributes/types.d.ts +0 -15
  162. package/dist/utils/filter-options-by-all-names-match.d.ts +0 -92
  163. package/dist/utils/filter-options-by-all-names-match.js +0 -11
@@ -1,3 +1,3 @@
1
1
  const name = 'eslint-plugin-perfectionist'
2
- const version = '5.5.0'
2
+ const version = '5.7.0'
3
3
  export { name, version }
@@ -0,0 +1,11 @@
1
+ import { TSESTree } from '@typescript-eslint/types'
2
+ /**
3
+ * Computes array elements for the given expression.
4
+ *
5
+ * @param expression - The expression to compute array elements from.
6
+ * @returns An array of elements if the expression is an array or a new
7
+ * expression, otherwise null.
8
+ */
9
+ export declare function computeArrayElements(
10
+ expression: TSESTree.ArrayExpression | TSESTree.NewExpression,
11
+ ): (TSESTree.SpreadElement | TSESTree.Expression | null)[] | null
@@ -0,0 +1,20 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2
+ import { UnreachableCaseError } from '../../utils/unreachable-case-error.js'
3
+ function computeArrayElements(expression) {
4
+ switch (expression.type) {
5
+ case AST_NODE_TYPES.ArrayExpression:
6
+ return expression.elements
7
+ case AST_NODE_TYPES.NewExpression:
8
+ if (expression.callee.type !== AST_NODE_TYPES.Identifier) {
9
+ return null
10
+ }
11
+ if (expression.callee.name !== 'Array') {
12
+ return null
13
+ }
14
+ return expression.arguments
15
+ /* v8 ignore next 2 -- @preserve Exhaustive guard. */
16
+ default:
17
+ throw new UnreachableCaseError(expression)
18
+ }
19
+ }
20
+ export { computeArrayElements }
@@ -0,0 +1,25 @@
1
+ import { RuleContext } from '@typescript-eslint/utils/ts-eslint'
2
+ import { TSESTree } from '@typescript-eslint/types'
3
+ import { Options } from './types.js'
4
+ /**
5
+ * Computes the matched context options for a given array node.
6
+ *
7
+ * @param params - Parameters.
8
+ * @param params.matchedAstSelectors - The matched AST selectors for an array
9
+ * node.
10
+ * @param params.elements - The array elements to compute the context options
11
+ * for.
12
+ * @param params.context - The rule context.
13
+ * @returns The matched context options or undefined if none match.
14
+ */
15
+ export declare function computeMatchedContextOptions<
16
+ MessageIds extends string,
17
+ >({
18
+ matchedAstSelectors,
19
+ elements,
20
+ context,
21
+ }: {
22
+ elements: (TSESTree.SpreadElement | TSESTree.Expression | null)[]
23
+ context: Readonly<RuleContext<MessageIds, Options>>
24
+ matchedAstSelectors: ReadonlySet<string>
25
+ }): Options[number] | undefined
@@ -0,0 +1,33 @@
1
+ import { passesAllNamesMatchPatternFilter } from '../../utils/context-matching/passes-all-names-match-pattern-filter.js'
2
+ import { passesAstSelectorFilter } from '../../utils/context-matching/passes-ast-selector-filter.js'
3
+ import { computeNodeName } from './compute-node-name.js'
4
+ function computeMatchedContextOptions({
5
+ matchedAstSelectors,
6
+ elements,
7
+ context,
8
+ }) {
9
+ let nodeNames = elements
10
+ .filter(element => element !== null)
11
+ .map(element =>
12
+ computeNodeName({ sourceCode: context.sourceCode, node: element }),
13
+ )
14
+ return context.options.find(options =>
15
+ isContextOptionMatching({ matchedAstSelectors, nodeNames, options }),
16
+ )
17
+ }
18
+ function isContextOptionMatching({ matchedAstSelectors, nodeNames, options }) {
19
+ if (!options.useConfigurationIf) {
20
+ return true
21
+ }
22
+ return (
23
+ passesAllNamesMatchPatternFilter({
24
+ allNamesMatchPattern: options.useConfigurationIf.allNamesMatchPattern,
25
+ nodeNames,
26
+ }) &&
27
+ passesAstSelectorFilter({
28
+ matchesAstSelector: options.useConfigurationIf.matchesAstSelector,
29
+ matchedAstSelectors,
30
+ })
31
+ )
32
+ }
33
+ export { computeMatchedContextOptions }
@@ -0,0 +1,17 @@
1
+ import { TSESTree } from '@typescript-eslint/types'
2
+ import { TSESLint } from '@typescript-eslint/utils'
3
+ /**
4
+ * Computes the name of an array member.
5
+ *
6
+ * @param props - The parameters object.
7
+ * @param props.sourceCode - ESLint source code object for text extraction.
8
+ * @param props.node - The AST node representing an array member.
9
+ * @returns The name of the array member.
10
+ */
11
+ export declare function computeNodeName({
12
+ sourceCode,
13
+ node,
14
+ }: {
15
+ node: TSESTree.SpreadElement | TSESTree.Expression
16
+ sourceCode: TSESLint.SourceCode
17
+ }): string
@@ -0,0 +1,7 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2
+ function computeNodeName({ sourceCode, node }) {
3
+ return node.type === AST_NODE_TYPES.Literal ?
4
+ `${node.value}`
5
+ : sourceCode.getText(node)
6
+ }
7
+ export { computeNodeName }
@@ -0,0 +1,23 @@
1
+ import { RuleContext } from '@typescript-eslint/utils/ts-eslint'
2
+ import { TSESTree } from '@typescript-eslint/types'
3
+ import { Options } from './types.js'
4
+ export declare function sortArray<MessageIds extends string>({
5
+ cachedGroupsByModifiersAndSelectors,
6
+ availableMessageIds,
7
+ matchedAstSelectors,
8
+ defaultOptions,
9
+ context,
10
+ node,
11
+ }: {
12
+ availableMessageIds: {
13
+ missedSpacingBetweenMembers: MessageIds
14
+ extraSpacingBetweenMembers: MessageIds
15
+ unexpectedGroupOrder: MessageIds
16
+ unexpectedOrder: MessageIds
17
+ }
18
+ cachedGroupsByModifiersAndSelectors: Map<string, string[]>
19
+ node: TSESTree.ArrayExpression | TSESTree.NewExpression
20
+ context: Readonly<RuleContext<MessageIds, Options>>
21
+ defaultOptions: Required<Options[number]>
22
+ matchedAstSelectors: ReadonlySet<string>
23
+ }): void
@@ -0,0 +1,131 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2
+ import { validateNewlinesAndPartitionConfiguration } from '../../utils/validate-newlines-and-partition-configuration.js'
3
+ import { defaultComparatorByOptionsComputer } from '../../utils/compare/default-comparator-by-options-computer.js'
4
+ import { buildOptionsByGroupIndexComputer } from '../../utils/build-options-by-group-index-computer.js'
5
+ import { validateCustomSortConfiguration } from '../../utils/validate-custom-sort-configuration.js'
6
+ import { validateGroupsConfiguration } from '../../utils/validate-groups-configuration.js'
7
+ import { generatePredefinedGroups } from '../../utils/generate-predefined-groups.js'
8
+ import { computeMatchedContextOptions } from './compute-matched-context-options.js'
9
+ import { getEslintDisabledLines } from '../../utils/get-eslint-disabled-lines.js'
10
+ import { doesCustomGroupMatch } from '../../utils/does-custom-group-match.js'
11
+ import { isNodeEslintDisabled } from '../../utils/is-node-eslint-disabled.js'
12
+ import { sortNodesByGroups } from '../../utils/sort-nodes-by-groups.js'
13
+ import { computeArrayElements } from './compute-array-elements.js'
14
+ import { reportAllErrors } from '../../utils/report-all-errors.js'
15
+ import { shouldPartition } from '../../utils/should-partition.js'
16
+ import { computeGroup } from '../../utils/compute-group.js'
17
+ import { rangeToDiff } from '../../utils/range-to-diff.js'
18
+ import { getSettings } from '../../utils/get-settings.js'
19
+ import { computeNodeName } from './compute-node-name.js'
20
+ import { isSortable } from '../../utils/is-sortable.js'
21
+ import { complete } from '../../utils/complete.js'
22
+ import { allSelectors } from './types.js'
23
+ function sortArray({
24
+ cachedGroupsByModifiersAndSelectors,
25
+ availableMessageIds,
26
+ matchedAstSelectors,
27
+ defaultOptions,
28
+ context,
29
+ node,
30
+ }) {
31
+ let elements = computeArrayElements(node)
32
+ if (!elements) {
33
+ return
34
+ }
35
+ if (!isSortable(elements)) {
36
+ return
37
+ }
38
+ let { sourceCode, id } = context
39
+ let settings = getSettings(context.settings)
40
+ let matchedContextOptions = computeMatchedContextOptions({
41
+ matchedAstSelectors,
42
+ elements,
43
+ context,
44
+ })
45
+ let options = complete(matchedContextOptions, settings, defaultOptions)
46
+ validateCustomSortConfiguration(options)
47
+ validateGroupsConfiguration({
48
+ selectors: allSelectors,
49
+ modifiers: [],
50
+ options,
51
+ })
52
+ validateNewlinesAndPartitionConfiguration(options)
53
+ let eslintDisabledLines = getEslintDisabledLines({
54
+ ruleName: id,
55
+ sourceCode,
56
+ })
57
+ let optionsByGroupIndexComputer = buildOptionsByGroupIndexComputer(options)
58
+ let formattedMembers = elements.reduce(
59
+ (accumulator, element) => {
60
+ if (element === null) {
61
+ return accumulator
62
+ }
63
+ if (element.type === AST_NODE_TYPES.SpreadElement) {
64
+ accumulator.push([])
65
+ return accumulator
66
+ }
67
+ let name = computeNodeName({ node: element, sourceCode })
68
+ let selector = 'literal'
69
+ let predefinedGroups = generatePredefinedGroups({
70
+ cache: cachedGroupsByModifiersAndSelectors,
71
+ selectors: [selector],
72
+ modifiers: [],
73
+ })
74
+ let group = computeGroup({
75
+ customGroupMatcher: customGroup =>
76
+ doesCustomGroupMatch({
77
+ selectors: [selector],
78
+ elementName: name,
79
+ modifiers: [],
80
+ customGroup,
81
+ }),
82
+ predefinedGroups,
83
+ options,
84
+ })
85
+ let sortingNode = {
86
+ isEslintDisabled: isNodeEslintDisabled(element, eslintDisabledLines),
87
+ size: rangeToDiff(element, sourceCode),
88
+ node: element,
89
+ group,
90
+ name,
91
+ }
92
+ let lastSortingNode = accumulator.at(-1)?.at(-1)
93
+ if (
94
+ shouldPartition({
95
+ lastSortingNode,
96
+ sortingNode,
97
+ sourceCode,
98
+ options,
99
+ })
100
+ ) {
101
+ accumulator.push([])
102
+ }
103
+ accumulator.at(-1).push({
104
+ ...sortingNode,
105
+ partitionId: accumulator.length,
106
+ })
107
+ return accumulator
108
+ },
109
+ [[]],
110
+ )
111
+ function sortNodesExcludingEslintDisabled(ignoreEslintDisabledNodes) {
112
+ return formattedMembers.flatMap(nodes2 =>
113
+ sortNodesByGroups({
114
+ comparatorByOptionsComputer: defaultComparatorByOptionsComputer,
115
+ optionsByGroupIndexComputer,
116
+ ignoreEslintDisabledNodes,
117
+ groups: options.groups,
118
+ nodes: nodes2,
119
+ }),
120
+ )
121
+ }
122
+ let nodes = formattedMembers.flat()
123
+ reportAllErrors({
124
+ sortNodesExcludingEslintDisabled,
125
+ availableMessageIds,
126
+ options,
127
+ context,
128
+ nodes,
129
+ })
130
+ }
131
+ export { sortArray }
@@ -11,8 +11,7 @@ import { AllCommonOptions } from '../../types/all-common-options.js'
11
11
  export type Options = Partial<
12
12
  {
13
13
  /**
14
- * Conditional configuration based on pattern matching. When specified, the
15
- * rule applies only if all array element names match the given pattern.
14
+ * Conditional configuration based on pattern matching.
16
15
  */
17
16
  useConfigurationIf: {
18
17
  /**
@@ -20,6 +19,10 @@ export type Options = Partial<
20
19
  * The rule is only applied when all names match this pattern.
21
20
  */
22
21
  allNamesMatchPattern?: RegexOption
22
+ /**
23
+ * AST selector to match against ArrayExpression nodes.
24
+ */
25
+ matchesAstSelector?: string
23
26
  }
24
27
  } & AllCommonOptions<
25
28
  TypeOption,
@@ -1,7 +1,4 @@
1
1
  import { JSONSchema4 } from '@typescript-eslint/utils/json-schema'
2
- import { RuleContext } from '@typescript-eslint/utils/ts-eslint'
3
- import { TSESTree } from '@typescript-eslint/types'
4
- import { TSESLint } from '@typescript-eslint/utils'
5
2
  import { Options } from './sort-array-includes/types.js'
6
3
  declare const ORDER_ERROR_ID = 'unexpectedArrayIncludesOrder'
7
4
  declare const GROUP_ORDER_ERROR_ID = 'unexpectedArrayIncludesGroupOrder'
@@ -15,26 +12,14 @@ type MessageId =
15
12
  | typeof ORDER_ERROR_ID
16
13
  export declare let defaultOptions: Required<Options[number]>
17
14
  export declare let jsonSchema: JSONSchema4
18
- declare const _default: TSESLint.RuleModule<
15
+ declare const _default: import('@typescript-eslint/utils/ts-eslint').RuleModule<
19
16
  MessageId,
20
17
  Options,
21
- import('../utils/create-eslint-rule.js').ESLintPluginDocumentation,
22
- TSESLint.RuleListener
18
+ {
19
+ recommended?: boolean
20
+ },
21
+ import('@typescript-eslint/utils/ts-eslint').RuleListener
23
22
  > & {
24
23
  name: string
25
24
  }
26
25
  export default _default
27
- export declare function sortArray<MessageIds extends string>({
28
- availableMessageIds,
29
- elements,
30
- context,
31
- }: {
32
- availableMessageIds: {
33
- missedSpacingBetweenMembers: MessageIds
34
- extraSpacingBetweenMembers: MessageIds
35
- unexpectedGroupOrder: MessageIds
36
- unexpectedOrder: MessageIds
37
- }
38
- elements: (TSESTree.SpreadElement | TSESTree.Expression | null)[]
39
- context: Readonly<RuleContext<MessageIds, Options>>
40
- }): void
@@ -1,4 +1,9 @@
1
1
  import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2
+ import {
3
+ buildUseConfigurationIfJsonSchema,
4
+ matchesAstSelectorJsonSchema,
5
+ buildCommonJsonSchemas,
6
+ } from '../utils/json-schemas/common-json-schemas.js'
2
7
  import {
3
8
  partitionByNewLineJsonSchema,
4
9
  partitionByCommentJsonSchema,
@@ -9,34 +14,11 @@ import {
9
14
  EXTRA_SPACING_ERROR,
10
15
  MISSED_SPACING_ERROR,
11
16
  } from '../utils/report-errors.js'
12
- import {
13
- buildUseConfigurationIfJsonSchema,
14
- buildCommonJsonSchemas,
15
- } from '../utils/json-schemas/common-json-schemas.js'
16
- import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration.js'
17
- import { defaultComparatorByOptionsComputer } from '../utils/compare/default-comparator-by-options-computer.js'
18
- import {
19
- additionalCustomGroupMatchOptionsJsonSchema,
20
- allSelectors,
21
- } from './sort-array-includes/types.js'
22
- import { buildOptionsByGroupIndexComputer } from '../utils/build-options-by-group-index-computer.js'
23
17
  import { buildCommonGroupsJsonSchemas } from '../utils/json-schemas/common-groups-json-schemas.js'
24
- import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration.js'
25
- import { filterOptionsByAllNamesMatch } from '../utils/filter-options-by-all-names-match.js'
26
- import { validateGroupsConfiguration } from '../utils/validate-groups-configuration.js'
27
- import { generatePredefinedGroups } from '../utils/generate-predefined-groups.js'
28
- import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines.js'
29
- import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled.js'
30
- import { doesCustomGroupMatch } from '../utils/does-custom-group-match.js'
31
- import { sortNodesByGroups } from '../utils/sort-nodes-by-groups.js'
18
+ import { additionalCustomGroupMatchOptionsJsonSchema } from './sort-array-includes/types.js'
19
+ import { buildAstListeners } from '../utils/build-ast-listeners.js'
32
20
  import { createEslintRule } from '../utils/create-eslint-rule.js'
33
- import { reportAllErrors } from '../utils/report-all-errors.js'
34
- import { shouldPartition } from '../utils/should-partition.js'
35
- import { computeGroup } from '../utils/compute-group.js'
36
- import { rangeToDiff } from '../utils/range-to-diff.js'
37
- import { getSettings } from '../utils/get-settings.js'
38
- import { isSortable } from '../utils/is-sortable.js'
39
- import { complete } from '../utils/complete.js'
21
+ import { sortArray } from './sort-array-includes/sort-array.js'
40
22
  let cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
41
23
  const ORDER_ERROR_ID = 'unexpectedArrayIncludesOrder'
42
24
  const GROUP_ORDER_ERROR_ID = 'unexpectedArrayIncludesGroupOrder'
@@ -66,7 +48,11 @@ let jsonSchema = {
66
48
  additionalCustomGroupMatchProperties:
67
49
  additionalCustomGroupMatchOptionsJsonSchema,
68
50
  }),
69
- useConfigurationIf: buildUseConfigurationIfJsonSchema(),
51
+ useConfigurationIf: buildUseConfigurationIfJsonSchema({
52
+ additionalProperties: {
53
+ matchesAstSelector: matchesAstSelectorJsonSchema,
54
+ },
55
+ }),
70
56
  partitionByComment: partitionByCommentJsonSchema,
71
57
  partitionByNewLine: partitionByNewLineJsonSchema,
72
58
  },
@@ -77,31 +63,6 @@ let jsonSchema = {
77
63
  type: 'array',
78
64
  }
79
65
  const sortArrayIncludes = createEslintRule({
80
- create: context => ({
81
- MemberExpression: node => {
82
- if (
83
- (node.object.type === AST_NODE_TYPES.ArrayExpression ||
84
- node.object.type === AST_NODE_TYPES.NewExpression) &&
85
- node.property.type === AST_NODE_TYPES.Identifier &&
86
- node.property.name === 'includes'
87
- ) {
88
- let elements =
89
- node.object.type === AST_NODE_TYPES.ArrayExpression ?
90
- node.object.elements
91
- : node.object.arguments
92
- sortArray({
93
- availableMessageIds: {
94
- missedSpacingBetweenMembers: MISSED_SPACING_ERROR_ID,
95
- extraSpacingBetweenMembers: EXTRA_SPACING_ERROR_ID,
96
- unexpectedGroupOrder: GROUP_ORDER_ERROR_ID,
97
- unexpectedOrder: ORDER_ERROR_ID,
98
- },
99
- elements,
100
- context,
101
- })
102
- }
103
- },
104
- }),
105
66
  meta: {
106
67
  messages: {
107
68
  [MISSED_SPACING_ERROR_ID]: MISSED_SPACING_ERROR,
@@ -118,110 +79,49 @@ const sortArrayIncludes = createEslintRule({
118
79
  type: 'suggestion',
119
80
  fixable: 'code',
120
81
  },
82
+ create: context =>
83
+ buildAstListeners({
84
+ nodeTypes: [AST_NODE_TYPES.NewExpression, AST_NODE_TYPES.ArrayExpression],
85
+ sorter: sortPotentiallyValidArray,
86
+ context,
87
+ }),
121
88
  defaultOptions: [defaultOptions],
122
89
  name: 'sort-array-includes',
123
90
  })
124
- function sortArray({ availableMessageIds, elements, context }) {
125
- if (!isSortable(elements)) {
91
+ function sortPotentiallyValidArray({ matchedAstSelectors, context, node }) {
92
+ if (!isValidArray()) {
126
93
  return
127
94
  }
128
- let { sourceCode, id } = context
129
- let settings = getSettings(context.settings)
130
- let matchedContextOptions = filterOptionsByAllNamesMatch({
131
- nodeNames: elements
132
- .filter(element => element !== null)
133
- .map(element => getNodeName({ sourceCode, element })),
134
- contextOptions: context.options,
135
- })
136
- let options = complete(matchedContextOptions[0], settings, defaultOptions)
137
- validateCustomSortConfiguration(options)
138
- validateGroupsConfiguration({
139
- selectors: allSelectors,
140
- modifiers: [],
141
- options,
142
- })
143
- validateNewlinesAndPartitionConfiguration(options)
144
- let eslintDisabledLines = getEslintDisabledLines({
145
- ruleName: id,
146
- sourceCode,
147
- })
148
- let optionsByGroupIndexComputer = buildOptionsByGroupIndexComputer(options)
149
- let formattedMembers = elements.reduce(
150
- (accumulator, element) => {
151
- if (element === null) {
152
- return accumulator
153
- }
154
- if (element.type === AST_NODE_TYPES.SpreadElement) {
155
- accumulator.push([])
156
- return accumulator
157
- }
158
- let name = getNodeName({ sourceCode, element })
159
- let selector = 'literal'
160
- let predefinedGroups = generatePredefinedGroups({
161
- cache: cachedGroupsByModifiersAndSelectors,
162
- selectors: [selector],
163
- modifiers: [],
164
- })
165
- let group = computeGroup({
166
- customGroupMatcher: customGroup =>
167
- doesCustomGroupMatch({
168
- selectors: [selector],
169
- elementName: name,
170
- modifiers: [],
171
- customGroup,
172
- }),
173
- predefinedGroups,
174
- options,
175
- })
176
- let sortingNode = {
177
- isEslintDisabled: isNodeEslintDisabled(element, eslintDisabledLines),
178
- size: rangeToDiff(element, sourceCode),
179
- node: element,
180
- group,
181
- name,
182
- }
183
- let lastSortingNode = accumulator.at(-1)?.at(-1)
184
- if (
185
- shouldPartition({
186
- lastSortingNode,
187
- sortingNode,
188
- sourceCode,
189
- options,
190
- })
191
- ) {
192
- accumulator.push([])
193
- }
194
- accumulator.at(-1).push({
195
- ...sortingNode,
196
- partitionId: accumulator.length,
197
- })
198
- return accumulator
95
+ sortArray({
96
+ availableMessageIds: {
97
+ missedSpacingBetweenMembers: MISSED_SPACING_ERROR_ID,
98
+ extraSpacingBetweenMembers: EXTRA_SPACING_ERROR_ID,
99
+ unexpectedGroupOrder: GROUP_ORDER_ERROR_ID,
100
+ unexpectedOrder: ORDER_ERROR_ID,
199
101
  },
200
- [[]],
201
- )
202
- function sortNodesExcludingEslintDisabled(ignoreEslintDisabledNodes) {
203
- return formattedMembers.flatMap(nodes2 =>
204
- sortNodesByGroups({
205
- comparatorByOptionsComputer: defaultComparatorByOptionsComputer,
206
- optionsByGroupIndexComputer,
207
- ignoreEslintDisabledNodes,
208
- groups: options.groups,
209
- nodes: nodes2,
210
- }),
211
- )
212
- }
213
- let nodes = formattedMembers.flat()
214
- reportAllErrors({
215
- sortNodesExcludingEslintDisabled,
216
- availableMessageIds,
217
- options,
102
+ cachedGroupsByModifiersAndSelectors,
103
+ matchedAstSelectors,
104
+ defaultOptions,
218
105
  context,
219
- nodes,
106
+ node,
220
107
  })
108
+ function isValidArray() {
109
+ if (node.parent.type !== AST_NODE_TYPES.MemberExpression) {
110
+ return false
111
+ }
112
+ if (node.parent.property.type !== AST_NODE_TYPES.Identifier) {
113
+ return false
114
+ }
115
+ if (node.parent.property.name !== 'includes') {
116
+ return false
117
+ }
118
+ if (node.parent.parent.type !== AST_NODE_TYPES.CallExpression) {
119
+ return false
120
+ }
121
+ if (node.parent.parent.callee !== node.parent) {
122
+ return false
123
+ }
124
+ return true
125
+ }
221
126
  }
222
- function getNodeName({ sourceCode, element }) {
223
- return element.type === AST_NODE_TYPES.Literal ?
224
- `${element.value}`
225
- : sourceCode.getText(element)
226
- }
227
- export { sortArrayIncludes as default, defaultOptions, jsonSchema, sortArray }
127
+ export { sortArrayIncludes as default, defaultOptions, jsonSchema }
@@ -17,11 +17,4 @@ export declare function computeDependenciesBySortingNode({
17
17
  sourceCode: TSESLint.SourceCode
18
18
  classBody: TSESTree.ClassBody
19
19
  }): Map<SortingNodeWithoutDependencies, SortingNodeWithoutDependencies[]>
20
- export declare function computeThisExpressionsInsideClassElement({
21
- classElement,
22
- sourceCode,
23
- }: {
24
- classElement: TSESTree.ClassElement
25
- sourceCode: TSESLint.SourceCode
26
- }): TSESTree.ThisExpression[]
27
20
  export {}
@@ -38,21 +38,6 @@ function computeDependenciesBySortingNode({
38
38
  }
39
39
  return dependenciesBySortingNode
40
40
  }
41
- function computeThisExpressionsInsideClassElement({
42
- classElement,
43
- sourceCode,
44
- }) {
45
- let thisTokens = sourceCode.getTokens(classElement).filter(isThisToken)
46
- return thisTokens
47
- .map(computeTokenNode)
48
- .filter(node => node?.type === AST_NODE_TYPES.ThisExpression)
49
- function computeTokenNode(token) {
50
- return sourceCode.getNodeByRangeIndex(token.range[0])
51
- }
52
- function isThisToken(token) {
53
- return token.type === AST_TOKEN_TYPES.Keyword && token.value === 'this'
54
- }
55
- }
56
41
  function computeIdentifierOrThisExpressionDependency({
57
42
  ignoreCallbackDependenciesPatterns,
58
43
  sortingNodes,
@@ -183,7 +168,19 @@ function shouldIgnoreDependencyComputation(node) {
183
168
  throw new UnreachableCaseError(node)
184
169
  }
185
170
  }
186
- export {
187
- computeDependenciesBySortingNode,
188
- computeThisExpressionsInsideClassElement,
171
+ function computeThisExpressionsInsideClassElement({
172
+ classElement,
173
+ sourceCode,
174
+ }) {
175
+ let thisTokens = sourceCode.getTokens(classElement).filter(isThisToken)
176
+ return thisTokens
177
+ .map(computeTokenNode)
178
+ .filter(node => node?.type === AST_NODE_TYPES.ThisExpression)
179
+ function computeTokenNode(token) {
180
+ return sourceCode.getNodeByRangeIndex(token.range[0])
181
+ }
182
+ function isThisToken(token) {
183
+ return token.type === AST_TOKEN_TYPES.Keyword && token.value === 'this'
184
+ }
189
185
  }
186
+ export { computeDependenciesBySortingNode }
@@ -0,0 +1,23 @@
1
+ import { RuleContext } from '@typescript-eslint/utils/ts-eslint'
2
+ import { TSESTree } from '@typescript-eslint/types'
3
+ import { Options } from './types.js'
4
+ /**
5
+ * Computes the matched context options for a given class node.
6
+ *
7
+ * @param params - Parameters.
8
+ * @param params.matchedAstSelectors - The matched AST selectors for a class
9
+ * node.
10
+ * @param params.context - The rule context.
11
+ * @returns The matched context options or undefined if none match.
12
+ */
13
+ export declare function computeMatchedContextOptions<
14
+ MessageIds extends string,
15
+ >({
16
+ matchedAstSelectors,
17
+ classElements,
18
+ context,
19
+ }: {
20
+ context: Readonly<RuleContext<MessageIds, Options>>
21
+ matchedAstSelectors: ReadonlySet<string>
22
+ classElements: TSESTree.ClassElement[]
23
+ }): Options[number] | undefined