From ebe5b31f06bd106172e9d00096bb9a2aaced3326 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sat, 30 Nov 2024 00:54:06 -0700 Subject: [PATCH] feat(eslint-config): allow perfectionist to be overridden or disabled (#693) --- .changeset/nice-avocados-rush.md | 6 ++ .../src/configs/perfectionist.ts | 86 ++++++++++++------- packages/eslint-config/src/define-config.ts | 12 ++- packages/eslint-config/src/options.ts | 32 +++++++ 4 files changed, 105 insertions(+), 31 deletions(-) create mode 100644 .changeset/nice-avocados-rush.md diff --git a/.changeset/nice-avocados-rush.md b/.changeset/nice-avocados-rush.md new file mode 100644 index 00000000..c995bb8a --- /dev/null +++ b/.changeset/nice-avocados-rush.md @@ -0,0 +1,6 @@ +--- +"@bfra.me/eslint-config": minor +--- + +Add options to override or disable the Perfectionist config. + \ No newline at end of file diff --git a/packages/eslint-config/src/configs/perfectionist.ts b/packages/eslint-config/src/configs/perfectionist.ts index bb2fee3d..9cb33b5e 100644 --- a/packages/eslint-config/src/configs/perfectionist.ts +++ b/packages/eslint-config/src/configs/perfectionist.ts @@ -1,12 +1,28 @@ import type {Config} from '../config' +import type {Flatten, OptionsIsInEditor, OptionsOverrides, OptionsPerfectionist} from '../options' import {perfectionist as pluginPerfectionist} from '../plugins' +/** + * Represents the combined options for the Perfectionist ESLint plugin, including options for editor integration, overrides, and the Perfectionist plugin itself. + */ +export type PerfectionistOptions = Flatten< + OptionsIsInEditor & OptionsOverrides & OptionsPerfectionist +> + /** * Perfectionist plugin for sorting items and properties. * * @see https://github.com/azat-io/eslint-plugin-perfectionist */ -export async function perfectionist(): Promise { +export async function perfectionist(options: PerfectionistOptions = {}): Promise { + const { + isInEditor = false, + overrides = {}, + sortExports = true, + sortImports = true, + sortNamedExports = true, + sortNamedImports = true, + } = options return [ { name: '@bfra.me/perfectionist', @@ -14,37 +30,47 @@ export async function perfectionist(): Promise { perfectionist: pluginPerfectionist as any, }, rules: { - 'perfectionist/sort-named-exports': [ - 'error', - {groupKind: 'values-first', order: 'asc', type: 'natural'}, - ], + ...(sortNamedExports && { + 'perfectionist/sort-named-exports': [ + isInEditor ? 'warn' : 'error', + {groupKind: 'values-first', type: 'natural'}, + ], + }), + + ...(sortNamedImports && { + 'perfectionist/sort-named-imports': [ + isInEditor ? 'warn' : 'error', + {groupKind: 'values-first', type: 'natural'}, + ], + }), + + ...(sortExports && { + 'perfectionist/sort-exports': [isInEditor ? 'warn' : 'error', {type: 'natural'}], + }), - 'perfectionist/sort-named-imports': [ - 'error', - {groupKind: 'values-first', order: 'asc', type: 'natural'}, - ], - 'perfectionist/sort-exports': ['error', {type: 'natural'}], + ...(sortImports && { + 'perfectionist/sort-imports': [ + isInEditor ? 'warn' : 'error', + { + groups: [ + 'type', + ['parent-type', 'sibling-type', 'index-type'], + 'builtin', + 'external', + ['internal', 'internal-type'], + ['parent', 'sibling', 'index'], + 'object', + 'side-effect', + 'side-effect-style', + ], + internalPattern: ['^[~#]/.*'], + newlinesBetween: 'ignore', + type: 'natural', + }, + ], + }), - 'perfectionist/sort-imports': [ - 'error', - { - groups: [ - 'type', - ['parent-type', 'sibling-type', 'index-type'], - 'builtin', - 'external', - ['internal', 'internal-type'], - ['parent', 'sibling', 'index'], - 'object', - 'side-effect', - 'side-effect-style', - ], - internalPattern: ['^[~#]/.*'], - newlinesBetween: 'ignore', - order: 'asc', - type: 'natural', - }, - ], + ...overrides, }, }, ] diff --git a/packages/eslint-config/src/define-config.ts b/packages/eslint-config/src/define-config.ts index fe57b7ae..5e5c96a8 100644 --- a/packages/eslint-config/src/define-config.ts +++ b/packages/eslint-config/src/define-config.ts @@ -48,6 +48,7 @@ export async function defineConfig( ): ConfigComposer { const { gitignore: enableGitignore = true, + perfectionist: enablePerfectionist = true, typescript: enableTypeScript = isPackageExists('typescript'), } = options @@ -80,9 +81,18 @@ export async function defineConfig( jsdoc(), imports(), command(), - perfectionist(), ) + if (enablePerfectionist) { + configs.push( + perfectionist({ + isInEditor, + overrides: getOverrides(options, 'perfectionist'), + ...resolveSubOptions(options, 'perfectionist'), + }), + ) + } + const typescriptOptions = resolveSubOptions(options, 'typescript') // const tsconfigPath ='tsconfigPath' in typescriptOptions ? typescriptOptions.tsconfigPath : undefined diff --git a/packages/eslint-config/src/options.ts b/packages/eslint-config/src/options.ts index f961258b..700f2497 100644 --- a/packages/eslint-config/src/options.ts +++ b/packages/eslint-config/src/options.ts @@ -42,6 +42,33 @@ export interface OptionsOverrides { overrides?: Config['rules'] } +/** + * Options for configuring the Perfectionist sorting behavior. + */ +export interface OptionsPerfectionist { + /** + * Whether to sort named exports. + * + * @default true + */ + sortNamedExports?: boolean + /** + * Whether to sort named imports. + * @default true + */ + sortNamedImports?: boolean + /** + * Whether to sort exports. + * @default true + */ + sortExports?: boolean + /** + * Whether to sort imports. + * @default true + */ + sortImports?: boolean +} + /** * Provides options to configure the TypeScript parser and type-aware linting rules. * @@ -140,6 +167,11 @@ export type Options = Flatten< */ javascript?: OptionsOverrides + /** + * Options to override the behavior of Perfectionist sorting rules. + */ + perfectionist?: boolean | OptionsPerfectionist + /** * Enable TypeScript support. *