eslint-plugin-perfectionist 5.2.0 → 5.3.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 (127) hide show
  1. package/dist/package.json.js +1 -1
  2. package/dist/rules/sort-array-includes/types.d.ts +15 -18
  3. package/dist/rules/sort-array-includes/types.js +2 -2
  4. package/dist/rules/sort-array-includes.js +13 -10
  5. package/dist/rules/sort-classes/compute-dependencies.d.ts +24 -0
  6. package/dist/rules/sort-classes/compute-dependencies.js +147 -0
  7. package/dist/rules/sort-classes/compute-dependency-name.d.ts +9 -0
  8. package/dist/rules/sort-classes/compute-dependency-name.js +8 -0
  9. package/dist/rules/sort-classes/compute-identifier-name-details.d.ts +16 -0
  10. package/dist/rules/sort-classes/compute-identifier-name-details.js +27 -0
  11. package/dist/rules/sort-classes/get-overload-signature-groups.js +4 -3
  12. package/dist/rules/sort-classes/node-info/common-modifiers.d.ts +39 -0
  13. package/dist/rules/sort-classes/node-info/common-modifiers.js +62 -0
  14. package/dist/rules/sort-classes/node-info/compute-accessor-details.d.ts +26 -0
  15. package/dist/rules/sort-classes/node-info/compute-accessor-details.js +43 -0
  16. package/dist/rules/sort-classes/node-info/compute-index-signature-details.d.ts +23 -0
  17. package/dist/rules/sort-classes/node-info/compute-index-signature-details.js +21 -0
  18. package/dist/rules/sort-classes/node-info/compute-method-details.d.ts +29 -0
  19. package/dist/rules/sort-classes/node-info/compute-method-details.js +80 -0
  20. package/dist/rules/sort-classes/node-info/compute-method-or-property-name-details.d.ts +21 -0
  21. package/dist/rules/sort-classes/node-info/compute-method-or-property-name-details.js +17 -0
  22. package/dist/rules/sort-classes/node-info/compute-property-details.d.ts +36 -0
  23. package/dist/rules/sort-classes/node-info/compute-property-details.js +109 -0
  24. package/dist/rules/sort-classes/node-info/compute-static-block-details.d.ts +26 -0
  25. package/dist/rules/sort-classes/node-info/compute-static-block-details.js +18 -0
  26. package/dist/rules/sort-classes/types.d.ts +15 -18
  27. package/dist/rules/sort-classes/types.js +6 -2
  28. package/dist/rules/sort-classes.js +79 -291
  29. package/dist/rules/sort-decorators/types.d.ts +10 -12
  30. package/dist/rules/sort-decorators.js +57 -56
  31. package/dist/rules/sort-enums/build-comparator-by-options-computer.js +6 -0
  32. package/dist/rules/sort-enums/types.d.ts +16 -19
  33. package/dist/rules/sort-enums/types.js +2 -2
  34. package/dist/rules/sort-enums.js +13 -11
  35. package/dist/rules/sort-export-attributes/types.d.ts +6 -8
  36. package/dist/rules/sort-export-attributes.js +2 -1
  37. package/dist/rules/sort-exports/types.d.ts +11 -10
  38. package/dist/rules/sort-exports/types.js +6 -2
  39. package/dist/rules/sort-exports.js +7 -6
  40. package/dist/rules/sort-heritage-clauses/types.d.ts +6 -8
  41. package/dist/rules/sort-heritage-clauses.js +2 -1
  42. package/dist/rules/sort-import-attributes/types.d.ts +6 -8
  43. package/dist/rules/sort-import-attributes.js +2 -1
  44. package/dist/rules/sort-imports/comparator-by-options-computer.js +5 -0
  45. package/dist/rules/sort-imports/compute-specifier-modifiers.js +1 -1
  46. package/dist/rules/sort-imports/is-non-external-reference-ts-import-equals.js +1 -1
  47. package/dist/rules/sort-imports/is-side-effect-import.js +1 -1
  48. package/dist/rules/sort-imports/types.d.ts +18 -24
  49. package/dist/rules/sort-imports/types.js +9 -6
  50. package/dist/rules/sort-imports.js +25 -17
  51. package/dist/rules/sort-jsx-props/types.d.ts +18 -18
  52. package/dist/rules/sort-jsx-props/types.js +6 -2
  53. package/dist/rules/sort-jsx-props.js +14 -7
  54. package/dist/rules/sort-maps/types.d.ts +10 -16
  55. package/dist/rules/sort-maps.js +11 -6
  56. package/dist/rules/sort-modules/build-comparator-by-options-computer.js +2 -0
  57. package/dist/rules/sort-modules/compute-dependencies.d.ts +2 -5
  58. package/dist/rules/sort-modules/compute-dependencies.js +3 -0
  59. package/dist/rules/sort-modules/compute-node-details.d.ts +38 -0
  60. package/dist/rules/sort-modules/compute-node-details.js +127 -0
  61. package/dist/rules/sort-modules/is-arrow-function-node.js +1 -1
  62. package/dist/rules/sort-modules/is-property-or-accessor-node.js +1 -1
  63. package/dist/rules/sort-modules/types.d.ts +24 -17
  64. package/dist/rules/sort-modules/types.js +2 -2
  65. package/dist/rules/sort-modules.js +72 -141
  66. package/dist/rules/sort-named-exports/compute-node-name.js +1 -1
  67. package/dist/rules/sort-named-exports/types.d.ts +16 -16
  68. package/dist/rules/sort-named-exports/types.js +6 -2
  69. package/dist/rules/sort-named-exports.js +6 -5
  70. package/dist/rules/sort-named-imports/compute-node-name.js +1 -1
  71. package/dist/rules/sort-named-imports/types.d.ts +16 -17
  72. package/dist/rules/sort-named-imports/types.js +6 -2
  73. package/dist/rules/sort-named-imports.js +7 -6
  74. package/dist/rules/sort-object-types/comparator-by-options-computer.js +3 -0
  75. package/dist/rules/sort-object-types/is-member-optional.js +1 -1
  76. package/dist/rules/sort-object-types/is-node-function-type.js +20 -0
  77. package/dist/rules/sort-object-types/types.d.ts +21 -34
  78. package/dist/rules/sort-object-types/types.js +9 -6
  79. package/dist/rules/sort-object-types.js +7 -6
  80. package/dist/rules/sort-objects/types.d.ts +17 -21
  81. package/dist/rules/sort-objects/types.js +3 -3
  82. package/dist/rules/sort-objects.js +5 -3
  83. package/dist/rules/sort-sets.js +5 -4
  84. package/dist/rules/sort-switch-case.js +6 -4
  85. package/dist/rules/sort-union-types/types.d.ts +12 -12
  86. package/dist/rules/sort-union-types/types.js +2 -2
  87. package/dist/rules/sort-union-types.js +37 -35
  88. package/dist/rules/sort-variable-declarations/types.d.ts +12 -13
  89. package/dist/rules/sort-variable-declarations/types.js +2 -2
  90. package/dist/rules/sort-variable-declarations.js +14 -12
  91. package/dist/types/all-common-options.d.ts +14 -0
  92. package/dist/types/common-groups-options.d.ts +73 -95
  93. package/dist/types/common-options.d.ts +60 -55
  94. package/dist/utils/build-default-options-by-group-index-computer.d.ts +1 -1
  95. package/dist/utils/compare/build-string-formatter.d.ts +4 -5
  96. package/dist/utils/compare/build-subgroup-order-comparator.d.ts +10 -0
  97. package/dist/utils/compare/build-subgroup-order-comparator.js +49 -0
  98. package/dist/utils/compare/default-comparator-by-options-computer.d.ts +4 -1
  99. package/dist/utils/compare/default-comparator-by-options-computer.js +9 -0
  100. package/dist/utils/compute-group.d.ts +9 -9
  101. package/dist/utils/compute-overridden-options-by-group-index.d.ts +1 -1
  102. package/dist/utils/does-custom-group-match.d.ts +6 -4
  103. package/dist/utils/get-comment-above-that-should-exist.d.ts +1 -1
  104. package/dist/utils/get-newlines-between-errors.d.ts +1 -1
  105. package/dist/utils/get-newlines-between-option.d.ts +1 -7
  106. package/dist/utils/get-node-range.d.ts +2 -9
  107. package/dist/utils/get-settings.d.ts +1 -1
  108. package/dist/utils/is-group-with-overrides-option.d.ts +3 -6
  109. package/dist/utils/json-schemas/common-groups-json-schemas.d.ts +6 -6
  110. package/dist/utils/json-schemas/common-groups-json-schemas.js +12 -10
  111. package/dist/utils/json-schemas/common-json-schemas.d.ts +5 -5
  112. package/dist/utils/json-schemas/common-json-schemas.js +13 -12
  113. package/dist/utils/make-comment-above-fixes.d.ts +1 -1
  114. package/dist/utils/make-fixes.d.ts +3 -5
  115. package/dist/utils/make-newlines-between-fixes.d.ts +1 -1
  116. package/dist/utils/make-order-fixes.d.ts +2 -5
  117. package/dist/utils/report-all-errors.d.ts +19 -17
  118. package/dist/utils/report-errors.d.ts +3 -1
  119. package/dist/utils/should-partition.d.ts +2 -5
  120. package/dist/utils/validate-custom-sort-configuration.d.ts +1 -1
  121. package/dist/utils/validate-groups-configuration.d.ts +1 -1
  122. package/dist/utils/validate-newlines-and-partition-configuration.d.ts +1 -1
  123. package/package.json +2 -2
  124. package/readme.md +1 -1
  125. package/dist/types/join.d.ts +0 -19
  126. package/dist/utils/is-node-function-type.js +0 -13
  127. /package/dist/{utils → rules/sort-object-types}/is-node-function-type.d.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
