Skip to content

Commit bc9520c

Browse files
hugop95azat-io
authored andcommitted
feat(sort-objects): add pattern matching for variable declarations
1 parent 59fe9ad commit bc9520c

File tree

4 files changed

+178
-2
lines changed

4 files changed

+178
-2
lines changed

docs/content/rules/sort-objects.mdx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ The `groups` attribute specifies whether to use groups to sort destructured obje
323323
{
324324
allNamesMatchPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[]
325325
callingFunctionNamePattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[]
326+
declarationMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[]
326327
declarationCommentMatchesPattern?: string | string[] | { pattern: string; flags: string } | { pattern: string; flags: string }[]
327328
}
328329
```
@@ -387,6 +388,26 @@ Example configuration:
387388
}
388389
```
389390

391+
- `declarationMatchesPattern` — A regexp pattern that the object's declaration name must match.
392+
393+
Example configuration:
394+
```ts
395+
{
396+
'perfectionist/sort-objects': [
397+
'error',
398+
{
399+
type: 'unsorted', // Do not sort metadata objects
400+
useConfigurationIf: {
401+
declarationMatchesPattern: '*metadata$',
402+
},
403+
},
404+
{
405+
type: 'alphabetical' // Fallback configuration
406+
}
407+
],
408+
}
409+
```
410+
390411
- `declarationCommentMatchesPattern` — A regexp pattern to specify which comments above the object declaration should match.
391412

392413
Example configuration:

rules/sort-objects.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ export default createEslintRule<Options, MessageId>({
426426
additionalProperties: {
427427
declarationCommentMatchesPattern: regexJsonSchema,
428428
callingFunctionNamePattern: regexJsonSchema,
429+
declarationMatchesPattern: regexJsonSchema,
429430
},
430431
}),
431432
objectDeclarations: {
@@ -516,13 +517,32 @@ function computeMatchedContextOptions({
516517
if (!objectParent) {
517518
return false
518519
}
519-
if (objectParent.type === 'VariableDeclarator' || !objectParent.name) {
520+
if (objectParent.type !== 'CallExpression' || !objectParent.name) {
520521
return false
521522
}
522-
return matches(
523+
let patternMatches = matches(
523524
objectParent.name,
524525
options.useConfigurationIf.callingFunctionNamePattern,
525526
)
527+
if (!patternMatches) {
528+
return false
529+
}
530+
}
531+
532+
if (options.useConfigurationIf.declarationMatchesPattern) {
533+
if (!objectParent) {
534+
return false
535+
}
536+
if (objectParent.type !== 'VariableDeclarator' || !objectParent.name) {
537+
return false
538+
}
539+
let patternMatches = matches(
540+
objectParent.name,
541+
options.useConfigurationIf.declarationMatchesPattern,
542+
)
543+
if (!patternMatches) {
544+
return false
545+
}
526546
}
527547

528548
return true

rules/sort-objects/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ export type Options = Partial<
4242
*/
4343
callingFunctionNamePattern?: RegexOption
4444

45+
/**
46+
* Regular expression pattern to match against the object's declaration
47+
* name. The rule is only applied to declarations with matching names.
48+
*/
49+
declarationMatchesPattern?: RegexOption
50+
4551
/**
4652
* Regular expression pattern to match against all property names. The
4753
* rule is only applied when all property names match this pattern.

test/rules/sort-objects.test.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,135 @@ describe('sort-objects', () => {
23182318
})
23192319
})
23202320

2321+
it('applies configuration when declarationMatchesPattern matches', async () => {
2322+
await valid({
2323+
options: [
2324+
{
2325+
useConfigurationIf: {
2326+
declarationMatchesPattern: '^constant$',
2327+
},
2328+
type: 'unsorted',
2329+
},
2330+
options,
2331+
],
2332+
code: dedent`
2333+
const constant = {
2334+
b,
2335+
a,
2336+
c,
2337+
}
2338+
`,
2339+
})
2340+
2341+
await valid({
2342+
options: [
2343+
{
2344+
useConfigurationIf: {
2345+
declarationMatchesPattern: '^constant$',
2346+
},
2347+
type: 'unsorted',
2348+
},
2349+
options,
2350+
],
2351+
code: dedent`
2352+
const notAConstant = {
2353+
constant: {
2354+
b,
2355+
a,
2356+
c,
2357+
}
2358+
}
2359+
`,
2360+
})
2361+
2362+
await invalid({
2363+
options: [
2364+
{
2365+
...options,
2366+
useConfigurationIf: {
2367+
declarationMatchesPattern: '^.*$',
2368+
},
2369+
type: 'unsorted',
2370+
},
2371+
],
2372+
errors: [
2373+
{
2374+
data: {
2375+
right: 'a',
2376+
left: 'b',
2377+
},
2378+
messageId: 'unexpectedObjectsOrder',
2379+
},
2380+
],
2381+
output: dedent`
2382+
func({ a: 1, b: 1 })
2383+
`,
2384+
code: dedent`
2385+
func({ b: 1, a: 1 })
2386+
`,
2387+
})
2388+
2389+
await invalid({
2390+
options: [
2391+
{
2392+
useConfigurationIf: {
2393+
declarationMatchesPattern: '^constant$',
2394+
},
2395+
type: 'unsorted',
2396+
},
2397+
options,
2398+
],
2399+
errors: [
2400+
{
2401+
data: {
2402+
right: 'a',
2403+
left: 'b',
2404+
},
2405+
messageId: 'unexpectedObjectsOrder',
2406+
},
2407+
],
2408+
output: dedent`
2409+
let notAConstant = {
2410+
a,
2411+
b,
2412+
}
2413+
`,
2414+
code: dedent`
2415+
let notAConstant = {
2416+
b,
2417+
a,
2418+
}
2419+
`,
2420+
})
2421+
2422+
await invalid({
2423+
options: [
2424+
{
2425+
...options,
2426+
useConfigurationIf: {
2427+
declarationMatchesPattern: '^.*$',
2428+
},
2429+
type: 'unsorted',
2430+
},
2431+
],
2432+
errors: [
2433+
{
2434+
data: {
2435+
right: 'a',
2436+
left: 'b',
2437+
},
2438+
messageId: 'unexpectedObjectsOrder',
2439+
},
2440+
],
2441+
output: dedent`
2442+
({ a: 1, b: 1 })
2443+
`,
2444+
code: dedent`
2445+
({ b: 1, a: 1 })
2446+
`,
2447+
})
2448+
})
2449+
23212450
it('applies configuration when declaration comment matches', async () => {
23222451
await valid({
23232452
options: [

0 commit comments

Comments
 (0)