diff --git a/README.md b/README.md index d2f48f8513..cb4e421404 100644 --- a/README.md +++ b/README.md @@ -299,22 +299,22 @@ export default antfu({ This config also provides some optional plugins/rules for extended usages. -#### `sort-keys` +#### `perfectionist` (sorting) -This plugin [`eslint-plugin-sort-keys`](https://github.com/namnm/eslint-plugin-sort-keys) allows you to keep object keys sorted with auto-fix. +This plugin [`eslint-plugin-perfectionist`](https://github.com/azat-io/eslint-plugin-perfectionist) allows you to sorted object keys, imports, etc, with auto-fix. -It's installed but no rules are enabled by default. +The plugin is installed but no rules are enabled by default. It's recommended to opt-in on each file individually using [configuration comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1). ```js -/* eslint sort-keys/sort-keys-fix: "error" */ +/* eslint perfectionist/sort-objects: "error" */ const objectWantedToSort = { a: 2, b: 1, c: 3, } -/* eslint sort-keys/sort-keys-fix: "off" */ +/* eslint perfectionist/sort-objects: "off" */ ``` ### Type Aware Rules diff --git a/eslint.config.js b/eslint.config.js index fdc274eef4..1009e409e1 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -14,7 +14,7 @@ export default antfu( { files: ['src/**/*.ts'], rules: { - 'sort-keys/sort-keys-fix': 'error', + 'perfectionist/sort-objects': 'error', }, }, { diff --git a/package.json b/package.json index 2af574bb98..0e50bdda6b 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "eslint-plugin-markdown": "^3.0.1", "eslint-plugin-n": "^16.2.0", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-sort-keys": "^2.3.5", + "eslint-plugin-perfectionist": "^2.2.0", "eslint-plugin-unicorn": "^49.0.0", "eslint-plugin-unused-imports": "^3.0.0", "eslint-plugin-vitest": "^0.3.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index be4ce7b580..f6c335d4f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,9 +47,9 @@ importers: eslint-plugin-no-only-tests: specifier: ^3.1.0 version: 3.1.0 - eslint-plugin-sort-keys: - specifier: ^2.3.5 - version: 2.3.5 + eslint-plugin-perfectionist: + specifier: ^2.2.0 + version: 2.2.0(eslint@8.52.0)(typescript@5.2.2)(vue-eslint-parser@9.3.2) eslint-plugin-unicorn: specifier: ^49.0.0 version: 49.0.0(eslint@8.52.0) @@ -1439,7 +1439,6 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 - dev: true /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -2185,10 +2184,32 @@ packages: engines: {node: '>=5.0.0'} dev: false - /eslint-plugin-sort-keys@2.3.5: - resolution: {integrity: sha512-2j/XKQ9sNJwK8kIp/U0EvuF6stS6/8aIc53/NskE4C5NRNh4dt3xzbZyOdrVC11cTH6Zo59/pdzA0Kb+2fQGWg==} + /eslint-plugin-perfectionist@2.2.0(eslint@8.52.0)(typescript@5.2.2)(vue-eslint-parser@9.3.2): + resolution: {integrity: sha512-/nG2Uurd6AY7CI6zlgjHPOoiPY8B7EYMUWdNb5w+EzyauYiQjjD5lQwAI1FlkBbCCFFZw/CdZIPQhXumYoiyaw==} + peerDependencies: + astro-eslint-parser: ^0.16.0 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.33.0 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true dependencies: - natural-compare: 1.4.0 + '@typescript-eslint/utils': 6.9.1(eslint@8.52.0)(typescript@5.2.2) + eslint: 8.52.0 + minimatch: 9.0.3 + natural-compare-lite: 1.4.0 + vue-eslint-parser: 9.3.2(eslint@8.52.0) + transitivePeerDependencies: + - supports-color + - typescript dev: false /eslint-plugin-unicorn@49.0.0(eslint@8.52.0): @@ -3357,7 +3378,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 - dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -3447,6 +3467,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: false + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} diff --git a/src/configs/index.ts b/src/configs/index.ts index 8cfc45b5bb..e57fb7c834 100644 --- a/src/configs/index.ts +++ b/src/configs/index.ts @@ -13,4 +13,4 @@ export * from './unicorn' export * from './vue' export * from './yaml' export * from './test' -export * from './sort-keys' +export * from './perfectionist' diff --git a/src/configs/jsonc.ts b/src/configs/jsonc.ts index 489f9f4f07..dcf5dd50f9 100644 --- a/src/configs/jsonc.ts +++ b/src/configs/jsonc.ts @@ -4,8 +4,8 @@ import { parserJsonc, pluginJsonc } from '../plugins' export function jsonc(options: OptionsStylistic & OptionsOverrides = {}): ConfigItem[] { const { - stylistic = true, overrides = {}, + stylistic = true, } = options const { diff --git a/src/configs/perfectionist.ts b/src/configs/perfectionist.ts new file mode 100644 index 0000000000..c4c7483e1f --- /dev/null +++ b/src/configs/perfectionist.ts @@ -0,0 +1,18 @@ +import type { ConfigItem } from '../types' +import { pluginPerfectionist } from '../plugins' + +/** + * Optional perfectionist plugin for props and items sorting. + * + * @see https://github.com/azat-io/eslint-plugin-perfectionist + */ +export function perfectionist(): ConfigItem[] { + return [ + { + name: 'antfu:perfectionist', + plugins: { + perfectionist: pluginPerfectionist, + }, + }, + ] +} diff --git a/src/configs/sort-keys.ts b/src/configs/sort-keys.ts deleted file mode 100644 index ccfd8306cd..0000000000 --- a/src/configs/sort-keys.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { ConfigItem } from '../types' -import { pluginSortKeys } from '../plugins' - -/** - * Optional sort-keys plugin - * - * @see https://github.com/namnm/eslint-plugin-sort-keys - */ -export function sortKeys(): ConfigItem[] { - return [ - { - name: 'antfu:sort-keys', - plugins: { - 'sort-keys': pluginSortKeys, - }, - }, - ] -} diff --git a/src/configs/stylistic.ts b/src/configs/stylistic.ts index 6505bc6c41..33e2c4c856 100644 --- a/src/configs/stylistic.ts +++ b/src/configs/stylistic.ts @@ -4,8 +4,8 @@ import { pluginAntfu, pluginStylistic } from '../plugins' export function stylistic(options: StylisticConfig = {}): ConfigItem[] { const { indent = 2, - quotes = 'single', jsx = true, + quotes = 'single', } = options return [ @@ -36,14 +36,9 @@ export function stylistic(options: StylisticConfig = {}): ConfigItem[] { 'style/indent': ['error', indent, { ArrayExpression: 1, CallExpression: { arguments: 1 }, + flatTernaryExpressions: false, FunctionDeclaration: { body: 1, parameters: 1 }, FunctionExpression: { body: 1, parameters: 1 }, - ImportDeclaration: 1, - MemberExpression: 1, - ObjectExpression: 1, - SwitchCase: 1, - VariableDeclarator: 1, - flatTernaryExpressions: false, ignoreComments: false, ignoredNodes: [ 'TemplateLiteral *', @@ -68,8 +63,13 @@ export function stylistic(options: StylisticConfig = {}): ConfigItem[] { 'FunctionExpression > .params > :matches(Decorator, :not(:first-child))', 'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key', ], + ImportDeclaration: 1, + MemberExpression: 1, + ObjectExpression: 1, offsetTernaryExpressions: true, outerIIFEBody: 1, + SwitchCase: 1, + VariableDeclarator: 1, }], 'style/key-spacing': ['error', { afterColon: true, beforeColon: false }], 'style/keyword-spacing': ['error', { after: true, before: true }], diff --git a/src/factory.ts b/src/factory.ts index 9564bdbcbc..e27680b14c 100644 --- a/src/factory.ts +++ b/src/factory.ts @@ -12,7 +12,7 @@ import { jsonc, markdown, node, - sortKeys, + perfectionist, sortPackageJson, sortTsconfig, stylistic, @@ -47,12 +47,12 @@ const VuePackages = [ */ export function antfu(options: OptionsConfig & ConfigItem = {}, ...userConfigs: (ConfigItem | ConfigItem[])[]) { const { - isInEditor = !!((process.env.VSCODE_PID || process.env.JETBRAINS_IDE) && !process.env.CI), - vue: enableVue = VuePackages.some(i => isPackageExists(i)), - typescript: enableTypeScript = isPackageExists('typescript'), + componentExts = [], gitignore: enableGitignore = true, + isInEditor = !!((process.env.VSCODE_PID || process.env.JETBRAINS_IDE) && !process.env.CI), overrides = {}, - componentExts = [], + typescript: enableTypeScript = isPackageExists('typescript'), + vue: enableVue = VuePackages.some(i => isPackageExists(i)), } = options const stylisticOptions = options.stylistic === false @@ -92,8 +92,8 @@ export function antfu(options: OptionsConfig & ConfigItem = {}, ...userConfigs: }), unicorn(), - // Optional plugins (not enabled by default) - sortKeys(), + // Optional plugins (installed but not enabled by default) + perfectionist(), ) if (enableVue) diff --git a/src/plugins.ts b/src/plugins.ts index b5099a253c..2a7de22bd0 100644 --- a/src/plugins.ts +++ b/src/plugins.ts @@ -16,7 +16,7 @@ export { default as pluginVue } from 'eslint-plugin-vue' export * as pluginYaml from 'eslint-plugin-yml' export { default as pluginNoOnlyTests } from 'eslint-plugin-no-only-tests' export { default as pluginVitest } from 'eslint-plugin-vitest' -export { default as pluginSortKeys } from 'eslint-plugin-sort-keys' +export { default as pluginPerfectionist } from 'eslint-plugin-perfectionist' export * as parserTs from '@typescript-eslint/parser' export { default as parserVue } from 'vue-eslint-parser'