eslint-plugin-perfectionist 3.7.0 → 3.9.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 (67) hide show
  1. package/dist/index.d.ts +91 -31
  2. package/dist/index.js +7 -4
  3. package/dist/index.mjs +7 -4
  4. package/dist/rules/sort-array-includes.js +17 -3
  5. package/dist/rules/sort-array-includes.mjs +17 -3
  6. package/dist/rules/sort-astro-attributes.js +18 -1
  7. package/dist/rules/sort-astro-attributes.mjs +19 -3
  8. package/dist/rules/sort-classes-utils.js +62 -8
  9. package/dist/rules/sort-classes-utils.mjs +56 -8
  10. package/dist/rules/sort-classes.js +52 -63
  11. package/dist/rules/sort-classes.mjs +48 -60
  12. package/dist/rules/sort-classes.types.js +4 -0
  13. package/dist/rules/sort-classes.types.mjs +4 -0
  14. package/dist/rules/sort-enums.js +24 -3
  15. package/dist/rules/sort-enums.mjs +18 -3
  16. package/dist/rules/sort-exports.js +23 -3
  17. package/dist/rules/sort-exports.mjs +17 -3
  18. package/dist/rules/sort-imports.js +234 -238
  19. package/dist/rules/sort-imports.mjs +219 -227
  20. package/dist/rules/sort-interfaces.js +37 -10
  21. package/dist/rules/sort-interfaces.mjs +32 -12
  22. package/dist/rules/sort-intersection-types.js +24 -4
  23. package/dist/rules/sort-intersection-types.mjs +18 -4
  24. package/dist/rules/sort-jsx-props.js +18 -3
  25. package/dist/rules/sort-jsx-props.mjs +19 -5
  26. package/dist/rules/sort-maps.js +17 -3
  27. package/dist/rules/sort-maps.mjs +17 -3
  28. package/dist/rules/sort-named-exports.js +23 -3
  29. package/dist/rules/sort-named-exports.mjs +17 -3
  30. package/dist/rules/sort-named-imports.js +22 -3
  31. package/dist/rules/sort-named-imports.mjs +16 -3
  32. package/dist/rules/sort-object-types.js +37 -8
  33. package/dist/rules/sort-object-types.mjs +31 -10
  34. package/dist/rules/sort-objects.js +35 -16
  35. package/dist/rules/sort-objects.mjs +33 -15
  36. package/dist/rules/sort-sets.js +2 -0
  37. package/dist/rules/sort-sets.mjs +2 -0
  38. package/dist/rules/sort-svelte-attributes.js +21 -6
  39. package/dist/rules/sort-svelte-attributes.mjs +22 -8
  40. package/dist/rules/sort-switch-case.js +10 -1
  41. package/dist/rules/sort-switch-case.mjs +10 -1
  42. package/dist/rules/sort-union-types.js +24 -4
  43. package/dist/rules/sort-union-types.mjs +18 -4
  44. package/dist/rules/sort-variable-declarations.js +23 -3
  45. package/dist/rules/sort-variable-declarations.mjs +17 -3
  46. package/dist/rules/sort-vue-attributes.js +18 -1
  47. package/dist/rules/sort-vue-attributes.mjs +19 -3
  48. package/dist/utils/compare.js +26 -6
  49. package/dist/utils/compare.mjs +26 -6
  50. package/dist/utils/get-node-range.js +11 -3
  51. package/dist/utils/get-node-range.mjs +13 -3
  52. package/dist/utils/get-options-with-clean-groups.js +13 -0
  53. package/dist/utils/get-options-with-clean-groups.mjs +11 -0
  54. package/dist/utils/get-settings.js +9 -10
  55. package/dist/utils/get-settings.mjs +9 -10
  56. package/dist/utils/is-partition-comment.js +8 -10
  57. package/dist/utils/is-partition-comment.mjs +8 -10
  58. package/dist/utils/matches.js +15 -0
  59. package/dist/utils/matches.mjs +13 -0
  60. package/dist/utils/sort-nodes-by-groups.js +33 -7
  61. package/dist/utils/sort-nodes-by-groups.mjs +33 -7
  62. package/dist/utils/use-groups.js +4 -8
  63. package/dist/utils/use-groups.mjs +4 -13
  64. package/dist/utils/validate-groups-configuration.js +11 -0
  65. package/dist/utils/validate-groups-configuration.mjs +11 -1
  66. package/{license → license.md} +1 -1
  67. package/package.json +3 -3