1
2
  import {
2
3
  ORDER_ERROR,
3
4
  GROUP_ORDER_ERROR,
@@ -9,6 +10,11 @@ import {
9
10
  partitionByNewLineJsonSchema,
10
11
  partitionByCommentJsonSchema,
11
12
  } from '../utils/json-schemas/common-partition-json-schemas.js'
13
+ import {
14
+ additionalCustomGroupMatchOptionsJsonSchema,
15
+ allSelectors,
16
+ allModifiers,
17
+ } from './sort-classes/types.js'
12
18
  import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration.js'
13
19
  import { buildDefaultOptionsByGroupIndexComputer } from '../utils/build-default-options-by-group-index-computer.js'
14
20
  import {
@@ -16,20 +22,21 @@ import {
16
22
  buildCommonJsonSchemas,
17
23
  } from '../utils/json-schemas/common-json-schemas.js'
18
24
  import { defaultComparatorByOptionsComputer } from '../utils/compare/default-comparator-by-options-computer.js'
19
- import {
20
- singleCustomGroupJsonSchema,
21
- allSelectors,
22
- allModifiers,
23
- } from './sort-classes/types.js'
25
+ import { computeIndexSignatureDetails } from './sort-classes/node-info/compute-index-signature-details.js'
26
+ import { computeStaticBlockDetails } from './sort-classes/node-info/compute-static-block-details.js'
24
27
  import { buildCommonGroupsJsonSchemas } from '../utils/json-schemas/common-groups-json-schemas.js'
25
28
  import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration.js'
29
+ import { computePropertyDetails } from './sort-classes/node-info/compute-property-details.js'
30
+ import { computeAccessorDetails } from './sort-classes/node-info/compute-accessor-details.js'
26
31
  import { getOverloadSignatureGroups } from './sort-classes/get-overload-signature-groups.js'
32
+ import { computeMethodDetails } from './sort-classes/node-info/compute-method-details.js'
27
33
  import { validateGroupsConfiguration } from '../utils/validate-groups-configuration.js'
28
34
  import { generatePredefinedGroups } from '../utils/generate-predefined-groups.js'
29
35
  import { sortNodesByDependencies } from '../utils/sort-nodes-by-dependencies.js'
30
36
  import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines.js'
31
37
  import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled.js'
32
38
  import { doesCustomGroupMatch } from '../utils/does-custom-group-match.js'
39
+ import { UnreachableCaseError } from '../utils/unreachable-case-error.js'
33
40
  import { sortNodesByGroups } from '../utils/sort-nodes-by-groups.js'
34
41
  import { getNodeDecorators } from '../utils/get-node-decorators.js'
35
42
  import { createEslintRule } from '../utils/create-eslint-rule.js'
@@ -42,7 +49,6 @@ import { rangeToDiff } from '../utils/range-to-diff.js'
42
49
  import { getSettings } from '../utils/get-settings.js'
43
50
  import { isSortable } from '../utils/is-sortable.js'
44
51
  import { complete } from '../utils/complete.js'
45
- import { matches } from '../utils/matches.js'
46
52
  let cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
47
53
  const ORDER_ERROR_ID = 'unexpectedClassesOrder'
48
54
  const GROUP_ORDER_ERROR_ID = 'unexpectedClassesGroupOrder'
@@ -109,299 +115,88 @@ const sortClasses = createEslintRule({
109
115
  sourceCode,
110
116
  })
111
117
  let className = node.parent.id?.name
112
- function getDependencyName(props) {
113
- return `${props.isStatic ? 'static ' : ''}${props.isPrivateHash ? '#' : ''}${props.nodeNameWithoutStartingHash}`
114
- }
115
- let classMethodsDependencyNames = new Set(
116
- node.body
117
- .map(member => {
118
- if (
119
- (member.type === 'MethodDefinition' ||
120
- member.type === 'TSAbstractMethodDefinition') &&
121
- 'name' in member.key
122
- ) {
123
- return getDependencyName({
124
- isPrivateHash: member.key.type === 'PrivateIdentifier',
125
- nodeNameWithoutStartingHash: member.key.name,
126
- isStatic: member.static,
127
- })
128
- }
129
- return null
130
- })
131
- .filter(Boolean),
132
- )
133
- function extractDependencies(expression, isMemberStatic) {
134
- let dependencies = []
135
- function checkNode(nodeValue) {
136
- if (
137
- nodeValue.type === 'MemberExpression' &&
138
- (nodeValue.object.type === 'ThisExpression' ||
139
- (nodeValue.object.type === 'Identifier' &&
140
- nodeValue.object.name === className)) &&
141
- (nodeValue.property.type === 'Identifier' ||
142
- nodeValue.property.type === 'PrivateIdentifier')
143
- ) {
144
- let isStaticDependency =
145
- isMemberStatic || nodeValue.object.type === 'Identifier'
146
- let dependencyName = getDependencyName({
147
- isPrivateHash: nodeValue.property.type === 'PrivateIdentifier',
148
- nodeNameWithoutStartingHash: nodeValue.property.name,
149
- isStatic: isStaticDependency,
150
- })
151
- if (!classMethodsDependencyNames.has(dependencyName)) {
152
- dependencies.push(dependencyName)
153
- }
154
- }
155
- if (nodeValue.type === 'Property') {
156
- traverseNode(nodeValue.key)
157
- traverseNode(nodeValue.value)
158
- }
159
- if (nodeValue.type === 'ConditionalExpression') {
160
- traverseNode(nodeValue.test)
161
- traverseNode(nodeValue.consequent)
162
- traverseNode(nodeValue.alternate)
163
- }
164
- if (
165
- 'expression' in nodeValue &&
166
- typeof nodeValue.expression !== 'boolean'
167
- ) {
168
- traverseNode(nodeValue.expression)
169
- }
170
- if ('object' in nodeValue) {
171
- traverseNode(nodeValue.object)
172
- }
173
- if ('callee' in nodeValue) {
174
- traverseNode(nodeValue.callee)
175
- }
176
- if ('init' in nodeValue && nodeValue.init) {
177
- traverseNode(nodeValue.init)
178
- }
179
- if ('body' in nodeValue && nodeValue.body) {
180
- traverseNode(nodeValue.body)
181
- }
182
- if ('left' in nodeValue) {
183
- traverseNode(nodeValue.left)
184
- }
185
- if ('right' in nodeValue) {
186
- traverseNode(nodeValue.right)
187
- }
188
- if ('elements' in nodeValue) {
189
- let elements = nodeValue.elements.filter(
190
- currentNode => currentNode !== null,
191
- )
192
- for (let element of elements) {
193
- traverseNode(element)
194
- }
195
- }
196
- if ('argument' in nodeValue && nodeValue.argument) {
197
- traverseNode(nodeValue.argument)
198
- }
199
- if ('arguments' in nodeValue) {
200
- let shouldIgnore = false
201
- if (nodeValue.type === 'CallExpression') {
202
- let functionName =
203
- 'name' in nodeValue.callee ? nodeValue.callee.name : null
204
- shouldIgnore =
205
- functionName !== null &&
206
- matches(
207
- functionName,
208
- options.ignoreCallbackDependenciesPatterns,
209
- )
210
- }
211
- if (!shouldIgnore) {
212
- for (let argument of nodeValue.arguments) {
213
- traverseNode(argument)
214
- }
215
- }
216
- }
217
- if ('declarations' in nodeValue) {
218
- for (let declaration of nodeValue.declarations) {
219
- traverseNode(declaration)
220
- }
221
- }
222
- if ('properties' in nodeValue) {
223
- for (let property of nodeValue.properties) {
224
- traverseNode(property)
225
- }
226
- }
227
- if ('expressions' in nodeValue) {
228
- for (let nodeExpression of nodeValue.expressions) {
229
- traverseNode(nodeExpression)
230
- }
231
- }
232
- }
233
- function traverseNode(nodeValue) {
234
- if (Array.isArray(nodeValue)) {
235
- for (let nodeItem of nodeValue) {
236
- traverseNode(nodeItem)
237
- }
238
- } else {
239
- checkNode(nodeValue)
240
- }
241
- }
242
- traverseNode(expression)
243
- return dependencies
244
- }
245
118
  let overloadSignatureGroups = getOverloadSignatureGroups(node.body)
246
119
  let formattedNodes = node.body.reduce(
247
120
  (accumulator, member) => {
248
- let name
249
121
  let dependencies = []
250
- if (member.type === 'StaticBlock') {
251
- name = 'static'
252
- } else if (member.type === 'TSIndexSignature') {
253
- name = sourceCode.text.slice(
254
- member.range.at(0),
255
- member.typeAnnotation?.range.at(0) ?? member.range.at(1),
256
- )
257
- } else if (member.key.type === 'Identifier') {
258
- ;({ name } = member.key)
259
- } else {
260
- name = sourceCode.getText(member.key)
261
- }
262
- let isPrivateHash =
263
- 'key' in member && member.key.type === 'PrivateIdentifier'
264
- let decorated = false
122
+ let isDecorated = false
265
123
  let decorators = []
266
124
  if ('decorators' in member) {
267
125
  decorators = getNodeDecorators(member).map(decorator =>
268
126
  getDecoratorName({ sourceCode, decorator }),
269
127
  )
270
- decorated = decorators.length > 0
128
+ isDecorated = decorators.length > 0
271
129
  }
130
+ let addSafetySemicolonWhenInline
131
+ let dependencyNames
132
+ let name
272
133
  let memberValue
273
- let modifiers = []
274
- let selectors = []
275
- let addSafetySemicolonWhenInline = true
134
+ let modifiers
135
+ let selectors
276
136
  switch (member.type) {
277
- case 'TSAbstractPropertyDefinition':
278
- case 'PropertyDefinition':
279
- if ('static' in member && member.static) {
280
- modifiers.push('static')
281
- }
282
- if ('declare' in member && member.declare) {
283
- modifiers.push('declare')
284
- }
285
- if (member.type === 'TSAbstractPropertyDefinition') {
286
- modifiers.push('abstract')
287
- }
288
- if (decorated) {
289
- modifiers.push('decorated')
290
- }
291
- if ('override' in member && member.override) {
292
- modifiers.push('override')
293
- }
294
- if ('readonly' in member && member.readonly) {
295
- modifiers.push('readonly')
296
- }
297
- if (
298
- 'accessibility' in member &&
299
- member.accessibility === 'protected'
300
- ) {
301
- modifiers.push('protected')
302
- } else if (
303
- ('accessibility' in member &&
304
- member.accessibility === 'private') ||
305
- isPrivateHash
306
- ) {
307
- modifiers.push('private')
308
- } else {
309
- modifiers.push('public')
310
- }
311
- if ('optional' in member && member.optional) {
312
- modifiers.push('optional')
313
- }
314
- if (
315
- member.value?.type === 'ArrowFunctionExpression' ||
316
- member.value?.type === 'FunctionExpression'
317
- ) {
318
- if (member.value.async) {
319
- modifiers.push('async')
320
- }
321
- selectors.push('function-property')
322
- } else if (member.value) {
323
- memberValue = sourceCode.getText(member.value)
324
- dependencies = extractDependencies(member.value, member.static)
325
- }
326
- selectors.push('property')
137
+ case AST_NODE_TYPES.TSAbstractPropertyDefinition:
138
+ case AST_NODE_TYPES.PropertyDefinition:
139
+ addSafetySemicolonWhenInline = true
140
+ ;({
141
+ dependencyNames,
142
+ dependencies,
143
+ memberValue,
144
+ modifiers,
145
+ selectors,
146
+ name,
147
+ } = computePropertyDetails({
148
+ ignoreCallbackDependenciesPatterns:
149
+ options.ignoreCallbackDependenciesPatterns,
150
+ property: member,
151
+ isDecorated,
152
+ sourceCode,
153
+ className,
154
+ }))
327
155
  break
328
- case 'TSAbstractMethodDefinition':
329
- case 'MethodDefinition':
330
- if (member.static) {
331
- modifiers.push('static')
332
- }
333
- if (member.type === 'TSAbstractMethodDefinition') {
334
- modifiers.push('abstract')
335
- } else if (!node.parent.declare) {
336
- addSafetySemicolonWhenInline = false
337
- }
338
- if (decorated) {
339
- modifiers.push('decorated')
340
- }
341
- if (member.override) {
342
- modifiers.push('override')
343
- }
344
- if (member.accessibility === 'protected') {
345
- modifiers.push('protected')
346
- } else if (member.accessibility === 'private' || isPrivateHash) {
347
- modifiers.push('private')
348
- } else {
349
- modifiers.push('public')
350
- }
351
- if (member.optional) {
352
- modifiers.push('optional')
353
- }
354
- if (member.value.async) {
355
- modifiers.push('async')
356
- }
357
- if (member.kind === 'constructor') {
358
- selectors.push('constructor')
359
- }
360
- if (member.kind === 'get') {
361
- selectors.push('get-method')
362
- }
363
- if (member.kind === 'set') {
364
- selectors.push('set-method')
365
- }
366
- selectors.push('method')
156
+ case AST_NODE_TYPES.TSAbstractMethodDefinition:
157
+ case AST_NODE_TYPES.MethodDefinition:
158
+ dependencyNames = []
159
+ ;({ addSafetySemicolonWhenInline, selectors, modifiers, name } =
160
+ computeMethodDetails({
161
+ hasParentDeclare: node.parent.declare,
162
+ method: member,
163
+ isDecorated,
164
+ sourceCode,
165
+ }))
367
166
  break
368
- case 'TSAbstractAccessorProperty':
369
- case 'AccessorProperty':
370
- if (member.static) {
371
- modifiers.push('static')
372
- }
373
- if (member.type === 'TSAbstractAccessorProperty') {
374
- modifiers.push('abstract')
375
- }
376
- if (decorated) {
377
- modifiers.push('decorated')
378
- }
379
- if (member.override) {
380
- modifiers.push('override')
381
- }
382
- if (member.accessibility === 'protected') {
383
- modifiers.push('protected')
384
- } else if (member.accessibility === 'private' || isPrivateHash) {
385
- modifiers.push('private')
386
- } else {
387
- modifiers.push('public')
388
- }
389
- selectors.push('accessor-property')
167
+ case AST_NODE_TYPES.TSAbstractAccessorProperty:
168
+ case AST_NODE_TYPES.AccessorProperty:
169
+ addSafetySemicolonWhenInline = true
170
+ ;({ dependencyNames, selectors, modifiers, name } =
171
+ computeAccessorDetails({
172
+ accessor: member,
173
+ isDecorated,
174
+ sourceCode,
175
+ }))
390
176
  break
391
- case 'TSIndexSignature':
392
- if (member.static) {
393
- modifiers.push('static')
394
- }
395
- if (member.readonly) {
396
- modifiers.push('readonly')
397
- }
398
- selectors.push('index-signature')
177
+ case AST_NODE_TYPES.TSIndexSignature:
178
+ addSafetySemicolonWhenInline = true
179
+ dependencyNames = []
180
+ ;({ modifiers, selectors, name } = computeIndexSignatureDetails({
181
+ indexSignature: member,
182
+ sourceCode,
183
+ }))
399
184
  break
400
- case 'StaticBlock':
185
+ case AST_NODE_TYPES.StaticBlock:
401
186
  addSafetySemicolonWhenInline = false
402
- selectors.push('static-block')
403
- dependencies = extractDependencies(member, true)
187
+ dependencyNames = []
188
+ name = 'static'
189
+ ;({ dependencies, selectors, modifiers } =
190
+ computeStaticBlockDetails({
191
+ ignoreCallbackDependenciesPatterns:
192
+ options.ignoreCallbackDependenciesPatterns,
193
+ staticBlock: member,
194
+ className,
195
+ }))
404
196
  break
197
+ /* v8 ignore next 2 -- @preserve Exhaustive guard. */
198
+ default:
199
+ throw new UnreachableCaseError(member)
405
200
  }
406
201
  let predefinedGroups = generatePredefinedGroups({
407
202
  cache: cachedGroupsByModifiersAndSelectors,
@@ -428,15 +223,6 @@ const sortClasses = createEslintRule({
428
223
  let overloadSignatureGroupMember =
429
224
  overloadSignatureGroups[overloadSignatureGroupMemberIndex]?.at(-1)
430
225
  let sortingNode = {
431
- dependencyNames: [
432
- getDependencyName({
433
- nodeNameWithoutStartingHash: name.startsWith('#')
434
- ? name.slice(1)
435
- : name,
436
- isStatic: modifiers.includes('static'),
437
- isPrivateHash,
438
- }),
439
- ],
440
226
  overloadSignaturesGroupId:
441
227
  overloadSignatureGroupMemberIndex === -1
442
228
  ? null
@@ -446,6 +232,7 @@ const sortClasses = createEslintRule({
446
232
  : rangeToDiff(member, sourceCode),
447
233
  isEslintDisabled: isNodeEslintDisabled(member, eslintDisabledLines),
448
234
  addSafetySemicolonWhenInline,
235
+ dependencyNames,
449
236
  node: member,
450
237
  dependencies,
451
238
  group,
@@ -523,7 +310,8 @@ const sortClasses = createEslintRule({
523
310
  properties: {
524
311
  ...buildCommonJsonSchemas(),
525
312
  ...buildCommonGroupsJsonSchemas({
526
- singleCustomGroupJsonSchema,
313
+ additionalCustomGroupMatchProperties:
314
+ additionalCustomGroupMatchOptionsJsonSchema,
527
315
  }),
528
316
  ignoreCallbackDependenciesPatterns: buildRegexJsonSchema(),
529
317
  partitionByComment: partitionByCommentJsonSchema,
@@ -1,7 +1,6 @@
1
1
  import { TSESTree } from '@typescript-eslint/types'
2
- import { CommonPartitionOptions } from '../../types/common-partition-options.js'
3
- import { CommonGroupsOptions } from '../../types/common-groups-options.js'
4
- import { CommonOptions, TypeOption } from '../../types/common-options.js'
2
+ import { AllCommonOptions } from '../../types/all-common-options.js'
3
+ import { TypeOption } from '../../types/common-options.js'
5
4
  import { SortingNode } from '../../types/sorting-node.js'
6
5
  export type Options = Partial<
7
6
  {
@@ -10,15 +9,14 @@ export type Options = Partial<
10
9
  sortOnAccessors: boolean
11
10
  sortOnMethods: boolean
12
11
  sortOnClasses: boolean
13
- } & CommonGroupsOptions<
14
- SingleCustomGroup,
15
- Record<string, never>,
16
- TypeOption
17
- > &
18
- CommonOptions<TypeOption> &
19
- CommonPartitionOptions
12
+ } & AllCommonOptions<
13
+ TypeOption,
14
+ AdditionalSortOptions,
15
+ CustomGroupMatchOptions
16
+ >
20
17
  >[]
21
18
  export type SortDecoratorsSortingNode = SortingNode<TSESTree.Decorator>
22
- /** Additional configuration for a single custom group. */
23
- type SingleCustomGroup = Record<string, never>
19
+ /** Match options for a custom group. */
20
+ type CustomGroupMatchOptions = object
21
+ type AdditionalSortOptions = object
24
22
  export {}
@@ -1,3 +1,4 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
1
2
  import {
2
3
  partitionByNewLineJsonSchema,
3
4
  partitionByCommentJsonSchema,
@@ -54,60 +55,6 @@ let defaultOptions = {
54
55
  groups: [],
55
56
  }
56
57
  const sortDecorators = createEslintRule({
57
- meta: {
58
- schema: {
59
- items: {
60
- properties: {
61
- ...buildCommonJsonSchemas(),
62
- ...buildCommonGroupsJsonSchemas(),
63
- sortOnParameters: {
64
- description:
65
- 'Controls whether sorting should be enabled for method parameter decorators.',
66
- type: 'boolean',
67
- },
68
- sortOnProperties: {
69
- description:
70
- 'Controls whether sorting should be enabled for class property decorators.',
71
- type: 'boolean',
72
- },
73
- sortOnAccessors: {
74
- description:
75
- 'Controls whether sorting should be enabled for class accessor decorators.',
76
- type: 'boolean',
77
- },
78
- sortOnMethods: {
79
- description:
80
- 'Controls whether sorting should be enabled for class method decorators.',
81
- type: 'boolean',
82
- },
83
- sortOnClasses: {
84
- description:
85
- 'Controls whether sorting should be enabled for class decorators.',
86
- type: 'boolean',
87
- },
88
- partitionByComment: partitionByCommentJsonSchema,
89
- partitionByNewLine: partitionByNewLineJsonSchema,
90
- },
91
- additionalProperties: false,
92
- type: 'object',
93
- },
94
- uniqueItems: true,
95
- type: 'array',
96
- },
97
- messages: {
98
- [MISSED_SPACING_ERROR_ID]: MISSED_SPACING_ERROR,
99
- [EXTRA_SPACING_ERROR_ID]: EXTRA_SPACING_ERROR,
100
- [GROUP_ORDER_ERROR_ID]: GROUP_ORDER_ERROR,
101
- [ORDER_ERROR_ID]: ORDER_ERROR,
102
- },
103
- docs: {
104
- url: 'https://perfectionist.dev/rules/sort-decorators',
105
- description: 'Enforce sorted decorators.',
106
- recommended: true,
107
- },
108
- type: 'suggestion',
109
- fixable: 'code',
110
- },
111
58
  create: context => {
112
59
  let settings = getSettings(context.settings)
113
60
  let options = complete(context.options.at(0), settings, defaultOptions)
@@ -125,8 +72,8 @@ const sortDecorators = createEslintRule({
125
72
  }
126
73
  if (
127
74
  'decorators' in decorator.parent &&
128
- decorator.parent.type === 'Identifier' &&
129
- decorator.parent.parent.type === 'FunctionExpression'
75
+ decorator.parent.type === AST_NODE_TYPES.Identifier &&
76
+ decorator.parent.parent.type === AST_NODE_TYPES.FunctionExpression
130
77
  ) {
131
78
  let { decorators } = decorator.parent
132
79
  if (decorator !== decorators[0]) {
@@ -165,6 +112,60 @@ const sortDecorators = createEslintRule({
165
112
  : null,
166
113
  }
167
114
  },
115
+ meta: {
116
+ schema: {
117
+ items: {
118
+ properties: {
119
+ ...buildCommonJsonSchemas(),
120
+ ...buildCommonGroupsJsonSchemas(),
121
+ sortOnParameters: {
122
+ description:
123
+ 'Controls whether sorting should be enabled for method parameter decorators.',
124
+ type: 'boolean',
125
+ },
126
+ sortOnProperties: {
127
+ description:
128
+ 'Controls whether sorting should be enabled for class property decorators.',
129
+ type: 'boolean',
130
+ },
131
+ sortOnAccessors: {
132
+ description:
133
+ 'Controls whether sorting should be enabled for class accessor decorators.',
134
+ type: 'boolean',
135
+ },
136
+ sortOnMethods: {
137
+ description:
138
+ 'Controls whether sorting should be enabled for class method decorators.',
139
+ type: 'boolean',
140
+ },
141
+ sortOnClasses: {
142
+ description:
143
+ 'Controls whether sorting should be enabled for class decorators.',
144
+ type: 'boolean',
145
+ },
146
+ partitionByComment: partitionByCommentJsonSchema,
147
+ partitionByNewLine: partitionByNewLineJsonSchema,
148
+ },
149
+ additionalProperties: false,
150
+ type: 'object',
151
+ },
152
+ uniqueItems: true,
153
+ type: 'array',
154
+ },
155
+ messages: {
156
+ [MISSED_SPACING_ERROR_ID]: MISSED_SPACING_ERROR,
157
+ [EXTRA_SPACING_ERROR_ID]: EXTRA_SPACING_ERROR,
158
+ [GROUP_ORDER_ERROR_ID]: GROUP_ORDER_ERROR,
159
+ [ORDER_ERROR_ID]: ORDER_ERROR,
160
+ },
161
+ docs: {
162
+ url: 'https://perfectionist.dev/rules/sort-decorators',
163
+ description: 'Enforce sorted decorators.',
164
+ recommended: true,
165
+ },
166
+ type: 'suggestion',
167
+ fixable: 'code',
168
+ },
168
169
  defaultOptions: [defaultOptions],
169
170
  name: 'sort-decorators',
170
171
  })
@@ -28,6 +28,9 @@ function buildComparatorByOptionsComputer(isNumericEnum) {
28
28
  }
29
29
  let byNonNumericValueComparatorComputer = options => {
30
30
  switch (options.type) {
31
+ /* v8 ignore next 2 -- @preserve Untested for now as not a relevant sort for this rule. */
32
+ case 'subgroup-order':
33
+ return defaultComparatorByOptionsComputer(options)
31
34
  case 'alphabetical':
32
35
  return (a, b) =>
33
36
  compareAlphabetically(a.value ?? '', b.value ?? '', options)
@@ -47,6 +50,9 @@ let byNonNumericValueComparatorComputer = options => {
47
50
  }
48
51
  let byNumericValueComparatorComputer = options => {
49
52
  switch (options.type) {
53
+ /* v8 ignore next 2 -- @preserve Untested for now as not a relevant sort for this rule. */
54
+ case 'subgroup-order':
55
+ return defaultComparatorByOptionsComputer(options)
50
56
  case 'alphabetical':
51
57
  case 'line-length':
52
58
  case 'natural':