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.
- package/dist/index.d.ts +91 -31
- package/dist/index.js +7 -4
- package/dist/index.mjs +7 -4
- package/dist/rules/sort-array-includes.js +17 -3
- package/dist/rules/sort-array-includes.mjs +17 -3
- package/dist/rules/sort-astro-attributes.js +18 -1
- package/dist/rules/sort-astro-attributes.mjs +19 -3
- package/dist/rules/sort-classes-utils.js +62 -8
- package/dist/rules/sort-classes-utils.mjs +56 -8
- package/dist/rules/sort-classes.js +52 -63
- package/dist/rules/sort-classes.mjs +48 -60
- package/dist/rules/sort-classes.types.js +4 -0
- package/dist/rules/sort-classes.types.mjs +4 -0
- package/dist/rules/sort-enums.js +24 -3
- package/dist/rules/sort-enums.mjs +18 -3
- package/dist/rules/sort-exports.js +23 -3
- package/dist/rules/sort-exports.mjs +17 -3
- package/dist/rules/sort-imports.js +234 -238
- package/dist/rules/sort-imports.mjs +219 -227
- package/dist/rules/sort-interfaces.js +37 -10
- package/dist/rules/sort-interfaces.mjs +32 -12
- package/dist/rules/sort-intersection-types.js +24 -4
- package/dist/rules/sort-intersection-types.mjs +18 -4
- package/dist/rules/sort-jsx-props.js +18 -3
- package/dist/rules/sort-jsx-props.mjs +19 -5
- package/dist/rules/sort-maps.js +17 -3
- package/dist/rules/sort-maps.mjs +17 -3
- package/dist/rules/sort-named-exports.js +23 -3
- package/dist/rules/sort-named-exports.mjs +17 -3
- package/dist/rules/sort-named-imports.js +22 -3
- package/dist/rules/sort-named-imports.mjs +16 -3
- package/dist/rules/sort-object-types.js +37 -8
- package/dist/rules/sort-object-types.mjs +31 -10
- package/dist/rules/sort-objects.js +35 -16
- package/dist/rules/sort-objects.mjs +33 -15
- package/dist/rules/sort-sets.js +2 -0
- package/dist/rules/sort-sets.mjs +2 -0
- package/dist/rules/sort-svelte-attributes.js +21 -6
- package/dist/rules/sort-svelte-attributes.mjs +22 -8
- package/dist/rules/sort-switch-case.js +10 -1
- package/dist/rules/sort-switch-case.mjs +10 -1
- package/dist/rules/sort-union-types.js +24 -4
- package/dist/rules/sort-union-types.mjs +18 -4
- package/dist/rules/sort-variable-declarations.js +23 -3
- package/dist/rules/sort-variable-declarations.mjs +17 -3
- package/dist/rules/sort-vue-attributes.js +18 -1
- package/dist/rules/sort-vue-attributes.mjs +19 -3
- package/dist/utils/compare.js +26 -6
- package/dist/utils/compare.mjs +26 -6
- package/dist/utils/get-node-range.js +11 -3
- package/dist/utils/get-node-range.mjs +13 -3
- package/dist/utils/get-options-with-clean-groups.js +13 -0
- package/dist/utils/get-options-with-clean-groups.mjs +11 -0
- package/dist/utils/get-settings.js +9 -10
- package/dist/utils/get-settings.mjs +9 -10
- package/dist/utils/is-partition-comment.js +8 -10
- package/dist/utils/is-partition-comment.mjs +8 -10
- package/dist/utils/matches.js +15 -0
- package/dist/utils/matches.mjs +13 -0
- package/dist/utils/sort-nodes-by-groups.js +33 -7
- package/dist/utils/sort-nodes-by-groups.mjs +33 -7
- package/dist/utils/use-groups.js +4 -8
- package/dist/utils/use-groups.mjs +4 -13
- package/dist/utils/validate-groups-configuration.js +11 -0
- package/dist/utils/validate-groups-configuration.mjs +11 -1
- package/{license → license.md} +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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(
|
|
550
|
+
accumulator.at(-1).push(sortingNode)
|
|
533
551
|
return accumulator
|
|
534
552
|
},
|
|
535
553
|
[[]],
|
|
536
554
|
)
|
|
537
|
-
let sortedNodes =
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
)
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
|
|
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(
|
|
622
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
554
|
+
accumulator.at(-1).push(sortingNode)
|
|
538
555
|
return accumulator
|
|
539
556
|
},
|
|
540
557
|
[[]],
|
|
541
558
|
)
|
|
542
|
-
let sortedNodes =
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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
|
-
|
|
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',
|
package/dist/rules/sort-enums.js
CHANGED
|
@@ -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(
|
|
259
|
-
|
|
260
|
-
|
|
275
|
+
makeFixes.makeFixes(
|
|
276
|
+
fixer,
|
|
277
|
+
nodes,
|
|
278
|
+
sortedNodes,
|
|
279
|
+
sourceCode,
|
|
280
|
+
options,
|
|
281
|
+
),
|
|
261
282
|
})
|
|
262
283
|
}
|
|
263
284
|
})
|