eslint-plugin-perfectionist 5.6.0 → 5.8.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 (167) hide show
  1. package/dist/index.js +7 -2
  2. package/dist/package.json.js +1 -1
  3. package/dist/rules/sort-array-includes.d.ts +6 -21
  4. package/dist/rules/sort-array-includes.js +51 -150
  5. package/dist/rules/sort-arrays/compute-array-elements.d.ts +11 -0
  6. package/dist/rules/sort-arrays/compute-array-elements.js +20 -0
  7. package/dist/rules/sort-arrays/compute-matched-context-options.d.ts +25 -0
  8. package/dist/rules/sort-arrays/compute-matched-context-options.js +33 -0
  9. package/dist/rules/sort-arrays/compute-node-name.d.ts +17 -0
  10. package/dist/rules/sort-arrays/compute-node-name.js +7 -0
  11. package/dist/rules/sort-arrays/sort-array.d.ts +25 -0
  12. package/dist/rules/sort-arrays/sort-array.js +135 -0
  13. package/dist/rules/{sort-array-includes → sort-arrays}/types.d.ts +5 -2
  14. package/dist/rules/sort-arrays.d.ts +21 -0
  15. package/dist/rules/sort-arrays.js +108 -0
  16. package/dist/rules/sort-classes/compute-dependencies-by-sorting-node.d.ts +0 -7
  17. package/dist/rules/sort-classes/compute-dependencies-by-sorting-node.js +15 -18
  18. package/dist/rules/sort-classes/compute-matched-context-options.d.ts +23 -0
  19. package/dist/rules/sort-classes/compute-matched-context-options.js +39 -0
  20. package/dist/rules/sort-classes/node-info/common-modifiers.d.ts +3 -3
  21. package/dist/rules/sort-classes/node-info/common-modifiers.js +23 -16
  22. package/dist/rules/sort-classes/sort-class.d.ts +13 -0
  23. package/dist/rules/sort-classes/sort-class.js +313 -0
  24. package/dist/rules/sort-classes/types.d.ts +40 -16
  25. package/dist/rules/sort-classes/types.js +10 -0
  26. package/dist/rules/sort-classes.d.ts +4 -13
  27. package/dist/rules/sort-classes.js +28 -320
  28. package/dist/rules/sort-decorators.d.ts +3 -1
  29. package/dist/rules/sort-enums/compute-expression-number-value.d.ts +13 -0
  30. package/dist/rules/sort-enums/compute-expression-number-value.js +76 -0
  31. package/dist/rules/sort-enums/compute-matched-context-options.d.ts +24 -0
  32. package/dist/rules/sort-enums/compute-matched-context-options.js +31 -0
  33. package/dist/rules/sort-enums/compute-node-name.d.ts +17 -0
  34. package/dist/rules/sort-enums/compute-node-name.js +7 -0
  35. package/dist/rules/sort-enums/sort-enum.d.ts +13 -0
  36. package/dist/rules/sort-enums/sort-enum.js +174 -0
  37. package/dist/rules/sort-enums/types.d.ts +27 -0
  38. package/dist/rules/sort-enums/types.js +13 -1
  39. package/dist/rules/sort-enums.d.ts +4 -13
  40. package/dist/rules/sort-enums.js +32 -252
  41. package/dist/rules/sort-export-attributes.d.ts +7 -6
  42. package/dist/rules/sort-export-attributes.js +24 -132
  43. package/dist/rules/sort-exports.d.ts +3 -1
  44. package/dist/rules/sort-heritage-clauses/compute-matched-context-options.d.ts +24 -0
  45. package/dist/rules/sort-heritage-clauses/compute-matched-context-options.js +31 -0
  46. package/dist/rules/sort-heritage-clauses/compute-node-name.d.ts +13 -0
  47. package/dist/rules/sort-heritage-clauses/compute-node-name.js +13 -0
  48. package/dist/rules/sort-heritage-clauses/sort-heritage-clause.d.ts +13 -0
  49. package/dist/rules/sort-heritage-clauses/sort-heritage-clause.js +135 -0
  50. package/dist/rules/sort-heritage-clauses/types.d.ts +34 -2
  51. package/dist/rules/sort-heritage-clauses/types.js +10 -0
  52. package/dist/rules/sort-heritage-clauses.d.ts +4 -11
  53. package/dist/rules/sort-heritage-clauses.js +30 -139
  54. package/dist/rules/sort-import-attributes/compute-matched-context-options.d.ts +26 -0
  55. package/dist/rules/sort-import-attributes/compute-matched-context-options.js +31 -0
  56. package/dist/rules/sort-import-attributes/compute-node-name.d.ts +16 -0
  57. package/dist/rules/sort-import-attributes/compute-node-name.js +15 -0
  58. package/dist/rules/sort-import-attributes/sort-import-or-export-attributes.d.ts +23 -0
  59. package/dist/rules/sort-import-attributes/sort-import-or-export-attributes.js +109 -0
  60. package/dist/rules/sort-import-attributes/types.d.ts +22 -2
  61. package/dist/rules/sort-import-attributes.d.ts +7 -4
  62. package/dist/rules/sort-import-attributes.js +48 -128
  63. package/dist/rules/sort-imports.d.ts +3 -1
  64. package/dist/rules/sort-interfaces.d.ts +3 -1
  65. package/dist/rules/sort-interfaces.js +24 -19
  66. package/dist/rules/sort-intersection-types.d.ts +3 -1
  67. package/dist/rules/sort-intersection-types.js +28 -16
  68. package/dist/rules/sort-jsx-props/compute-matched-context-options.d.ts +24 -0
  69. package/dist/rules/sort-jsx-props/compute-matched-context-options.js +64 -0
  70. package/dist/rules/sort-jsx-props/compute-node-name.d.ts +8 -0
  71. package/dist/rules/sort-jsx-props/compute-node-name.js +14 -0
  72. package/dist/rules/sort-jsx-props/sort-jsx-object.d.ts +13 -0
  73. package/dist/rules/sort-jsx-props/sort-jsx-object.js +164 -0
  74. package/dist/rules/sort-jsx-props/types.d.ts +15 -0
  75. package/dist/rules/sort-jsx-props/types.js +8 -0
  76. package/dist/rules/sort-jsx-props.d.ts +6 -14
  77. package/dist/rules/sort-jsx-props.js +20 -189
  78. package/dist/rules/sort-maps/compute-matched-context-options.d.ts +23 -0
  79. package/dist/rules/sort-maps/compute-matched-context-options.js +37 -0
  80. package/dist/rules/sort-maps/compute-node-name.d.ts +21 -0
  81. package/dist/rules/sort-maps/compute-node-name.js +14 -0
  82. package/dist/rules/sort-maps/sort-potential-map.d.ts +13 -0
  83. package/dist/rules/sort-maps/sort-potential-map.js +153 -0
  84. package/dist/rules/sort-maps/types.d.ts +16 -0
  85. package/dist/rules/sort-maps/types.js +10 -0
  86. package/dist/rules/sort-maps.d.ts +6 -14
  87. package/dist/rules/sort-maps.js +27 -178
  88. package/dist/rules/sort-modules.d.ts +3 -1
  89. package/dist/rules/sort-modules.js +24 -0
  90. package/dist/rules/sort-named-exports/compute-export-kind-modifier.d.ts +4 -0
  91. package/dist/rules/sort-named-exports/compute-export-kind-modifier.js +15 -0
  92. package/dist/rules/sort-named-exports/compute-matched-context-options.d.ts +25 -0
  93. package/dist/rules/sort-named-exports/compute-matched-context-options.js +27 -0
  94. package/dist/rules/sort-named-exports/sort-named-export.d.ts +13 -0
  95. package/dist/rules/sort-named-exports/sort-named-export.js +140 -0
  96. package/dist/rules/sort-named-exports/types.d.ts +25 -1
  97. package/dist/rules/sort-named-exports/types.js +8 -0
  98. package/dist/rules/sort-named-exports.d.ts +4 -11
  99. package/dist/rules/sort-named-exports.js +29 -153
  100. package/dist/rules/sort-named-imports/compute-import-kind-modifier.d.ts +4 -0
  101. package/dist/rules/sort-named-imports/compute-import-kind-modifier.js +15 -0
  102. package/dist/rules/sort-named-imports/compute-matched-context-options.d.ts +25 -0
  103. package/dist/rules/sort-named-imports/compute-matched-context-options.js +28 -0
  104. package/dist/rules/sort-named-imports/sort-named-import.d.ts +13 -0
  105. package/dist/rules/sort-named-imports/sort-named-import.js +144 -0
  106. package/dist/rules/sort-named-imports/types.d.ts +25 -1
  107. package/dist/rules/sort-named-imports/types.js +8 -0
  108. package/dist/rules/sort-named-imports.d.ts +4 -11
  109. package/dist/rules/sort-named-imports.js +28 -156
  110. package/dist/rules/sort-object-types/compute-matched-context-options.d.ts +2 -0
  111. package/dist/rules/sort-object-types/compute-matched-context-options.js +43 -33
  112. package/dist/rules/sort-object-types/sort-object-type-elements.d.ts +21 -0
  113. package/dist/rules/sort-object-types/sort-object-type-elements.js +176 -0
  114. package/dist/rules/sort-object-types/types.d.ts +5 -0
  115. package/dist/rules/sort-object-types.d.ts +4 -20
  116. package/dist/rules/sort-object-types.js +26 -192
  117. package/dist/rules/sort-objects/compute-dependency-names.d.ts +2 -0
  118. package/dist/rules/sort-objects/compute-dependency-names.js +38 -0
  119. package/dist/rules/sort-objects/compute-matched-context-options.d.ts +4 -0
  120. package/dist/rules/sort-objects/compute-matched-context-options.js +25 -14
  121. package/dist/rules/sort-objects/compute-node-value.d.ts +11 -0
  122. package/dist/rules/sort-objects/compute-node-value.js +19 -0
  123. package/dist/rules/sort-objects/sort-object.d.ts +13 -0
  124. package/dist/rules/sort-objects/sort-object.js +219 -0
  125. package/dist/rules/sort-objects/types.d.ts +9 -0
  126. package/dist/rules/sort-objects.d.ts +5 -4
  127. package/dist/rules/sort-objects.js +18 -261
  128. package/dist/rules/sort-sets.d.ts +4 -2
  129. package/dist/rules/sort-sets.js +44 -29
  130. package/dist/rules/sort-switch-case.d.ts +3 -1
  131. package/dist/rules/sort-union-types/compute-matched-context-options.d.ts +25 -0
  132. package/dist/rules/sort-union-types/compute-matched-context-options.js +31 -0
  133. package/dist/rules/sort-union-types/sort-union-or-intersection-types.d.ts +27 -0
  134. package/dist/rules/sort-union-types/sort-union-or-intersection-types.js +181 -0
  135. package/dist/rules/sort-union-types/types.d.ts +22 -2
  136. package/dist/rules/sort-union-types.d.ts +3 -21
  137. package/dist/rules/sort-union-types.js +35 -188
  138. package/dist/rules/sort-variable-declarations/compute-matched-context-options.d.ts +29 -0
  139. package/dist/rules/sort-variable-declarations/compute-matched-context-options.js +32 -0
  140. package/dist/rules/sort-variable-declarations/sort-variable-declaration.d.ts +13 -0
  141. package/dist/rules/sort-variable-declarations/sort-variable-declaration.js +171 -0
  142. package/dist/rules/sort-variable-declarations/types.d.ts +30 -1
  143. package/dist/rules/sort-variable-declarations/types.js +16 -1
  144. package/dist/rules/sort-variable-declarations.d.ts +4 -16
  145. package/dist/rules/sort-variable-declarations.js +35 -174
  146. package/dist/types/scoped-regex-option.d.ts +1 -3
  147. package/dist/utils/assert-is-never.d.ts +7 -0
  148. package/dist/utils/assert-is-never.js +2 -0
  149. package/dist/utils/build-ast-listeners.d.ts +46 -0
  150. package/dist/utils/build-ast-listeners.js +57 -0
  151. package/dist/utils/context-matching/passes-all-names-match-pattern-filter.d.ts +18 -0
  152. package/dist/utils/context-matching/passes-all-names-match-pattern-filter.js +8 -0
  153. package/dist/utils/context-matching/passes-ast-selector-filter.d.ts +17 -0
  154. package/dist/utils/context-matching/passes-ast-selector-filter.js +7 -0
  155. package/dist/utils/create-eslint-rule.d.ts +16 -18
  156. package/dist/utils/does-custom-group-match.d.ts +1 -1
  157. package/dist/utils/get-eslint-disabled-rules.d.ts +1 -1
  158. package/dist/utils/get-settings.d.ts +1 -1
  159. package/dist/utils/get-settings.js +1 -1
  160. package/dist/utils/json-schemas/common-json-schemas.d.ts +1 -0
  161. package/dist/utils/json-schemas/common-json-schemas.js +6 -0
  162. package/package.json +2 -2
  163. package/readme.md +33 -31
  164. package/dist/rules/sort-export-attributes/types.d.ts +0 -15
  165. package/dist/utils/filter-options-by-all-names-match.d.ts +0 -92
  166. package/dist/utils/filter-options-by-all-names-match.js +0 -11
  167. /package/dist/rules/{sort-array-includes → sort-arrays}/types.js +0 -0