@@ -1,4 +1,6 @@
1
- import { minimatch } from 'minimatch'
1
+ import { validateNoDuplicatedGroups } from '../utils/validate-groups-configuration.mjs'
2
+ import { allSelectors, allModifiers } from './sort-classes.types.mjs'
3
+ import { matches } from '../utils/matches.mjs'
2
4
  const cachedGroupsByModifiersAndSelectors = /* @__PURE__ */ new Map()
3
5
  const generateOfficialGroups = (modifiers, selectors) => {
4
6
  let modifiersAndSelectorsKey = modifiers.join('&') + '/' + selectors.join('&')
@@ -117,26 +119,35 @@ const customGroupMatches = props => {
117
119
  'elementNamePattern' in props.customGroup &&
118
120
  props.customGroup.elementNamePattern
119
121
  ) {
120
- let matchesElementNamePattern = minimatch(
122
+ let matchesElementNamePattern = matches(
121
123
  props.elementName,
122
124
  props.customGroup.elementNamePattern,
123
- {
124
- nocomment: true,
125
- },
125
+ props.matcher,
126
126
  )
127
127
  if (!matchesElementNamePattern) {
128
128
  return false
129
129
  }
130
130
  }
131
+ if (
132
+ 'elementValuePattern' in props.customGroup &&
133
+ props.customGroup.elementValuePattern
134
+ ) {
135
+ let matchesElementValuePattern = matches(
136
+ props.elementValue ?? '',
137
+ props.customGroup.elementValuePattern,
138
+ props.matcher,
139
+ )
140
+ if (!matchesElementValuePattern) {
141
+ return false
142
+ }
143
+ }
131
144
  if (
132
145
  'decoratorNamePattern' in props.customGroup &&
133
146
  props.customGroup.decoratorNamePattern
134
147
  ) {
135
148
  let decoratorPattern = props.customGroup.decoratorNamePattern
136
149
  let matchesDecoratorNamePattern = props.decorators.some(decorator =>
137
- minimatch(decorator, decoratorPattern, {
138
- nocomment: true,
139
- }),
150
+ matches(decorator, decoratorPattern, props.matcher),
140
151
  )
141
152
  if (!matchesDecoratorNamePattern) {
142
153
  return false
@@ -159,12 +170,49 @@ const getCompareOptions = (options, groupNumber) => {
159
170
  customGroup && 'order' in customGroup && customGroup.order
160
171
  ? customGroup.order
161
172
  : options.order,
173
+ specialCharacters: options.specialCharacters,
162
174
  ignoreCase: options.ignoreCase,
163
175
  }
164
176
  }
177
+ let validateGroupsConfiguration = (groups, customGroups) => {
178
+ let availableCustomGroupNames = Array.isArray(customGroups)
179
+ ? customGroups.map(customGroup => customGroup.groupName)
180
+ : Object.keys(customGroups)
181
+ let invalidGroups = groups
182
+ .flat()
183
+ .filter(
184
+ group =>
185
+ !isPredefinedGroup(group) && !availableCustomGroupNames.includes(group),
186
+ )
187
+ if (invalidGroups.length) {
188
+ throw new Error('Invalid group(s): ' + invalidGroups.join(', '))
189
+ }
190
+ validateNoDuplicatedGroups(groups)
191
+ }
192
+ const isPredefinedGroup = input => {
193
+ if (input === 'unknown') {
194
+ return true
195
+ }
196
+ let singleWordSelector = input.split('-').at(-1)
197
+ if (!singleWordSelector) {
198
+ return false
199
+ }
200
+ let twoWordsSelector = input.split('-').slice(-2).join('-')
201
+ let isTwoWordSelectorValid = allSelectors.includes(twoWordsSelector)
202
+ if (!allSelectors.includes(singleWordSelector) && !isTwoWordSelectorValid) {
203
+ return false
204
+ }
205
+ let modifiers = input.split('-').slice(0, isTwoWordSelectorValid ? -2 : -1)
206
+ return (
207
+ new Set(modifiers).size === modifiers.length &&
208
+ modifiers.every(modifier => allModifiers.includes(modifier))
209
+ )
210
+ }
165
211
  export {
166
212
  customGroupMatches,
167
213
  generateOfficialGroups,
214
+ getCombinations,
168
215
  getCompareOptions,
169
216
  getOverloadSignatureGroups,
217
+ validateGroupsConfiguration,
170
218
  }
@@ -3,6 +3,7 @@ const sortClassesUtils = require('./sort-classes-utils.js')
3
3
  const sortClasses_types = require('./sort-classes.types.js')
4
4
  const sortNodesByDependencies = require('../utils/sort-nodes-by-dependencies.js')
5
5
  const isPartitionComment = require('../utils/is-partition-comment.js')
6
+ const sortNodesByGroups = require('../utils/sort-nodes-by-groups.js')
6
7
  const getCommentsBefore = require('../utils/get-comments-before.js')
7
8
  const createEslintRule = require('../utils/create-eslint-rule.js')
8
9
  const getGroupNumber = require('../utils/get-group-number.js')
@@ -11,7 +12,6 @@ const toSingleLine = require('../utils/to-single-line.js')
11
12
  const rangeToDiff = require('../utils/range-to-diff.js')
12
13
  const getSettings = require('../utils/get-settings.js')
13
14
  const useGroups = require('../utils/use-groups.js')
14
- const sortNodes = require('../utils/sort-nodes.js')
15
15
  const makeFixes = require('../utils/make-fixes.js')
16
16
  const complete = require('../utils/complete.js')
17
17
  const pairwise = require('../utils/pairwise.js')
@@ -38,11 +38,22 @@ const sortClasses = createEslintRule.createEslintRule({
38
38
  type: 'string',
39
39
  enum: ['asc', 'desc'],
40
40
  },
41
+ matcher: {
42
+ description: 'Specifies the string matcher.',
43
+ type: 'string',
44
+ enum: ['minimatch', 'regex'],
45
+ },
41
46
  ignoreCase: {
42
47
  description:
43
48
  'Controls whether sorting should be case-sensitive or not.',
44
49
  type: 'boolean',
45
50
  },
51
+ specialCharacters: {
52
+ description:
53
+ 'Controls how special characters should be handled before sorting.',
54
+ type: 'string',
55
+ enum: ['remove', 'trim', 'keep'],
56
+ },
46
57
  partitionByComment: {
47
58
  description:
48
59
  'Allows to use comments to separate the class members into logical groups.',
@@ -154,6 +165,8 @@ const sortClasses = createEslintRule.createEslintRule({
154
165
  type: 'alphabetical',
155
166
  order: 'asc',
156
167
  ignoreCase: true,
168
+ specialCharacters: 'keep',
169
+ matcher: 'minimatch',
157
170
  partitionByComment: false,
158
171
  groups: [
159
172
  'index-signature',
@@ -194,12 +207,18 @@ const sortClasses = createEslintRule.createEslintRule({
194
207
  ['get-method', 'set-method'],
195
208
  'unknown',
196
209
  ],
210
+ matcher: 'minimatch',
197
211
  partitionByComment: false,
198
212
  type: 'alphabetical',
199
213
  ignoreCase: true,
214
+ specialCharacters: 'keep',
200
215
  customGroups: [],
201
216
  order: 'asc',
202
217
  })
218
+ sortClassesUtils.validateGroupsConfiguration(
219
+ options.groups,
220
+ options.customGroups,
221
+ )
203
222
  let sourceCode = getSourceCode.getSourceCode(context)
204
223
  let className = (_a = node.parent.id) == null ? void 0 : _a.name
205
224
  let getDependencyName = (nodeName, isStatic) =>
@@ -221,12 +240,6 @@ const sortClasses = createEslintRule.createEslintRule({
221
240
  let extractDependencies = (expression, isMemberStatic) => {
222
241
  let dependencies = []
223
242
  let checkNode = nodeValue => {
224
- if (
225
- nodeValue.type === 'ArrowFunctionExpression' ||
226
- nodeValue.type === 'FunctionExpression'
227
- ) {
228
- return
229
- }
230
243
  if (
231
244
  nodeValue.type === 'MemberExpression' &&
232
245
  (nodeValue.object.type === 'ThisExpression' ||
@@ -322,6 +335,7 @@ const sortClasses = createEslintRule.createEslintRule({
322
335
  isPartitionComment.hasPartitionComment(
323
336
  options.partitionByComment,
324
337
  comments,
338
+ options.matcher,
325
339
  )
326
340
  ) {
327
341
  accumulator.push([])
@@ -329,7 +343,7 @@ const sortClasses = createEslintRule.createEslintRule({
329
343
  let name
330
344
  let dependencies = []
331
345
  let { getGroup, defineGroup, setCustomGroups } =
332
- useGroups.useGroups(options.groups)
346
+ useGroups.useGroups(options)
333
347
  if (member.type === 'StaticBlock') {
334
348
  name = 'static'
335
349
  } else if (member.type === 'TSIndexSignature') {
@@ -339,12 +353,10 @@ const sortClasses = createEslintRule.createEslintRule({
339
353
  ? void 0
340
354
  : _a2.range.at(0)) ?? member.range.at(1),
341
355
  )
356
+ } else if (member.key.type === 'Identifier') {
357
+ ;({ name } = member.key)
342
358
  } else {
343
- if (member.key.type === 'Identifier') {
344
- ;({ name } = member.key)
345
- } else {
346
- name = sourceCode.text.slice(...member.key.range)
347
- }
359
+ name = sourceCode.text.slice(...member.key.range)
348
360
  }
349
361
  let isPrivateHash =
350
362
  'key' in member && member.key.type === 'PrivateIdentifier'
@@ -363,6 +375,7 @@ const sortClasses = createEslintRule.createEslintRule({
363
375
  }
364
376
  }
365
377
  }
378
+ let memberValue
366
379
  let modifiers = []
367
380
  let selectors = []
368
381
  if (
@@ -473,6 +486,9 @@ const sortClasses = createEslintRule.createEslintRule({
473
486
  if (isFunctionProperty) {
474
487
  selectors.push('function-property')
475
488
  }
489
+ if (!isFunctionProperty && member.value) {
490
+ memberValue = sourceCode.getText(member.value)
491
+ }
476
492
  selectors.push('property')
477
493
  if (
478
494
  member.type === 'PropertyDefinition' &&
@@ -494,9 +510,11 @@ const sortClasses = createEslintRule.createEslintRule({
494
510
  sortClassesUtils.customGroupMatches({
495
511
  customGroup,
496
512
  elementName: name,
513
+ elementValue: memberValue,
497
514
  modifiers,
498
515
  selectors,
499
516
  decorators,
517
+ matcher: options.matcher,
500
518
  })
501
519
  ) {
502
520
  defineGroup(customGroup.groupName, true)
@@ -516,7 +534,7 @@ const sortClasses = createEslintRule.createEslintRule({
516
534
  )) == null
517
535
  ? void 0
518
536
  : _d.at(-1)
519
- let value = {
537
+ let sortingNode = {
520
538
  size: overloadSignatureGroupMember
521
539
  ? rangeToDiff.rangeToDiff(overloadSignatureGroupMember.range)
522
540
  : rangeToDiff.rangeToDiff(member.range),
@@ -529,61 +547,28 @@ const sortClasses = createEslintRule.createEslintRule({
529
547
  modifiers.includes('static'),
530
548
  ),
531
549
  }
532
- accumulator.at(-1).push(value)
550
+ accumulator.at(-1).push(sortingNode)
533
551
  return accumulator
534
552
  },
535
553
  [[]],
536
554
  )
537
- let sortedNodes = []
538
- for (let nodes2 of formattedNodes) {
539
- let nodesByNonIgnoredGroupNumber = {}
540
- let ignoredNodeIndices = []
541
- for (let [index, sortingNode] of nodes2.entries()) {
542
- let groupNum = getGroupNumber.getGroupNumber(
543
- options.groups,
544
- sortingNode,
545
- )
546
- if (groupNum === options.groups.length) {
547
- ignoredNodeIndices.push(index)
548
- continue
549
- }
550
- nodesByNonIgnoredGroupNumber[groupNum] =
551
- nodesByNonIgnoredGroupNumber[groupNum] ?? []
552
- nodesByNonIgnoredGroupNumber[groupNum].push(sortingNode)
553
- }
554
- for (let groupNumber of Object.keys(
555
- nodesByNonIgnoredGroupNumber,
556
- ).sort((a, b) => Number(a) - Number(b))) {
557
- let compareOptions = sortClassesUtils.getCompareOptions(
558
- options,
559
- Number(groupNumber),
560
- )
561
- if (!compareOptions) {
562
- sortedNodes.push(
563
- ...nodesByNonIgnoredGroupNumber[Number(groupNumber)],
564
- )
565
- } else {
566
- sortedNodes.push(
567
- ...sortNodes.sortNodes(
568
- nodesByNonIgnoredGroupNumber[Number(groupNumber)],
569
- compareOptions,
570
- ),
571
- )
572
- }
573
- }
574
- for (let ignoredIndex of ignoredNodeIndices) {
575
- sortedNodes.splice(ignoredIndex, 0, nodes2[ignoredIndex])
576
- }
577
- }
555
+ let sortedNodes = formattedNodes
556
+ .map(nodes2 =>
557
+ sortNodesByGroups.sortNodesByGroups(nodes2, options, {
558
+ getGroupCompareOptions: groupNumber =>
559
+ sortClassesUtils.getCompareOptions(options, groupNumber),
560
+ isNodeIgnored: sortingNode =>
561
+ getGroupNumber.getGroupNumber(options.groups, sortingNode) ===
562
+ options.groups.length,
563
+ }),
564
+ )
565
+ .flat()
578
566
  sortedNodes =
579
567
  sortNodesByDependencies.sortNodesByDependencies(sortedNodes)
580
568
  let nodes = formattedNodes.flat()
581
569
  pairwise.pairwise(nodes, (left, right) => {
582
570
  let leftNum = getGroupNumber.getGroupNumber(options.groups, left)
583
571
  let rightNum = getGroupNumber.getGroupNumber(options.groups, right)
584
- let isLeftOrRightIgnored =
585
- leftNum === options.groups.length ||
586
- rightNum === options.groups.length
587
572
  let indexOfLeft = sortedNodes.indexOf(left)
588
573
  let indexOfRight = sortedNodes.indexOf(right)
589
574
  let firstUnorderedNodeDependentOnRight =
@@ -593,7 +578,7 @@ const sortClasses = createEslintRule.createEslintRule({
593
578
  )
594
579
  if (
595
580
  firstUnorderedNodeDependentOnRight ||
596
- (!isLeftOrRightIgnored && indexOfLeft > indexOfRight)
581
+ indexOfLeft > indexOfRight
597
582
  ) {
598
583
  let messageId
599
584
  if (firstUnorderedNodeDependentOnRight) {
@@ -618,9 +603,13 @@ const sortClasses = createEslintRule.createEslintRule({
618
603
  },
619
604
  node: right.node,
620
605
  fix: fixer =>
621
- makeFixes.makeFixes(fixer, nodes, sortedNodes, sourceCode, {
622
- partitionComment: options.partitionByComment,
623
- }),
606
+ makeFixes.makeFixes(
607
+ fixer,
608
+ nodes,
609
+ sortedNodes,
610
+ sourceCode,
611
+ options,
612
+ ),
624
613
  })
625
614
  }
626
615
  })
@@ -1,4 +1,5 @@
1
1
  import {
2
+ validateGroupsConfiguration,
2
3
  getOverloadSignatureGroups,
3
4
  generateOfficialGroups,
4
5
  customGroupMatches,
@@ -14,6 +15,7 @@ import {
14
15
  getFirstUnorderedNodeDependentOn,
15
16
  } from '../utils/sort-nodes-by-dependencies.mjs'
16
17
  import { hasPartitionComment } from '../utils/is-partition-comment.mjs'
18
+ import { sortNodesByGroups } from '../utils/sort-nodes-by-groups.mjs'
17
19
  import { getCommentsBefore } from '../utils/get-comments-before.mjs'
18
20
  import { createEslintRule } from '../utils/create-eslint-rule.mjs'
19
21
  import { getGroupNumber } from '../utils/get-group-number.mjs'
@@ -22,7 +24,6 @@ import { toSingleLine } from '../utils/to-single-line.mjs'
22
24
  import { rangeToDiff } from '../utils/range-to-diff.mjs'
23
25
  import { getSettings } from '../utils/get-settings.mjs'
24
26
  import { useGroups } from '../utils/use-groups.mjs'
25
- import { sortNodes } from '../utils/sort-nodes.mjs'
26
27
  import { makeFixes } from '../utils/make-fixes.mjs'
27
28
  import { complete } from '../utils/complete.mjs'
28
29
  import { pairwise } from '../utils/pairwise.mjs'
@@ -49,11 +50,22 @@ const sortClasses = createEslintRule({
49
50
  type: 'string',
50
51
  enum: ['asc', 'desc'],
51
52
  },
53
+ matcher: {
54
+ description: 'Specifies the string matcher.',
55
+ type: 'string',
56
+ enum: ['minimatch', 'regex'],
57
+ },
52
58
  ignoreCase: {
53
59
  description:
54
60
  'Controls whether sorting should be case-sensitive or not.',
55
61
  type: 'boolean',
56
62
  },
63
+ specialCharacters: {
64
+ description:
65
+ 'Controls how special characters should be handled before sorting.',
66
+ type: 'string',
67
+ enum: ['remove', 'trim', 'keep'],
68
+ },
57
69
  partitionByComment: {
58
70
  description:
59
71
  'Allows to use comments to separate the class members into logical groups.',
@@ -165,6 +177,8 @@ const sortClasses = createEslintRule({
165
177
  type: 'alphabetical',
166
178
  order: 'asc',
167
179
  ignoreCase: true,
180
+ specialCharacters: 'keep',
181
+ matcher: 'minimatch',
168
182
  partitionByComment: false,
169
183
  groups: [
170
184
  'index-signature',
@@ -205,12 +219,15 @@ const sortClasses = createEslintRule({
205
219
  ['get-method', 'set-method'],
206
220
  'unknown',
207
221
  ],
222
+ matcher: 'minimatch',
208
223
  partitionByComment: false,
209
224
  type: 'alphabetical',
210
225
  ignoreCase: true,
226
+ specialCharacters: 'keep',
211
227
  customGroups: [],
212
228
  order: 'asc',
213
229
  })
230
+ validateGroupsConfiguration(options.groups, options.customGroups)
214
231
  let sourceCode = getSourceCode(context)
215
232
  let className = (_a = node.parent.id) == null ? void 0 : _a.name
216
233
  let getDependencyName = (nodeName, isStatic) =>
@@ -232,12 +249,6 @@ const sortClasses = createEslintRule({
232
249
  let extractDependencies = (expression, isMemberStatic) => {
233
250
  let dependencies = []
234
251
  let checkNode = nodeValue => {
235
- if (
236
- nodeValue.type === 'ArrowFunctionExpression' ||
237
- nodeValue.type === 'FunctionExpression'
238
- ) {
239
- return
240
- }
241
252
  if (
242
253
  nodeValue.type === 'MemberExpression' &&
243
254
  (nodeValue.object.type === 'ThisExpression' ||
@@ -326,15 +337,17 @@ const sortClasses = createEslintRule({
326
337
  let comments = getCommentsBefore(member, sourceCode)
327
338
  if (
328
339
  options.partitionByComment &&
329
- hasPartitionComment(options.partitionByComment, comments)
340
+ hasPartitionComment(
341
+ options.partitionByComment,
342
+ comments,
343
+ options.matcher,
344
+ )
330
345
  ) {
331
346
  accumulator.push([])
332
347
  }
333
348
  let name
334
349
  let dependencies = []
335
- let { getGroup, defineGroup, setCustomGroups } = useGroups(
336
- options.groups,
337
- )
350
+ let { getGroup, defineGroup, setCustomGroups } = useGroups(options)
338
351
  if (member.type === 'StaticBlock') {
339
352
  name = 'static'
340
353
  } else if (member.type === 'TSIndexSignature') {
@@ -344,12 +357,10 @@ const sortClasses = createEslintRule({
344
357
  ? void 0
345
358
  : _a2.range.at(0)) ?? member.range.at(1),
346
359
  )
360
+ } else if (member.key.type === 'Identifier') {
361
+ ;({ name } = member.key)
347
362
  } else {
348
- if (member.key.type === 'Identifier') {
349
- ;({ name } = member.key)
350
- } else {
351
- name = sourceCode.text.slice(...member.key.range)
352
- }
363
+ name = sourceCode.text.slice(...member.key.range)
353
364
  }
354
365
  let isPrivateHash =
355
366
  'key' in member && member.key.type === 'PrivateIdentifier'
@@ -368,6 +379,7 @@ const sortClasses = createEslintRule({
368
379
  }
369
380
  }
370
381
  }
382
+ let memberValue
371
383
  let modifiers = []
372
384
  let selectors = []
373
385
  if (
@@ -478,6 +490,9 @@ const sortClasses = createEslintRule({
478
490
  if (isFunctionProperty) {
479
491
  selectors.push('function-property')
480
492
  }
493
+ if (!isFunctionProperty && member.value) {
494
+ memberValue = sourceCode.getText(member.value)
495
+ }
481
496
  selectors.push('property')
482
497
  if (
483
498
  member.type === 'PropertyDefinition' &&
@@ -499,9 +514,11 @@ const sortClasses = createEslintRule({
499
514
  customGroupMatches({
500
515
  customGroup,
501
516
  elementName: name,
517
+ elementValue: memberValue,
502
518
  modifiers,
503
519
  selectors,
504
520
  decorators,
521
+ matcher: options.matcher,
505
522
  })
506
523
  ) {
507
524
  defineGroup(customGroup.groupName, true)
@@ -521,7 +538,7 @@ const sortClasses = createEslintRule({
521
538
  )) == null
522
539
  ? void 0
523
540
  : _d.at(-1)
524
- let value = {
541
+ let sortingNode = {
525
542
  size: overloadSignatureGroupMember
526
543
  ? rangeToDiff(overloadSignatureGroupMember.range)
527
544
  : rangeToDiff(member.range),
@@ -534,61 +551,34 @@ const sortClasses = createEslintRule({
534
551
  modifiers.includes('static'),
535
552
  ),
536
553
  }
537
- accumulator.at(-1).push(value)
554
+ accumulator.at(-1).push(sortingNode)
538
555
  return accumulator
539
556
  },
540
557
  [[]],
541
558
  )
542
- let sortedNodes = []
543
- for (let nodes2 of formattedNodes) {
544
- let nodesByNonIgnoredGroupNumber = {}
545
- let ignoredNodeIndices = []
546
- for (let [index, sortingNode] of nodes2.entries()) {
547
- let groupNum = getGroupNumber(options.groups, sortingNode)
548
- if (groupNum === options.groups.length) {
549
- ignoredNodeIndices.push(index)
550
- continue
551
- }
552
- nodesByNonIgnoredGroupNumber[groupNum] =
553
- nodesByNonIgnoredGroupNumber[groupNum] ?? []
554
- nodesByNonIgnoredGroupNumber[groupNum].push(sortingNode)
555
- }
556
- for (let groupNumber of Object.keys(
557
- nodesByNonIgnoredGroupNumber,
558
- ).sort((a, b) => Number(a) - Number(b))) {
559
- let compareOptions = getCompareOptions(options, Number(groupNumber))
560
- if (!compareOptions) {
561
- sortedNodes.push(
562
- ...nodesByNonIgnoredGroupNumber[Number(groupNumber)],
563
- )
564
- } else {
565
- sortedNodes.push(
566
- ...sortNodes(
567
- nodesByNonIgnoredGroupNumber[Number(groupNumber)],
568
- compareOptions,
569
- ),
570
- )
571
- }
572
- }
573
- for (let ignoredIndex of ignoredNodeIndices) {
574
- sortedNodes.splice(ignoredIndex, 0, nodes2[ignoredIndex])
575
- }
576
- }
559
+ let sortedNodes = formattedNodes
560
+ .map(nodes2 =>
561
+ sortNodesByGroups(nodes2, options, {
562
+ getGroupCompareOptions: groupNumber =>
563
+ getCompareOptions(options, groupNumber),
564
+ isNodeIgnored: sortingNode =>
565
+ getGroupNumber(options.groups, sortingNode) ===
566
+ options.groups.length,
567
+ }),
568
+ )
569
+ .flat()
577
570
  sortedNodes = sortNodesByDependencies(sortedNodes)
578
571
  let nodes = formattedNodes.flat()
579
572
  pairwise(nodes, (left, right) => {
580
573
  let leftNum = getGroupNumber(options.groups, left)
581
574
  let rightNum = getGroupNumber(options.groups, right)
582
- let isLeftOrRightIgnored =
583
- leftNum === options.groups.length ||
584
- rightNum === options.groups.length
585
575
  let indexOfLeft = sortedNodes.indexOf(left)
586
576
  let indexOfRight = sortedNodes.indexOf(right)
587
577
  let firstUnorderedNodeDependentOnRight =
588
578
  getFirstUnorderedNodeDependentOn(right, nodes)
589
579
  if (
590
580
  firstUnorderedNodeDependentOnRight ||
591
- (!isLeftOrRightIgnored && indexOfLeft > indexOfRight)
581
+ indexOfLeft > indexOfRight
592
582
  ) {
593
583
  let messageId
594
584
  if (firstUnorderedNodeDependentOnRight) {
@@ -613,9 +603,7 @@ const sortClasses = createEslintRule({
613
603
  },
614
604
  node: right.node,
615
605
  fix: fixer =>
616
- makeFixes(fixer, nodes, sortedNodes, sourceCode, {
617
- partitionComment: options.partitionByComment,
618
- }),
606
+ makeFixes(fixer, nodes, sortedNodes, sourceCode, options),
619
607
  })
620
608
  }
621
609
  })
@@ -59,6 +59,10 @@ const singleCustomGroupJsonSchema = {
59
59
  description: 'Element name pattern filter.',
60
60
  type: 'string',
61
61
  },
62
+ elementValuePattern: {
63
+ description: 'Element value pattern filter for properties.',
64
+ type: 'string',
65
+ },
62
66
  decoratorNamePattern: {
63
67
  description: 'Decorator name pattern filter.',
64
68
  type: 'string',
@@ -57,6 +57,10 @@ const singleCustomGroupJsonSchema = {
57
57
  description: 'Element name pattern filter.',
58
58
  type: 'string',
59
59
  },
60
+ elementValuePattern: {
61
+ description: 'Element value pattern filter for properties.',
62
+ type: 'string',
63
+ },
60
64
  decoratorNamePattern: {
61
65
  description: 'Decorator name pattern filter.',
62
66
  type: 'string',
@@ -35,11 +35,22 @@ const sortEnums = createEslintRule.createEslintRule({
35
35
  type: 'string',
36
36
  enum: ['asc', 'desc'],
37
37
  },
38
+ matcher: {
39
+ description: 'Specifies the string matcher.',
40
+ type: 'string',
41
+ enum: ['minimatch', 'regex'],
42
+ },
38
43
  ignoreCase: {
39
44
  description:
40
45
  'Controls whether sorting should be case-sensitive or not.',
41
46
  type: 'boolean',
42
47
  },
48
+ specialCharacters: {
49
+ description:
50
+ 'Controls how special characters should be handled before sorting.',
51
+ type: 'string',
52
+ enum: ['remove', 'trim', 'keep'],
53
+ },
43
54
  sortByValue: {
44
55
  description: 'Compare enum values instead of names.',
45
56
  type: 'boolean',
@@ -87,6 +98,8 @@ const sortEnums = createEslintRule.createEslintRule({
87
98
  type: 'alphabetical',
88
99
  order: 'asc',
89
100
  ignoreCase: true,
101
+ specialCharacters: 'keep',
102
+ matcher: 'minimatch',
90
103
  sortByValue: false,
91
104
  partitionByComment: false,
92
105
  partitionByNewLine: false,
@@ -115,7 +128,9 @@ const sortEnums = createEslintRule.createEslintRule({
115
128
  partitionByComment: false,
116
129
  partitionByNewLine: false,
117
130
  type: 'alphabetical',
131
+ matcher: 'minimatch',
118
132
  ignoreCase: true,
133
+ specialCharacters: 'keep',
119
134
  order: 'asc',
120
135
  sortByValue: false,
121
136
  forceNumericSort: false,
@@ -174,6 +189,7 @@ const sortEnums = createEslintRule.createEslintRule({
174
189
  isPartitionComment.hasPartitionComment(
175
190
  partitionComment,
176
191
  getCommentsBefore.getCommentsBefore(member, sourceCode),
192
+ options.matcher,
177
193
  )) ||
178
194
  (options.partitionByNewLine &&
179
195
  lastSortingNode &&
@@ -205,6 +221,7 @@ const sortEnums = createEslintRule.createEslintRule({
205
221
  : options.type,
206
222
  order: options.order,
207
223
  ignoreCase: options.ignoreCase,
224
+ specialCharacters: options.specialCharacters,
208
225
  // Get the enum value rather than the name if needed
209
226
  nodeValueGetter:
210
227
  options.sortByValue || (isNumericEnum && options.forceNumericSort)
@@ -255,9 +272,13 @@ const sortEnums = createEslintRule.createEslintRule({
255
272
  },
256
273
  node: right.node,
257
274
  fix: fixer =>
258
- makeFixes.makeFixes(fixer, nodes, sortedNodes, sourceCode, {
259
- partitionComment,
260
- }),
275
+ makeFixes.makeFixes(
276
+ fixer,
277
+ nodes,
278
+ sortedNodes,
279
+ sourceCode,
280
+ options,
281
+ ),
261
282
  })
262
283
  }
263
284
  })