### Example Configuration for customGroups Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-interfaces.mdx Illustrates how to configure customGroups to place properties starting with 'id' and 'name' at the top, and metadata properties at the bottom. This example also shows how to group optional multiline properties. ```typescript interface User { id: string // top name: string // top age: number // unknown isAdmin: boolean // unknown lastUpdated_metadata: Date // bottom localization?: { // optional-multiline-member // Stuff about localization } version_metadata: string // bottom } ``` ```javascript { groups: [ 'top', 'unknown', ['optional-multiline-member', 'bottom'] ], customGroups: [ { groupName: 'top', selector: 'property', elementNamePattern: '^(?:id|name)$' }, { groupName: 'bottom', selector: 'property', elementNamePattern: '.+_metadata$' } ] } ``` -------------------------------- ### Usage Examples Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-sets.mdx Examples of how to configure the 'sort-sets' rule with custom groups in ESLint configuration files. ```APIDOC ## Usage Examples ### Flat Config ```javascript // eslint.config.js import perfectionist from 'eslint-plugin-perfectionist' export default [ { plugins: { perfectionist, }, rules: { 'perfectionist/sort-sets': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', useConfigurationIf: {}, groups: ['literal'], customGroups: [], }, ], }, }, ] ``` ### Legacy Config ```javascript // .eslintrc.js module.exports = { plugins: [ 'perfectionist', ], rules: { 'perfectionist/sort-sets': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', useConfigurationIf: {}, groups: ['literal'], customGroups: [], }, ], }, } ``` ``` -------------------------------- ### Example Object Keys Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx Demonstrates an example object with keys that can be categorized by the 'groups' option. ```typescript let user = { firstName: "John", // unknown lastName: "Doe", // unknown username: "john_doe", // unknown job: { // multiline-member // Stuff about job }, localization: { // multiline-member // Stuff about localization } } ``` -------------------------------- ### Install Project Dependencies with pnpm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/contributing.md Install all necessary project dependencies using the pnpm package manager after cloning the repository. ```sh pnpm install ``` -------------------------------- ### Example Configuration for Sorting Import Attributes Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-import-attributes.mdx An example configuration demonstrating how to sort import attributes, including custom groups for RGB colors and a fallback configuration. ```json { 'perfectionist/sort-import-attributes': [ 'error', { groups: ['r', 'g', 'b'], // Sort colors by RGB customGroups: [ { elementNamePattern: '^r$', groupName: 'r', }, { elementNamePattern: '^g$', groupName: 'g', }, { elementNamePattern: '^b$', groupName: 'b', }, ], useConfigurationIf: { allNamesMatchPattern: '^[rgb]$', }, }, { type: 'alphabetical' // Fallback configuration } ], } ``` -------------------------------- ### Flat Config Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-exports.mdx Example of configuring the 'sort-exports' rule with customGroups in a flat ESLint configuration file. ```javascript // eslint.config.js import perfectionist from 'eslint-plugin-perfectionist' export default [ { plugins: { perfectionist, }, rules: { 'perfectionist/sort-exports': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', groups: [], customGroups: [], }, ], }, }, ] ``` -------------------------------- ### Example ESLint Configuration with Custom Groups Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx Illustrates how to configure `groups` and `customGroups` to sort properties. This example places properties starting with 'id' and 'name' at the top, metadata properties at the bottom, and others in the middle. ```javascript { groups: [ 'top', 'unknown', ['multiline-member', 'bottom'] ], customGroups: [ { groupName: 'top', selector: 'property', elementNamePattern: '^(?:id|name)$' }, { groupName: 'bottom', selector: 'property', elementNamePattern: '.+_metadata$' } ] } ``` -------------------------------- ### Recommended Custom Configuration Usage Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/configs/recommended-custom.mdx This section demonstrates how to integrate the 'recommended-custom' ESLint configuration into your project, allowing for custom sorting alphabets. It includes examples for both Flat Config and Legacy Config setups. ```APIDOC ## Recommended Custom Configuration Usage This configuration allows you to define your own custom order for sorting elements in your codebase. You must provide an `alphabet` option in the `perfectionist` settings object or for each rule individually. ### Flat Config Example ```javascript // eslint.config.js import { Alphabet } from 'eslint-plugin-perfectionist/alphabet' import perfectionist from 'eslint-plugin-perfectionist' import naturalCompare from 'natural-compare-lite'; const myCustomAlphabet = Alphabet .generateRecommendedAlphabet() .sortingBy((a, b) => naturalCompare(a, b)) .getCharacters(); export default [ { ...perfectionist.configs['recommended-custom'], settings: { perfectionist: { alphabet: myCustomAlphabet } } } ] ``` ### Legacy Config Example ```javascript // .eslintrc.js import { Alphabet } from 'eslint-plugin-perfectionist/alphabet' import perfectionist from 'eslint-plugin-perfectionist' import naturalCompare from 'natural-compare-lite'; const myCustomAlphabet = Alphabet .generateRecommendedAlphabet() .sortingBy((a, b) => naturalCompare(a, b)) .getCharacters(); module.exports = { extends: [ 'plugin:perfectionist/recommended-custom-legacy', ], settings: { perfectionist: { alphabet: myCustomAlphabet } } } ``` ``` -------------------------------- ### Legacy Config Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-exports.mdx Example of configuring the 'sort-exports' rule with customGroups in a legacy ESLint configuration file. ```javascript // .eslintrc.js module.exports = { plugins: [ 'perfectionist', ], rules: { 'perfectionist/sort-exports': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', groups: [], customGroups: [], }, ], }, } ``` -------------------------------- ### Import sorting examples Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-imports.mdx Provides examples of various import types, categorized by their intended group and importance. This helps understand the sorting hierarchy. ```typescript // 'value-builtin' - Node.js Built-in Modules import path from 'path' ``` ```typescript // 'value-external' - External modules installed in the project import axios from 'axios' ``` ```typescript // 'value-internal' - Your internal modules import Button from '~/components/Button' ``` ```typescript // 'value-parent' - Modules from parent directory import formatNumber from '../utils/format-number' ``` ```typescript // 'value-subpath' - Node.js subpath imports import subpathContent from '#subpathModule' ``` ```typescript // 'value-sibling' - Modules from the same directory import config from './config' ``` ```typescript // 'value-side-effect' - Side effect imports import './set-production-env.js' ``` ```typescript // value-side-effect-style - Side effect style imports import './styles.scss' ``` ```typescript // 'value-index' - Main file from the current directory import main from '.' ``` ```typescript // 'value-style' - Styles import styles from './index.module.css' ``` ```typescript // 'type-external' - TypeScript type imports import type { FC } from 'react' ``` ```typescript // 'named-type-builtin' - TypeScript type imports from Built-in Modules import type { Server } from 'http' ``` ```typescript // 'named-type-internal' - TypeScript type imports from your internal modules import type { User } from '~/users' ``` ```typescript // 'named-type-parent' - TypeScript type imports from parent directory import type { InputProps } from '../Input' ``` ```typescript // 'named-type-sibling' - TypeScript type imports from the same directory import type { Details } from './data' ``` ```typescript // 'named-type-index' - TypeScript type imports from main directory file import type { BaseOptions } from './index.d.ts' ``` ```typescript // 'value-ts-equals-import' - TypeScript import-equals imports import NotFoundError = ErrorsNamespace.NotFoundError ``` -------------------------------- ### Legacy Config Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Example of configuring the 'sort-intersection-types' rule using legacy .eslintrc.js format. ```javascript // .eslintrc.js module.exports = { plugins: [ 'perfectionist', ], rules: { 'perfectionist/sort-intersection-types': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', groups: [], customGroups: [], }, ], }, } ``` -------------------------------- ### Example Configuration for sort-switch-case rule Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-switch-case.mdx This example demonstrates how to configure the sort-switch-case rule using both Flat Config and Legacy Config formats. It enforces alphabetical sorting in ascending order with specific fallback and character handling. ```javascript import perfectionist from 'eslint-plugin-perfectionist' export default [ { plugins: { perfectionist, }, rules: { 'perfectionist/sort-switch-case': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', }, ], }, }, ] ``` ```javascript // .eslintrc.js module.exports = { plugins: [ 'perfectionist', ], rules: { 'perfectionist/sort-switch-case': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', }, ], }, } ``` -------------------------------- ### Install ESLint with bun Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install ESLint version 8.45.0 or greater using bun. This command adds ESLint as a development dependency. ```bash bun install --dev eslint ``` -------------------------------- ### Flat Config Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Example of configuring the 'sort-intersection-types' rule using flat config format in eslint.config.js. ```javascript // eslint.config.js import perfectionist from 'eslint-plugin-perfectionist' export default [ { plugins: { perfectionist, }, rules: { 'perfectionist/sort-intersection-types': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', useConfigurationIf: {}, groups: [], customGroups: [], }, ], }, }, ] ``` -------------------------------- ### Partition by Newline Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-exports.mdx This example demonstrates how the 'partitionByNewLine' option preserves the order of exports separated by empty lines, treating each block as an independent group. ```typescript // Group 1 export * from "./atoms"; export * from "./organisms"; export * from "./shared"; // Group 2 export { Named } from './folder'; export { AnotherNamed } from './second-folder'; ``` -------------------------------- ### Example of Sorted Decorators (Alphabetical) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-decorators.mdx This example demonstrates decorators sorted alphabetically. It includes class decorators and property decorators. ```tsx @ApiDescription('Create a new user') @Authenticated() @Controller() @Post('/users') class CreateUserController { @AutoInjected() @NotNull() userService: UserService; @IsBoolean() @NotNull() accessor disableController: boolean; @ApiError({ status: 400, description: 'Bad request' }) @ApiResponse({ status: 200, description: 'User created successfully' }) createUser( @Body() @IsNotEmpty() @ValidateNested() createUserDto: CreateUserDto ): UserDto { // ... } } ``` -------------------------------- ### Install ESLint with pnpm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install ESLint version 8.45.0 or greater using pnpm. This command adds ESLint as a development dependency. ```bash pnpm add --save-dev eslint ``` -------------------------------- ### Install ESLint with npm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install ESLint version 8.45.0 or greater using npm. Ensure you have the correct version for the plugin to function properly. ```bash npm install --save-dev eslint ``` -------------------------------- ### Example of sorted module members (line length) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-modules.mdx Demonstrates the 'sort-modules' rule enforcing order based on line length. This example shows how types and interfaces might be ordered differently compared to alphabetical sorting. ```tsx enum CacheType { ALWAYS = 'ALWAYS', NEVER = 'NEVER', } export type FindAllUsersOutput = FindUserOutput[] export interface FindUserInput { id: string cache: CacheType } export type FindAllUsersInput = { ids: string[] cache: CacheType } export type FindUserOutput = { id: string name: string age: number } class Cache { // Some logic } export function findUser(input: FindUserInput): FindUserOutput { assertInputIsCorrect(input) return _findUserByIds([input.id])[0] } export function findAllUsers(input: FindAllUsersInput): FindAllUsersOutput { assertInputIsCorrect(input) return _findUserByIds(input.ids) } function assertInputIsCorrect(input: FindUserInput | FindAllUsersInput): void { // Some logic } ``` -------------------------------- ### Example of unsorted object keys Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx This example demonstrates an object with keys in an unsorted order. Use this rule to enforce consistent sorting. ```tsx const event = { description: 'Annual conference discussing the latest in technology.', organizer: { email: 'charlie.brown@protonmail.com', phone: '555-1234', name: 'Charlie Brown', }, title: 'Tech Conference 2023', schedule: [ { speaker: null, time: '09:00 AM', activity: 'Registration', }, { speaker: 'Jane Doe', time: '10:00 AM', activity: 'Opening Keynote', }, { activity: 'Tech Trends 2023', time: '11:00 AM', speaker: 'Alice Johnson', } ], location: { state: 'CA', address: '123 Tech Street', city: 'San Francisco', postalCode: '94103', country: 'USA', venue: 'Tech Center', }, date: new Date('2023-09-15'), status: 'upcoming', } ``` -------------------------------- ### Interface Sorting Examples Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-interfaces.mdx Demonstrates different sorting methods for TypeScript interfaces: alphabetical, by line length, and initial unsorted state. Use these examples to visualize the rule's effect. ```tsx interface Address { apartmentNumber?: string city: string country: string postalCode: string street: string } interface User { address: Address email: string firstName: string id: string login: string phoneNumber?: string roles: string[] } interface Project { budget: number description: string id: string name: string projectTeamMembers: User[] startDate: Date status: string } ``` ```tsx interface Address { apartmentNumber?: string postalCode: string country: string street: string city: string } interface User { phoneNumber?: string firstName: string address: Address roles: string[] email: string login: string id: string } interface Project { projectTeamMembers: User[] description: string startDate: Date budget: number status: string name: string id: string } ``` ```tsx interface Address { street: string city: string country: string postalCode: string apartmentNumber?: string } interface User { firstName: string email: string roles: string[] login: string phoneNumber?: string address: Address id: string } interface Project { startDate: Date budget: number description: string id: string projectTeamMembers: User[] name: string status: string } ``` -------------------------------- ### Example of object keys sorted by line length Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx This example demonstrates an object with keys sorted by the length of their code lines, with shorter lines appearing first. This sorting method can be configured using the 'type' option. ```tsx const event = { schedule: [ { activity: 'Registration', time: '09:00 AM', speaker: null, }, { activity: 'Opening Keynote', speaker: 'Jane Doe', time: '10:00 AM', }, { activity: 'Tech Trends 2023', speaker: 'Alice Johnson', time: '11:00 AM', } ], location: { address: '123 Tech Street', city: 'San Francisco', venue: 'Tech Center', postalCode: '94103', country: 'USA', state: 'CA', }, organizer: { email: 'charlie.brown@protonmail.com', name: 'Charlie Brown', phone: '555-1234', }, description: 'Annual conference discussing the latest in technology.', title: 'Tech Conference 2023', date: new Date('2023-09-15'), status: 'upcoming', } ``` -------------------------------- ### Install ESLint with yarn Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install ESLint version 8.45.0 or greater using yarn. This command adds ESLint as a development dependency. ```bash yarn add --dev eslint ``` -------------------------------- ### Example of Sorted Decorators (Line Length) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-decorators.mdx This example shows decorators sorted by line length, with shorter lines appearing first. It includes class and property decorators. ```tsx @ApiDescription('Create a new user') @Authenticated() @Post('/users') @Controller() class CreateUserController { @AutoInjected() @NotNull() userService: UserService; @IsBoolean() @NotNull() accessor disableController: boolean; @ApiResponse({ status: 200, description: 'User created successfully' }) @ApiError({ status: 400, description: 'Bad request' }) createUser( @ValidateNested() @IsNotEmpty() @Body() createUserDto: CreateUserDto ): UserDto { // ... } } ``` -------------------------------- ### Conditional Configuration Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Shows how to apply specific sorting rules for intersection types that match a pattern. This example sorts colors by RGB, with a fallback to alphabetical sorting. ```typescript { 'perfectionist/sort-intersection-types': [ 'error', { groups: ['r', 'g', 'b'], // Sort colors by RGB customGroups: [ { elementNamePattern: '^r$', groupName: 'r', }, { elementNamePattern: '^g$', groupName: 'g', }, { elementNamePattern: '^b$', groupName: 'b', }, ], useConfigurationIf: { allNamesMatchPattern: '^[rgb]$', }, }, { type: 'alphabetical' // Fallback configuration } ], } ``` -------------------------------- ### Example Map Initialization (Unsorted) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-maps.mdx Shows Map objects initialized with elements in an unsorted order. This example is useful for demonstrating how the rule would flag unsorted maps when the 'unsorted' type is not explicitly used or when other sorting types are configured. ```tsx const products = new Map([ ['monitor', { name: 'Monitor', price: 200 }], ['laptop', { name: 'Laptop', price: 1000 }], ['mouse', { name: 'Mouse', price: 25 }], ['keyboard', { name: 'Keyboard', price: 50 }] ]) const categories = new Map([ ['electronics', { name: 'Electronics' }], ['furniture', { name: 'Furniture' }], ['clothing', { name: 'Clothing' }], ['accessories', { name: 'Accessories' }] ]) ``` -------------------------------- ### Example of Sorted JSX Props Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-jsx-props.mdx Demonstrates how props are sorted alphabetically, by line length, and in their initial unsorted state. This example showcases the rule's ability to enforce consistent prop ordering. ```tsx const AuthForm = ({ handleSubmit, setUsername, t }) => (
) ``` ```tsx const AuthForm = ({ handleSubmit, setUsername, t }) => ( ) ``` ```tsx const AuthForm = ({ handleSubmit, setUsername, t }) => ( ) ``` -------------------------------- ### Example of group matching for a class Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-modules.mdx Demonstrates how a class declaration is matched against different group configurations, prioritizing specificity. ```typescript export default class {} ``` -------------------------------- ### Example of a TypeScript type import Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-imports.mdx Demonstrates a TypeScript type import. This can be matched by several groups, including 'named-type' and 'type'. ```typescript import type { FC } from 'react' ``` -------------------------------- ### Example of Unsorted Exports Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-exports.mdx Shows the initial state of exports before sorting is applied. This serves as a baseline for understanding the rule's impact. ```tsx export { MainContent } from './components/MainContent' export { calculateAge } from './utils/calculateAge' export { Sidebar } from './components/Sidebar' export { deleteUser } from './actions/deleteUser' export { Footer } from './components/Footer' export { debounce } from './utils/debounce' export { generateUUID } from './utils/generateUUID' export { formatDate } from './utils/formatDate' export { updateUser } from './actions/updateUser' export { fetchUser } from './actions/fetchUser' export { Header } from './components/Header' export { createUser } from './actions/createUser' export { parseQueryString } from './utils/parseQueryString' ``` -------------------------------- ### Demonstrate Import Sorting Options Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-imports.mdx Shows how imports are sorted using alphabetical, line-length, and initial configurations. This example is useful for visualizing the rule's behavior with different sorting strategies. ```tsx import type { Response, Request } from 'express' import bodyParser from 'body-parser' import express from 'express' import session from 'express-session' import defaultsDeep from 'lodash/defaultsDeep' import map from 'lodash/map' import mongoose from 'mongoose' import fs from 'node:fs/promises' import path from 'node:path' import passport from 'passport' import initializePassport from '~/config/passport' import logger from '~/middleware/logger' import User from '~/models/User' import authRoutes from '~/routes/auth' import dbConfig from './db' ``` ```tsx import type { Response, Request } from 'express' import defaultsDeep from 'lodash/defaultsDeep' import session from 'express-session' import bodyParser from 'body-parser' import fs from 'node:fs/promises' import mongoose from 'mongoose' import passport from 'passport' import express from 'express' import path from 'node:path' import map from 'lodash/map' import initializePassport from '~/config/passport' import logger from '~/middleware/logger' import authRoutes from '~/routes/auth' import User from '~/models/User' import dbConfig from './db' ``` ```tsx import User from '~/models/User' import bodyParser from 'body-parser' import initializePassport from '~/config/passport' import mongoose from 'mongoose' import express from 'express' import type { Response, Request } from 'express' import passport from 'passport' import path from 'node:path' import defaultsDeep from 'lodash/defaultsDeep' import logger from '~/middleware/logger' import map from 'lodash/map' import dbConfig from './db' import session from 'express-session' import fs from 'node:fs/promises' import authRoutes from '~/routes/auth' ``` -------------------------------- ### Example Configuration for Custom Groups Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-object-types.mdx Illustrates how to configure ESLint Perfectionist to use custom groups for sorting object properties. This example places properties starting with 'id' and 'name' at the top, metadata properties at the bottom, and others in the middle. ```typescript { groups: [ 'top', 'unknown', ['optional-multiline-member', 'bottom'] ], customGroups: [ { groupName: 'top', selector: 'property', elementNamePattern: '^(?:id|name)$' }, { groupName: 'bottom', selector: 'property', elementNamePattern: '.+_metadata$' } ] } ``` -------------------------------- ### Example Type Definition with All Selectors Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Demonstrates the usage of all predefined selectors for type grouping. Ensure all necessary types are imported or defined before use. ```typescript type Example = // 'conditional' — Conditional types. & (A extends B ? C : D) // 'function' — Function types. & ((arg: T) => U) // 'import' — Imported types. & import('module').Type // 'intersection' — Intersection types. & (A & B) // 'keyword' — Keyword types. & any // 'literal' — Literal types. & 'literal' & 42 // 'named' — Named types. & SomeType & AnotherType // 'object' — Object types. & { a: string; b: number; } // 'operator' — Operator types. & keyof T // 'tuple' — Tuple types. & [string, number] // 'union' — Union types. & (A | B) // 'nullish' — Nullish types. & null & undefined; ``` -------------------------------- ### Configure ESLint Perfectionist with Flat Config Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-object-types.mdx Use this configuration in `eslint.config.js` for modern ESLint setups. Ensure the plugin is installed and imported. ```javascript // eslint.config.js import perfectionist from 'eslint-plugin-perfectionist' export default [ { plugins: { perfectionist, }, rules: { 'perfectionist/sort-object-types': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', sortBy: 'name', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', useConfigurationIf: {}, groups: [], customGroups: [], }, ], }, }, ] ``` -------------------------------- ### Organize Object Keys with Comments Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx This example demonstrates how to use comments to logically group object keys. When `partitionByComment` is true, comments act as delimiters, creating distinct partitions for related properties. ```javascript const user = { // Group 1 firstName: 'John', lastName: 'Doe', // Group 2 age: 30, birthDate: '1990-01-01', // Group 3 email: 'john.doe@example.com', phone: '555-555-5555' }; ``` -------------------------------- ### Configure ESLint Perfectionist with Legacy Config Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-object-types.mdx Use this configuration in `.eslintrc.js` for older ESLint setups. Ensure the plugin is installed and listed in the plugins array. ```javascript // .eslintrc.js module.exports = { plugins: [ 'perfectionist', ], rules: { 'perfectionist/sort-object-types': [ 'error', { type: 'alphabetical', order: 'asc', fallbackSort: { type: 'unsorted' }, ignoreCase: true, specialCharacters: 'keep', sortBy: 'name', partitionByComment: false, partitionByNewLine: false, newlinesBetween: 'ignore', newlinesInside: 'ignore', useConfigurationIf: {}, groups: [], customGroups: [], }, ], }, } ``` -------------------------------- ### Example: Grouping Attributes with Custom Settings Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-export-attributes.mdx This configuration example shows how to define custom attribute groups. 'type-attrs' is defined to match attributes starting with 'type', and a newline is enforced between this group and any subsequent groups. The global `newlinesBetween` is set to 1, but overridden to 0 for the specific group between 'a' and 'b'. ```typescript { groups: ['type-attrs', 'unknown'], customGroups: [ { elementNamePattern: '^type', groupName: 'type-attrs' }, ], newlinesBetween: 1 } ``` ```typescript { newlinesBetween: 1, groups: [ 'a', { newlinesBetween: 0 }, // Overrides the global newlinesBetween option 'b', ] } ``` -------------------------------- ### Configure ESLint with Recommended Natural Flat Config Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/configs/recommended-natural.mdx Use this snippet to integrate the 'recommended-natural' configuration into your ESLint setup using the flat config format. Ensure 'eslint-plugin-perfectionist' is installed. ```javascript import perfectionist from 'eslint-plugin-perfectionist' export default [ perfectionist.configs['recommended-natural'], ] ``` -------------------------------- ### Example Usage of partitionByNewLine Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-sets.mdx Demonstrates how `partitionByNewLine` can be used to maintain the order of logically separated groups of members within a Set, using empty lines as delimiters. ```typescript let items = new Set([ // Group 1 'Drone', 'Keyboard', 'Mouse', 'Smartphone', // Group 2 'Laptop', 'Monitor', 'Smartwatch', 'Tablet', // Group 3 'Headphones', 'Router', ]) ``` -------------------------------- ### Example Map Initialization (Line Length) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-maps.mdx Illustrates initializing Map objects where elements are sorted by the length of their code lines. This can be useful for organizing entries based on their complexity or verbosity. ```tsx const products = new Map([ ['keyboard', { name: 'Keyboard', price: 50 }], ['monitor', { name: 'Monitor', price: 200 }], ['laptop', { name: 'Laptop', price: 1000 }], ['mouse', { name: 'Mouse', price: 25 }] ]) const categories = new Map([ ['accessories', { name: 'Accessories' }], ['electronics', { name: 'Electronics' }], ['furniture', { name: 'Furniture' }], ['clothing', { name: 'Clothing' }] ]) ``` -------------------------------- ### Example: Adding a Custom Group for Callbacks Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-jsx-props.mdx Illustrates how to add a custom group named 'callback' to the ESLint configuration, targeting props that start with 'on+'. This custom group is then added to the 'groups' array. ```javascript { groups: [ 'multiline-prop', 'unknown', 'shorthand-prop', 'callback' // [!code ++] ], customGroups: [ // [!code ++] { groupName: 'callback', // [!code ++] elementNamePattern: '^on.+' // [!code ++] } // [!code ++] ] // [!code ++] } ``` -------------------------------- ### Partitioning Options Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx Configure how to partition elements into logical groups based on comments, newlines, or computed keys. ```APIDOC ## Partitioning Options ### `partitionByComment` Enables the use of comments to separate the keys of objects into logical groups. **Type:** `boolean | RegExpPattern | RegExpPattern[] | { block: boolean | RegExpPattern | RegExpPattern[]; line: boolean | RegExpPattern | RegExpPattern[] }` **Default:** `false` ### `partitionByNewLine` When `true`, the rule will not sort the object's keys if there is an empty line between them. This helps maintain the defined order of logically separated groups of keys. **Default:** `false` ### `partitionByComputedKey` Enables the use of computed keys to separate the keys of objects into logical groups. **Default:** `false` ``` -------------------------------- ### Example Array Partitioning with Newlines Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-arrays.mdx Demonstrates how an array can be partitioned into logical groups using empty lines when `partitionByNewLine` is enabled. Each group is sorted independently, preserving the order within the group. ```typescript const ELECTRONICS = [ // Group 1 'Drone', 'Keyboard', 'Mouse', 'Smartphone', // Group 2 'Laptop', 'Monitor', 'Smartwatch', 'Tablet', // Group 3 'Headphones', 'Router', ] as const ``` -------------------------------- ### Example Union Type Partitioning with Comments Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-union-types.mdx Demonstrates how comments and empty lines can be used to partition union types into logical groups, preserving their order. This is applicable when `partitionByNewLine` is enabled. ```typescript type CarBrand = // Group 1 Fiat | Honda | // Group 2 Ferrari | // Group 3 Chevrolet | Ford ``` -------------------------------- ### Define User Type for Sorting Example Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-object-types.mdx Example TypeScript type definition used to illustrate sorting configurations. ```typescript type User = { createdAt: Date lastLoginAt: Date _id: ObjectId groupId: ObjectId city: string } ``` -------------------------------- ### Example Map Initialization (Alphabetical) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-maps.mdx Demonstrates initializing Map objects with elements sorted alphabetically. This is the default behavior when the rule is applied without specific options. ```tsx const products = new Map([ ['keyboard', { name: 'Keyboard', price: 50 }], ['laptop', { name: 'Laptop', price: 1000 }], ['monitor', { name: 'Monitor', price: 200 }], ['mouse', { name: 'Mouse', price: 25 }] ]) const categories = new Map([ ['accessories', { name: 'Accessories' }], ['clothing', { name: 'Clothing' }], ['electronics', { name: 'Electronics' }], ['furniture', { name: 'Furniture' }] ]) ``` -------------------------------- ### Example Type Definition with All Selectors Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-union-types.mdx Demonstrates the usage of all predefined selectors for organizing a complex type definition. Ensure all necessary types (A, B, C, D, T, U, SomeType, AnotherType) are defined elsewhere. ```typescript type Example = // 'conditional' — Conditional types. | (A extends B ? C : D) // 'function' — Function types. | ((arg: T) => U) // 'import' — Imported types. | import('module').Type // 'intersection' — Intersection types. | (A & B) // 'keyword' — Keyword types. | any // 'literal' — Literal types. | 'literal' | 42 // 'named' — Named types. | SomeType | AnotherType // 'object' — Object types. | { a: string; b: number; } // 'operator' — Operator types. | keyof T // 'tuple' — Tuple types. | [string, number] // 'union' — Union types. | (A | B) // 'nullish' — Nullish types. | null | undefined; ``` -------------------------------- ### Example of alphabetically sorted object keys Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-objects.mdx This example shows an object with keys sorted alphabetically. This is the default behavior of the sort-objects rule. ```tsx const event = { date: new Date('2023-09-15'), description: 'Annual conference discussing the latest in technology.', location: { address: '123 Tech Street', city: 'San Francisco', country: 'USA', postalCode: '94103', state: 'CA', venue: 'Tech Center', }, organizer: { email: 'charlie.brown@protonmail.com', name: 'Charlie Brown', phone: '555-1234', }, schedule: [ { activity: 'Registration', speaker: null, time: '09:00 AM', }, { activity: 'Opening Keynote', speaker: 'Jane Doe', time: '10:00 AM', }, { activity: 'Tech Trends 2023', speaker: 'Alice Johnson', time: '11:00 AM', } ], status: 'upcoming', title: 'Tech Conference 2023', } ``` -------------------------------- ### Install ESLint Plugin Perfectionist with bun Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install the ESLint Plugin Perfectionist using bun. This adds the plugin as a development dependency. ```bash bun install --dev eslint-plugin-perfectionist ``` -------------------------------- ### Install ESLint Plugin Perfectionist with yarn Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install the ESLint Plugin Perfectionist using yarn. This adds the plugin as a development dependency. ```bash yarn add --dev eslint-plugin-perfectionist ``` -------------------------------- ### Example Imports After Custom Alphabet Sorting Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-imports.mdx Illustrates the import order resulting from a custom alphabet configuration, where subpaths are sorted before hyphenated packages. ```ts import { Linter } from "eslint"; import { globalIgnores } from "eslint/config"; import { FlatConfigComposer } from "eslint-flat-config-utils"; ``` -------------------------------- ### Install ESLint Plugin Perfectionist with pnpm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install the ESLint Plugin Perfectionist using pnpm. This adds the plugin as a development dependency. ```bash pnpm add --save-dev eslint-plugin-perfectionist ``` -------------------------------- ### Install ESLint Plugin Perfectionist with npm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/guide/getting-started.mdx Install the ESLint Plugin Perfectionist using npm. This adds the plugin as a development dependency. ```bash npm install --save-dev eslint-plugin-perfectionist ``` -------------------------------- ### Example of Named Exports (Initial Unsorted) Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-named-exports.mdx Shows the initial state of named exports before sorting is applied. This serves as a baseline for demonstrating the rule's effect. ```tsx export { throttle, calculateAge, formatDate, generateUUID, debounce, parseQueryString, } from './utils' export { isPhoneNumberValid, parseDate, isEmpty, isEqual, capitalizeFirstLetter, isDateValid, isEmailValid, generateRandomString, } from './helpers' ``` -------------------------------- ### Example Usage of sort-arrays Rule Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-arrays.mdx Demonstrates how arrays like ELECTRONICS and ACCESSORIES are sorted alphabetically by default. Use the `useConfigurationIf` option to target specific arrays. ```tsx const ELECTRONICS = [ 'Drone', 'Headphones', 'Keyboard', 'Laptop', 'Monitor', 'Mouse', 'Router', 'Smartphone', 'Smartwatch', 'Tablet', ] as const const ACCESSORIES = [ 'Adapter', 'Battery', 'Cable', 'Case', 'Charger', 'Memory Card', 'Screen Protector', ] as const ``` ```tsx const ELECTRONICS = [ 'Smartphone', 'Smartwatch', 'Headphones', 'Keyboard', 'Monitor', 'Laptop', 'Router', 'Tablet', 'Drone', 'Mouse', ] as const const ACCESSORIES = [ 'Screen Protector', 'Memory Card', 'Adapter', 'Charger', 'Battery', 'Cable', 'Case', ] as const ``` ```tsx const ELECTRONICS = [ 'Mouse', 'Drone', 'Smartphone', 'Keyboard', 'Tablet', 'Monitor', 'Laptop', 'Smartwatch', 'Router', 'Headphones', ] as const const ACCESSORIES = [ 'Memory Card', 'Charger', 'Cable', 'Battery', 'Screen Protector', 'Case', 'Adapter', ] as const ``` -------------------------------- ### Example Intersection Type Partitioning Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Demonstrates how empty lines can partition intersection types into logical groups when `partitionByNewLine` is enabled. Each group is sorted independently. ```typescript type Employee = // Group 1 FirstName & LastName & // Group 2 Age & // Group 3 Address & Country ``` -------------------------------- ### Run Project Tests with pnpm Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/contributing.md Execute the project's test suite using the pnpm command to ensure everything is functioning correctly. ```sh pnpm test ``` -------------------------------- ### Example of Sorted Intersection Types Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-intersection-types.mdx Demonstrates how intersection types are sorted alphabetically by default. This example shows the expected output after the rule is applied. ```tsx type Employee = Address & ContactInfo & PersonalInfo & { employeeId: string isActive: boolean } type TeamMember = Employee & { teamId: string name: string } ``` -------------------------------- ### Example of Unsorted Decorators Source: https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/docs/content/rules/sort-decorators.mdx This example displays decorators in an unsorted order, which would trigger linting errors if the rule is configured to enforce sorting. ```tsx @Post('/users') @ApiDescription('Create a new user') @Authenticated() @Controller() class CreateUserController { @NotNull() @AutoInjected() userService: UserService; @NotNull() @IsBoolean() accessor disableController: boolean; @ApiError({ status: 400, description: 'Bad request' }) @ApiResponse({ status: 200, description: 'User created successfully' }) createUser( @IsNotEmpty() @ValidateNested() @Body() createUserDto: CreateUserDto ): UserDto { // ... } } ```