Skip to content

Commit 4e7e5ad

Browse files
authoredOct 8, 2024··
feat: add element value pattern filter for properties in sort-classes
1 parent 7dfcb8e commit 4e7e5ad

File tree

5 files changed

+116
-2
lines changed

5 files changed

+116
-2
lines changed
 

‎docs/content/rules/sort-classes.mdx

+3
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ interface CustomGroupDefinition {
491491
selector?: string
492492
modifiers?: string[]
493493
elementNamePattern?: string
494+
elementValuePattern?: string
494495
decoratorNamePattern?: string
495496
}
496497
```
@@ -507,6 +508,7 @@ interface CustomGroupBlockDefinition {
507508
selector?: string
508509
modifiers?: string[]
509510
elementNamePattern?: string
511+
elementValuePattern?: string
510512
decoratorNamePattern?: string
511513
}>
512514
}
@@ -520,6 +522,7 @@ A class member will match a `CustomGroupBlockDefinition` group if it matches all
520522
- `selector`: Filter on the `selector` of the element.
521523
- `modifiers`: Filter on the `modifiers` of the element. (All the modifiers of the element must be present in that list)
522524
- `elementNamePattern`: If entered, will check that the name of the element matches the pattern entered.
525+
- `elementValuePattern`: Only for non-function properties. If entered, will check that the value of the property matches the pattern entered.
523526
- `decoratorNamePattern`: If entered, will check that at least one `decorator` matches the pattern entered.
524527
- `type`: Overrides the sort type for that custom group. `unsorted` will not sort the group.
525528
- `order`: Overrides the sort order for that custom group

‎rules/sort-classes-utils.ts

+15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { matches } from '../utils/matches'
1313

1414
interface CustomGroupMatchesProps {
1515
customGroup: SingleCustomGroup | CustomGroupBlock
16+
elementValue: undefined | string
1617
matcher: 'minimatch' | 'regex'
1718
selectors: Selector[]
1819
modifiers: Modifier[]
@@ -195,6 +196,20 @@ export const customGroupMatches = (props: CustomGroupMatchesProps): boolean => {
195196
}
196197
}
197198

199+
if (
200+
'elementValuePattern' in props.customGroup &&
201+
props.customGroup.elementValuePattern
202+
) {
203+
let matchesElementValuePattern: boolean = matches(
204+
props.elementValue ?? '',
205+
props.customGroup.elementValuePattern,
206+
props.matcher,
207+
)
208+
if (!matchesElementValuePattern) {
209+
return false
210+
}
211+
}
212+
198213
if (
199214
'decoratorNamePattern' in props.customGroup &&
200215
props.customGroup.decoratorNamePattern

‎rules/sort-classes.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
428428
}
429429
}
430430

431+
let memberValue: undefined | string
431432
let modifiers: Modifier[] = []
432433
let selectors: Selector[] = []
433434
if (
@@ -568,6 +569,10 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
568569
selectors.push('function-property')
569570
}
570571

572+
if (!isFunctionProperty && member.value) {
573+
memberValue = sourceCode.getText(member.value)
574+
}
575+
571576
selectors.push('property')
572577

573578
if (
@@ -593,6 +598,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
593598
customGroupMatches({
594599
customGroup,
595600
elementName: name,
601+
elementValue: memberValue,
596602
modifiers,
597603
selectors,
598604
decorators,
@@ -619,7 +625,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
619625
.find(overloadSignatures => overloadSignatures.includes(member))
620626
?.at(-1)
621627

622-
let value: SortingNodeWithDependencies = {
628+
let sortingNode: SortingNodeWithDependencies = {
623629
size: overloadSignatureGroupMember
624630
? rangeToDiff(overloadSignatureGroupMember.range)
625631
: rangeToDiff(member.range),
@@ -633,7 +639,7 @@ export default createEslintRule<SortClassesOptions, MESSAGE_ID>({
633639
),
634640
}
635641

636-
accumulator.at(-1)!.push(value)
642+
accumulator.at(-1)!.push(sortingNode)
637643

638644
return accumulator
639645
},

‎rules/sort-classes.types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ interface BaseSingleCustomGroup<T extends Selector> {
156156

157157
type AdvancedSingleCustomGroup<T extends Selector> = {
158158
decoratorNamePattern?: string
159+
elementValuePattern?: string
159160
elementNamePattern?: string
160161
} & BaseSingleCustomGroup<T>
161162

@@ -263,6 +264,10 @@ export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = {
263264
description: 'Element name pattern filter.',
264265
type: 'string',
265266
},
267+
elementValuePattern: {
268+
description: 'Element value pattern filter for properties.',
269+
type: 'string',
270+
},
266271
decoratorNamePattern: {
267272
description: 'Decorator name pattern filter.',
268273
type: 'string',

‎test/sort-classes.test.ts

+85
Original file line numberDiff line numberDiff line change
@@ -6324,6 +6324,58 @@ describe(ruleName, () => {
63246324
],
63256325
})
63266326

6327+
ruleTester.run(`${ruleName}: filters on elementValuePattern`, rule, {
6328+
valid: [],
6329+
invalid: [
6330+
{
6331+
code: dedent`
6332+
class Class {
6333+
a = computed(A)
6334+
b = inject(B)
6335+
y = inject(Y)
6336+
z = computed(Z)
6337+
c() {}
6338+
}
6339+
`,
6340+
output: dedent`
6341+
class Class {
6342+
a = computed(A)
6343+
z = computed(Z)
6344+
b = inject(B)
6345+
y = inject(Y)
6346+
c() {}
6347+
}
6348+
`,
6349+
options: [
6350+
{
6351+
groups: ['computed', 'inject', 'unknown'],
6352+
customGroups: [
6353+
{
6354+
groupName: 'inject',
6355+
elementValuePattern: 'inject*',
6356+
},
6357+
{
6358+
groupName: 'computed',
6359+
elementValuePattern: 'computed*',
6360+
},
6361+
],
6362+
},
6363+
],
6364+
errors: [
6365+
{
6366+
messageId: 'unexpectedClassesGroupOrder',
6367+
data: {
6368+
left: 'y',
6369+
leftGroup: 'inject',
6370+
right: 'z',
6371+
rightGroup: 'computed',
6372+
},
6373+
},
6374+
],
6375+
},
6376+
],
6377+
})
6378+
63276379
ruleTester.run(`${ruleName}: filters on decoratorNamePattern`, rule, {
63286380
valid: [],
63296381
invalid: [
@@ -6775,6 +6827,39 @@ describe(ruleName, () => {
67756827
},
67766828
)
67776829

6830+
ruleTester.run(
6831+
`${ruleName}: allows to use regex matcher for element values in custom groups with new API`,
6832+
rule,
6833+
{
6834+
valid: [
6835+
{
6836+
code: dedent`
6837+
class Class {
6838+
x = "iHaveFooInMyName"
6839+
z = "MeTooIHaveFoo"
6840+
a = "a"
6841+
b = "b"
6842+
}
6843+
`,
6844+
options: [
6845+
{
6846+
type: 'alphabetical',
6847+
matcher: 'regex',
6848+
groups: ['unknown', 'elementsWithoutFoo'],
6849+
customGroups: [
6850+
{
6851+
groupName: 'elementsWithoutFoo',
6852+
elementValuePattern: '^(?!.*Foo).*$',
6853+
},
6854+
],
6855+
},
6856+
],
6857+
},
6858+
],
6859+
invalid: [],
6860+
},
6861+
)
6862+
67786863
ruleTester.run(
67796864
`${ruleName}: allows to use regex matcher for decorator names in custom groups with new API`,
67806865
rule,

0 commit comments

Comments
 (0)
Please sign in to comment.