Skip to content

Commit

Permalink
feat: add sort-sets rule
Browse files Browse the repository at this point in the history
  • Loading branch information
hugop95 committed Sep 3, 2024
1 parent 8d09b68 commit 7d4cf14
Show file tree
Hide file tree
Showing 5 changed files with 1,357 additions and 106 deletions.
235 changes: 235 additions & 0 deletions docs/content/rules/sort-sets.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
---
title: sort-sets
description: Ensure your sets are sorted. Improve readability and maintain consistent code with this ESLint rule
shortDescription: Enforce sorted sets
keywords:
- eslint
- sort set
- eslint rule
- coding standards
- code quality
- javascript linting
- set sorting
---

import CodeExample from '../../components/CodeExample.svelte'
import CodeTabs from '../../components/CodeTabs.svelte'
import { dedent } from 'ts-dedent'

Enforce sorted set values.

By keeping sets sorted, developers can quickly scan and verify the values, making the code more predictable and reducing the likelihood of errors. This practice simplifies debugging and enhances the overall clarity of the codebase.


## Try it out

<CodeExample
alphabetical={dedent`
const getProductCategories = (product) => {
let electronics = new Set([
'Drone',
'Headphones',
'Keyboard',
'Laptop',
'Monitor',
'Mouse',
'Router',
'Smartphone',
'Smartwatch',
'Tablet',
])
let accessories = new Set([
'Adapter',
'Case',
'Charger',
'Screen Protector',
'Cable',
'Battery',
'Memory Card',
])
if (electronics.has(product.name)) {
return 'Electronics'
} else if (accessories.has(product.name)) {
return 'Accessories'
}
return 'Unknown'
}
`}
lineLength={dedent`
const getProductCategories = (product) => {
let electronics = new Set([
'Smartphone',
'Smartwatch',
'Headphones',
'Keyboard',
'Monitor',
'Laptop',
'Router',
'Tablet',
'Drone',
'Mouse',
])
let accessories = new Set([
'Screen Protector',
'Memory Card',
'Adapter',
'Charger',
'Battery',
'Cable',
'Case',
])
if (electronics.has(product.name)) {
return 'Electronics'
} else if (accessories.has(product.name)) {
return 'Accessories'
}
return 'Unknown'
}
`}
client:load
lang="tsx"
initial={dedent`
const getProductCategories = (product) => {
let electronics = new Set([
'Mouse',
'Drone',
'Smartphone',
'Keyboard',
'Tablet',
'Monitor',
'Laptop',
'Smartwatch',
'Router',
'Headphones',
])
let accessories = new Set([
'Memory Card',
'Charger',
'Cable',
'Battery',
'Screen Protector',
'Case',
'Adapter',
])
if (electronics.has(product.name)) {
return 'Electronics'
} else if (accessories.has(product.name)) {
return 'Accessories'
}
return 'Unknown'
}
`}
/>

## Options

This rule accepts an options object with the following properties:

### type

<sub>default: `'alphabetical'`</sub>

Specifies the sorting method.

- `'alphabetical'` — Sort items alphabetically (e.g., “a” < “b” < “c”).
- `'natural'` — Sort items in a natural order (e.g., “item2” < “item10”).
- `'line-length'` — Sort items by the length of the code line (shorter lines first).

### order

<sub>default: `'asc'`</sub>

Determines whether the sorted items should be in ascending or descending order.

- `'asc'` — Sort items in ascending order (A to Z, 1 to 9).
- `'desc'` — Sort items in descending order (Z to A, 9 to 1).

### ignoreCase

<sub>default: `true`</sub>

Controls whether sorting should be case-sensitive or not.

- `true` — Ignore case when sorting alphabetically or naturally (e.g., “A” and “a” are the same).
- `false` — Consider case when sorting (e.g., “A” comes before “a”).


### groupKind

<sub>default: `'literals-first'`</sub>

Allows you to group set elements by their kind, determining whether spread values should come before or after literal values.

- `mixed` — Do not group set elements by their kind; spread values are sorted together with literal values.
- `literals-first` — Group all literal values before spread values.
- `spread-first` — Group all spread values before literal values.


## Usage

<CodeTabs
code={[
{
source: dedent`
// eslint.config.js
import perfectionist from 'eslint-plugin-perfectionist'
export default [
{
plugins: {
perfectionist,
},
rules: {
'perfectionist/sort-sets': [
'error',
{
type: 'alphabetical',
order: 'asc',
ignoreCase: true,
groupKind: 'literals-first',
},
],
},
},
]
`,
name: 'Flat Config',
value: 'flat',
},
{
source: dedent`
// .eslintrc.js
module.exports = {
plugins: [
'perfectionist',
],
rules: {
'perfectionist/sort-sets': [
'error',
{
type: 'alphabetical',
order: 'asc',
ignoreCase: true,
groupKind: 'literals-first',
},
],
},
}
`,
name: 'Legacy Config',
value: 'legacy',
},
]}
type="config-type"
client:load
lang="ts"
/>

## Version

This rule was introduced in [v3.4.0](https://github.com/azat-io/eslint-plugin-perfectionist/releases/tag/v3.4.0).

## Resources

- [Rule source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/rules/sort-sets.ts)
- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-sets.test.ts)
2 changes: 2 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import sortExports from './rules/sort-exports'
import sortObjects from './rules/sort-objects'
import sortEnums from './rules/sort-enums'
import sortMaps from './rules/sort-maps'
import sortSets from './rules/sort-sets'

interface BaseOptions {
type: 'alphabetical' | 'line-length' | 'natural'
Expand Down Expand Up @@ -54,6 +55,7 @@ let plugin = {
'sort-exports': sortExports,
'sort-objects': sortObjects,
'sort-enums': sortEnums,
'sort-sets': sortSets,
'sort-maps': sortMaps,
},
name,
Expand Down
Loading

0 comments on commit 7d4cf14

Please sign in to comment.