package/dist/index.js CHANGED
@@ -18,11 +18,12 @@ import sortImports from './rules/sort-imports.js'
18
18
  import sortExports from './rules/sort-exports.js'
19
19
  import sortObjects from './rules/sort-objects.js'
20
20
  import sortModules from './rules/sort-modules.js'
21
+ import sortArrays from './rules/sort-arrays.js'
21
22
  import sortEnums from './rules/sort-enums.js'
22
23
  import sortMaps from './rules/sort-maps.js'
23
24
  import sortSets from './rules/sort-sets.js'
24
25
  let pluginName = 'perfectionist'
25
- let rules = {
26
+ let recommendedRules = {
26
27
  'sort-variable-declarations': sortVariableDeclarations,
27
28
  'sort-intersection-types': sortIntersectionTypes,
28
29
  'sort-import-attributes': sortImportAttributes,
@@ -46,6 +47,10 @@ let rules = {
46
47
  'sort-sets': sortSets,
47
48
  'sort-maps': sortMaps,
48
49
  }
50
+ let rules = {
51
+ ...recommendedRules,
52
+ 'sort-arrays': sortArrays,
53
+ }
49
54
  let plugin = {
50
55
  meta: {
51
56
  version,
@@ -55,7 +60,7 @@ let plugin = {
55
60
  }
56
61
  function getRules(options) {
57
62
  return Object.fromEntries(
58
- Object.keys(plugin.rules).map(ruleName => [
63
+ Object.keys(recommendedRules).map(ruleName => [
59
64
  `${pluginName}/${ruleName}`,
60
65
  ['error', options],
61
66
  ]),
@@ -1,3 +1,3 @@
1
1
  const name = 'eslint-plugin-perfectionist'
2
- const version = '5.6.0'
2
+ const version = '5.8.0'
3
3
  export { name, version }
@@ -1,8 +1,5 @@
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
- import { Options } from './sort-array-includes/types.js'
2
+ import { Options } from './sort-arrays/types.js'
6
3
  declare const ORDER_ERROR_ID = 'unexpectedArrayIncludesOrder'
7
4
  declare const GROUP_ORDER_ERROR_ID = 'unexpectedArrayIncludesGroupOrder'
8
5
  declare const EXTRA_SPACING_ERROR_ID = 'extraSpacingBetweenArrayIncludesMembers'
@@ -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-arrays/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-arrays/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,50 @@ 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
+ mustHaveMatchedContextOptions: false,
103
+ cachedGroupsByModifiersAndSelectors,
104
+ matchedAstSelectors,
105
+ defaultOptions,
218
106
  context,
219
- nodes,
107
+ node,
220
108
  })
109
+ function isValidArray() {
110
+ if (node.parent.type !== AST_NODE_TYPES.MemberExpression) {
111
+ return false
112
+ }
113
+ if (node.parent.property.type !== AST_NODE_TYPES.Identifier) {
114
+ return false
115
+ }
116
+ if (node.parent.property.name !== 'includes') {
117
+ return false
118
+ }
119
+ if (node.parent.parent.type !== AST_NODE_TYPES.CallExpression) {
120
+ return false
121
+ }
122
+ if (node.parent.parent.callee !== node.parent) {
123
+ return false
124
+ }
125
+ return true
126
+ }
221
127
  }
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 }
128
+ export { sortArrayIncludes as default, defaultOptions, jsonSchema }
@@ -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,25 @@
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
+ mustHaveMatchedContextOptions,
7
+ availableMessageIds,
8
+ matchedAstSelectors,
9
+ defaultOptions,
10
+ context,
11
+ node,
12
+ }: {
13
+ availableMessageIds: {
14
+ missedSpacingBetweenMembers: MessageIds
15
+ extraSpacingBetweenMembers: MessageIds
16
+ unexpectedGroupOrder: MessageIds
17
+ unexpectedOrder: MessageIds
18
+ }
19
+ cachedGroupsByModifiersAndSelectors: Map<string, string[]>
20
+ node: TSESTree.ArrayExpression | TSESTree.NewExpression
21
+ context: Readonly<RuleContext<MessageIds, Options>>
22
+ defaultOptions: Required<Options[number]>
23
+ matchedAstSelectors: ReadonlySet<string>
24
+ mustHaveMatchedContextOptions: boolean
25
+ }): void
@@ -0,0 +1,135 @@
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
+ mustHaveMatchedContextOptions,
26
+ availableMessageIds,
27
+ matchedAstSelectors,
28
+ defaultOptions,
29
+ context,
30
+ node,
31
+ }) {
32
+ let elements = computeArrayElements(node)
33
+ if (!elements) {
34
+ return
35
+ }
36
+ if (!isSortable(elements)) {
37
+ return
38
+ }
39
+ let { sourceCode, id } = context
40
+ let settings = getSettings(context.settings)
41
+ let matchedContextOptions = computeMatchedContextOptions({
42
+ matchedAstSelectors,
43
+ elements,
44
+ context,
45
+ })
46
+ if (mustHaveMatchedContextOptions && !matchedContextOptions) {
47
+ return
48
+ }
49
+ let options = complete(matchedContextOptions, settings, defaultOptions)
50
+ validateCustomSortConfiguration(options)
51
+ validateGroupsConfiguration({
52
+ selectors: allSelectors,
53
+ modifiers: [],
54
+ options,
55
+ })
56
+ validateNewlinesAndPartitionConfiguration(options)
57
+ let eslintDisabledLines = getEslintDisabledLines({
58
+ ruleName: id,
59
+ sourceCode,
60
+ })
61
+ let optionsByGroupIndexComputer = buildOptionsByGroupIndexComputer(options)
62
+ let formattedMembers = elements.reduce(
63
+ (accumulator, element) => {
64
+ if (element === null) {
65
+ return accumulator
66
+ }
67
+ if (element.type === AST_NODE_TYPES.SpreadElement) {
68
+ accumulator.push([])
69
+ return accumulator
70
+ }
71
+ let name = computeNodeName({ node: element, sourceCode })
72
+ let selector = 'literal'
73
+ let predefinedGroups = generatePredefinedGroups({
74
+ cache: cachedGroupsByModifiersAndSelectors,
75
+ selectors: [selector],
76
+ modifiers: [],
77
+ })
78
+ let group = computeGroup({
79
+ customGroupMatcher: customGroup =>
80
+ doesCustomGroupMatch({
81
+ selectors: [selector],
82
+ elementName: name,
83
+ modifiers: [],
84
+ customGroup,
85
+ }),
86
+ predefinedGroups,
87
+ options,
88
+ })
89
+ let sortingNode = {
90
+ isEslintDisabled: isNodeEslintDisabled(element, eslintDisabledLines),
91
+ size: rangeToDiff(element, sourceCode),
92
+ node: element,
93
+ group,
94
+ name,
95
+ }
96
+ let lastSortingNode = accumulator.at(-1)?.at(-1)
97
+ if (
98
+ shouldPartition({
99
+ lastSortingNode,
100
+ sortingNode,
101
+ sourceCode,
102
+ options,
103
+ })
104
+ ) {
105
+ accumulator.push([])
106
+ }
107
+ accumulator.at(-1).push({
108
+ ...sortingNode,
109
+ partitionId: accumulator.length,
110
+ })
111
+ return accumulator
112
+ },
113
+ [[]],
114
+ )
115
+ function sortNodesExcludingEslintDisabled(ignoreEslintDisabledNodes) {
116
+ return formattedMembers.flatMap(nodes2 =>
117
+ sortNodesByGroups({
118
+ comparatorByOptionsComputer: defaultComparatorByOptionsComputer,
119
+ optionsByGroupIndexComputer,
120
+ ignoreEslintDisabledNodes,
121
+ groups: options.groups,
122
+ nodes: nodes2,
123
+ }),
124
+ )
125
+ }
126
+ let nodes = formattedMembers.flat()
127
+ reportAllErrors({
128
+ sortNodesExcludingEslintDisabled,
129
+ availableMessageIds,
130
+ options,
131
+ context,
132
+ nodes,
133
+ })
134
+ }
135
+ 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,
@@ -0,0 +1,21 @@
1
+ import { Options } from './sort-arrays/types.js'
2
+ declare const ORDER_ERROR_ID = 'unexpectedArraysOrder'
3
+ declare const GROUP_ORDER_ERROR_ID = 'unexpectedArraysGroupOrder'
4
+ declare const EXTRA_SPACING_ERROR_ID = 'extraSpacingBetweenArraysMembers'
5
+ declare const MISSED_SPACING_ERROR_ID = 'missedSpacingBetweenArraysMembers'
6
+ type MessageId =
7
+ | typeof MISSED_SPACING_ERROR_ID
8
+ | typeof EXTRA_SPACING_ERROR_ID
9
+ | typeof GROUP_ORDER_ERROR_ID
10
+ | typeof ORDER_ERROR_ID
11
+ declare const _default: import('@typescript-eslint/utils/ts-eslint').RuleModule<
12
+ MessageId,
13
+ Options,
14
+ {
15
+ recommended?: boolean
16
+ },
17
+ import('@typescript-eslint/utils/ts-eslint').RuleListener
18
+ > & {
19
+ name: string
20
+ }
21
+ export default _default