@lincy/eslint-config 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -133,9 +133,9 @@ export default lincy({
133
133
  // 是否启用 stylistic 格式化规则
134
134
  stylistic: true, // 默认值: true, 可选: false | { indent: number | 'tab', quotes: 'single' | 'double', jsx: boolean}
135
135
  // 是否启用 typescript 规则
136
- typescript: true, // 默认值: 检测是否安装typescript依赖, 可选: false
136
+ typescript: true, // 默认值: 检测是否安装typescript依赖, 可选: false | true
137
137
  // 是否启用 vue 规则
138
- vue: true, // 默认值: 检测是否安装vue依赖, 可选: false
138
+ vue: true, // 默认值: 检测是否安装vue依赖, 可选: false | true
139
139
  // 是否启用 jsx 规则
140
140
  jsx: true, // 默认值: true, 可选: false
141
141
  // 是否启用 jsonc 规则
@@ -148,8 +148,6 @@ export default lincy({
148
148
  test: false, // 默认值: true, 可选: false
149
149
  // 是否启用 markdown 规则
150
150
  markdown: false, // 默认值: true, 可选: false
151
- // 是否启用 eslint-plugin-sort-keys 规则
152
- sortKeys: true, // 默认值: false, 可选: true
153
151
  // 覆盖规则
154
152
  overrides: {},
155
153
 
@@ -203,7 +201,9 @@ export default lincy(
203
201
  // 你还可以继续配置多个 ESLint Flat Configs
204
202
  {
205
203
  files: ['**/*.ts'],
206
- rules: {},
204
+ rules: {
205
+ 'perfectionist/sort-objects': 'error',
206
+ },
207
207
  },
208
208
  )
209
209
  ```
@@ -221,7 +221,7 @@ import {
221
221
  jsonc,
222
222
  markdown,
223
223
  node,
224
- sortKeys,
224
+ perfectionist,
225
225
  sortPackageJson,
226
226
  sortTsconfig,
227
227
  stylistic,
@@ -232,20 +232,16 @@ import {
232
232
  } from '@lincy/eslint-config'
233
233
 
234
234
  export default [
235
- ...comments(),
236
235
  ...ignores(),
237
- ...imports(),
238
- ...javascript(),
239
- ...jsdoc(),
236
+ ...javascript(/* Options */),
237
+ ...comments(),
240
238
  ...node(),
241
- ...sortKeys(),
242
- ...sortPackageJson(),
243
- ...sortTsconfig(),
239
+ ...jsdoc(),
240
+ ...imports(),
244
241
  ...unicorn(),
245
-
246
- ...typescript(),
242
+ ...perfectionist(),
243
+ ...typescript(/* Options */),
247
244
  ...stylistic(),
248
-
249
245
  ...vue(),
250
246
  ...jsonc(),
251
247
  ...yaml(),
@@ -296,7 +292,6 @@ export default lincy(
296
292
  jsonc: true,
297
293
  yaml: true,
298
294
  markdown: true,
299
- sortKeys: true,
300
295
  overrides: {}
301
296
  },
302
297
  {
@@ -354,6 +349,24 @@ export default lincy({
354
349
  })
355
350
  ```
356
351
 
352
+ #### `perfectionist` (sorting)
353
+
354
+ 这个插件 [`eslint-plugin-perfectionist`](https://github.com/azat-io/eslint-plugin-perfectionist) 允许你排序对象键名,导入,自动修复等。
355
+
356
+ 安装了插件,但默认情况下没有启用任何规则。
357
+
358
+ 建议使用[configuration comments]单独选择每个文件。(https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1).
359
+
360
+ ```js
361
+ /* eslint perfectionist/sort-objects: "error" */
362
+ const objectWantedToSort = {
363
+ a: 2,
364
+ b: 1,
365
+ c: 3,
366
+ }
367
+ /* eslint perfectionist/sort-objects: "off" */
368
+ ```
369
+
357
370
  ### 类型感知规则
358
371
 
359
372
  您可以选择通过将选项对象传递给“typescript”配置来启用[类型感知规则](https://typescript-eslint.io/linting/typed-linting/):
package/dist/index.cjs CHANGED
@@ -66,6 +66,7 @@ __export(src_exports, {
66
66
  parserTs: () => parserTs,
67
67
  parserVue: () => import_vue_eslint_parser.default,
68
68
  parserYaml: () => import_yaml_eslint_parser.default,
69
+ perfectionist: () => perfectionist,
69
70
  pluginAntfu: () => import_eslint_plugin_antfu.default,
70
71
  pluginComments: () => import_eslint_plugin_eslint_comments.default,
71
72
  pluginImport: () => pluginImport,
@@ -74,6 +75,7 @@ __export(src_exports, {
74
75
  pluginMarkdown: () => import_eslint_plugin_markdown.default,
75
76
  pluginNoOnlyTests: () => import_eslint_plugin_no_only_tests.default,
76
77
  pluginNode: () => import_eslint_plugin_n.default,
78
+ pluginPerfectionist: () => import_eslint_plugin_perfectionist.default,
77
79
  pluginSortKeys: () => import_eslint_plugin_sort_keys.default,
78
80
  pluginStylistic: () => import_eslint_plugin.default,
79
81
  pluginTs: () => import_eslint_plugin2.default,
@@ -82,7 +84,6 @@ __export(src_exports, {
82
84
  pluginVue: () => import_eslint_plugin_vue.default,
83
85
  pluginYaml: () => pluginYaml,
84
86
  renameRules: () => renameRules,
85
- sortKeys: () => sortKeys,
86
87
  sortPackageJson: () => sortPackageJson,
87
88
  sortTsconfig: () => sortTsconfig,
88
89
  stylistic: () => stylistic,
@@ -117,6 +118,7 @@ var import_eslint_plugin_vue = __toESM(require("eslint-plugin-vue"), 1);
117
118
  var pluginYaml = __toESM(require("eslint-plugin-yml"), 1);
118
119
  var import_eslint_plugin_no_only_tests = __toESM(require("eslint-plugin-no-only-tests"), 1);
119
120
  var import_eslint_plugin_sort_keys = __toESM(require("eslint-plugin-sort-keys"), 1);
121
+ var import_eslint_plugin_perfectionist = __toESM(require("eslint-plugin-perfectionist"), 1);
120
122
  var parserTs = __toESM(require("@typescript-eslint/parser"), 1);
121
123
  var import_vue_eslint_parser = __toESM(require("vue-eslint-parser"), 1);
122
124
  var import_yaml_eslint_parser = __toESM(require("yaml-eslint-parser"), 1);
@@ -281,7 +283,6 @@ function javascript(options = {}) {
281
283
  "accessor-pairs": ["error", { enforceForClassMembers: true, setWithoutGet: true }],
282
284
  "antfu/top-level-function": "error",
283
285
  "array-callback-return": "error",
284
- "arrow-parens": ["error", "as-needed", { requireForBlockBody: true }],
285
286
  "block-scoped-var": "error",
286
287
  "constructor-super": "error",
287
288
  "default-case-last": "error",
@@ -440,6 +441,7 @@ function javascript(options = {}) {
440
441
  memberSyntaxSortOrder: ["none", "all", "multiple", "single"]
441
442
  }
442
443
  ],
444
+ "style/arrow-parens": ["error", "as-needed", { requireForBlockBody: true }],
443
445
  "symbol-description": "error",
444
446
  "unicode-bom": ["error", "never"],
445
447
  "unused-imports/no-unused-imports": isInEditor ? "off" : "error",
@@ -501,8 +503,8 @@ function jsdoc(options = {}) {
501
503
  // src/configs/jsonc.ts
502
504
  function jsonc(options = {}) {
503
505
  const {
504
- stylistic: stylistic2 = true,
505
- overrides = {}
506
+ overrides = {},
507
+ stylistic: stylistic2 = true
506
508
  } = options;
507
509
  return [
508
510
  {
@@ -877,8 +879,8 @@ function stylistic(options = {}) {
877
879
  } = options;
878
880
  const {
879
881
  indent = 4,
880
- quotes = "single",
881
- jsx = true
882
+ jsx = true,
883
+ quotes = "single"
882
884
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
883
885
  return [
884
886
  {
@@ -904,14 +906,9 @@ function stylistic(options = {}) {
904
906
  "style/indent": ["error", indent, {
905
907
  ArrayExpression: 1,
906
908
  CallExpression: { arguments: 1 },
909
+ flatTernaryExpressions: false,
907
910
  FunctionDeclaration: { body: 1, parameters: 1 },
908
911
  FunctionExpression: { body: 1, parameters: 1 },
909
- ImportDeclaration: 1,
910
- MemberExpression: 1,
911
- ObjectExpression: 1,
912
- SwitchCase: 1,
913
- VariableDeclarator: 1,
914
- flatTernaryExpressions: false,
915
912
  ignoreComments: false,
916
913
  ignoredNodes: [
917
914
  "TemplateLiteral *",
@@ -936,8 +933,13 @@ function stylistic(options = {}) {
936
933
  "FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
937
934
  "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
938
935
  ],
936
+ ImportDeclaration: 1,
937
+ MemberExpression: 1,
938
+ ObjectExpression: 1,
939
939
  offsetTernaryExpressions: true,
940
- outerIIFEBody: 1
940
+ outerIIFEBody: 1,
941
+ SwitchCase: 1,
942
+ VariableDeclarator: 1
941
943
  }],
942
944
  "style/key-spacing": ["error", { afterColon: true, beforeColon: false }],
943
945
  "style/keyword-spacing": ["error", { after: true, before: true }],
@@ -1033,7 +1035,7 @@ var import_node_process = __toESM(require("process"), 1);
1033
1035
 
1034
1036
  // src/utils.ts
1035
1037
  function combine(...configs) {
1036
- return configs.flatMap((config) => Array.isArray(config) ? config : [config]);
1038
+ return configs.flat();
1037
1039
  }
1038
1040
  function renameRules(rules, from, to) {
1039
1041
  return Object.fromEntries(
@@ -1419,12 +1421,12 @@ function test(options = {}) {
1419
1421
  ];
1420
1422
  }
1421
1423
 
1422
- // src/configs/sort-keys.ts
1423
- function sortKeys() {
1424
+ // src/configs/perfectionist.ts
1425
+ function perfectionist() {
1424
1426
  return [
1425
1427
  {
1426
1428
  plugins: {
1427
- "sort-keys": import_eslint_plugin_sort_keys.default
1429
+ perfectionist: import_eslint_plugin_perfectionist.default
1428
1430
  }
1429
1431
  }
1430
1432
  ];
@@ -1449,13 +1451,12 @@ var VuePackages = [
1449
1451
  ];
1450
1452
  function lincy(options = {}, ...userConfigs) {
1451
1453
  const {
1452
- isInEditor = !!((import_node_process2.default.env.VSCODE_PID || import_node_process2.default.env.JETBRAINS_IDE) && !import_node_process2.default.env.CI),
1453
- vue: enableVue = VuePackages.some((i) => (0, import_local_pkg2.isPackageExists)(i)),
1454
- typescript: enableTypeScript = (0, import_local_pkg2.isPackageExists)("typescript"),
1454
+ componentExts = [],
1455
1455
  gitignore: enableGitignore = true,
1456
- sortKeys: enableSortKeys = false,
1456
+ isInEditor = !!((import_node_process2.default.env.VSCODE_PID || import_node_process2.default.env.JETBRAINS_IDE) && !import_node_process2.default.env.CI),
1457
1457
  overrides = {},
1458
- componentExts = []
1458
+ typescript: enableTypeScript = (0, import_local_pkg2.isPackageExists)("typescript"),
1459
+ vue: enableVue = VuePackages.some((i) => (0, import_local_pkg2.isPackageExists)(i))
1459
1460
  } = options;
1460
1461
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
1461
1462
  if (stylisticOptions && !("jsx" in stylisticOptions))
@@ -1485,10 +1486,10 @@ function lincy(options = {}, ...userConfigs) {
1485
1486
  imports({
1486
1487
  stylistic: stylisticOptions
1487
1488
  }),
1488
- unicorn()
1489
+ unicorn(),
1490
+ // Optional plugins (installed but not enabled by default)
1491
+ perfectionist()
1489
1492
  );
1490
- if (enableSortKeys)
1491
- configs.push(sortKeys());
1492
1493
  if (enableVue)
1493
1494
  componentExts.push("vue");
1494
1495
  if (enableTypeScript) {
@@ -1592,6 +1593,7 @@ var src_default = lincy;
1592
1593
  parserTs,
1593
1594
  parserVue,
1594
1595
  parserYaml,
1596
+ perfectionist,
1595
1597
  pluginAntfu,
1596
1598
  pluginComments,
1597
1599
  pluginImport,
@@ -1600,6 +1602,7 @@ var src_default = lincy;
1600
1602
  pluginMarkdown,
1601
1603
  pluginNoOnlyTests,
1602
1604
  pluginNode,
1605
+ pluginPerfectionist,
1603
1606
  pluginSortKeys,
1604
1607
  pluginStylistic,
1605
1608
  pluginTs,
@@ -1608,7 +1611,6 @@ var src_default = lincy;
1608
1611
  pluginVue,
1609
1612
  pluginYaml,
1610
1613
  renameRules,
1611
- sortKeys,
1612
1614
  sortPackageJson,
1613
1615
  sortTsconfig,
1614
1616
  stylistic,
package/dist/index.d.cts CHANGED
@@ -2,9 +2,14 @@ import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
2
2
  import { ParserOptions } from '@typescript-eslint/parser';
3
3
  import * as parser from '@typescript-eslint/parser';
4
4
  export { parser as parserTs };
5
- import { MergeIntersection, EslintRules, Unprefix, ReactRules, TypeScriptRules, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ImportRules, JsoncRules, VueRules, UnicornRules, EslintCommentsRules, RuleConfig, FlatESLintConfigItem } from '@antfu/eslint-define-config';
5
+ import { RuleConfig, MergeIntersection, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ImportRules, EslintRules, JsoncRules, VueRules, EslintCommentsRules, FlatESLintConfigItem } from '@antfu/eslint-define-config';
6
+ import { RuleOptions as RuleOptions$1 } from '@eslint-types/jsdoc/types';
7
+ import { RuleOptions } from '@eslint-types/typescript-eslint/types';
8
+ import { RuleOptions as RuleOptions$2 } from '@eslint-types/unicorn/types';
6
9
  import { Rules as Rules$1 } from 'eslint-plugin-antfu';
7
10
  export { default as pluginAntfu } from 'eslint-plugin-antfu';
11
+ import { UnprefixedRuleOptions } from '@stylistic/eslint-plugin';
12
+ export { default as pluginStylistic } from '@stylistic/eslint-plugin';
8
13
  export { default as pluginComments } from 'eslint-plugin-eslint-comments';
9
14
  import * as eslintPluginI from 'eslint-plugin-i';
10
15
  export { eslintPluginI as pluginImport };
@@ -13,7 +18,6 @@ import * as eslintPluginJsonc from 'eslint-plugin-jsonc';
13
18
  export { eslintPluginJsonc as pluginJsonc };
14
19
  export { default as pluginMarkdown } from 'eslint-plugin-markdown';
15
20
  export { default as pluginNode } from 'eslint-plugin-n';
16
- export { default as pluginStylistic } from '@stylistic/eslint-plugin';
17
21
  export { default as pluginTs } from '@typescript-eslint/eslint-plugin';
18
22
  export { default as pluginUnicorn } from 'eslint-plugin-unicorn';
19
23
  export { default as pluginUnusedImports } from 'eslint-plugin-unused-imports';
@@ -22,16 +26,19 @@ import * as eslintPluginYml from 'eslint-plugin-yml';
22
26
  export { eslintPluginYml as pluginYaml };
23
27
  export { default as pluginNoOnlyTests } from 'eslint-plugin-no-only-tests';
24
28
  export { default as pluginSortKeys } from 'eslint-plugin-sort-keys';
29
+ export { default as pluginPerfectionist } from 'eslint-plugin-perfectionist';
25
30
  export { default as parserVue } from 'vue-eslint-parser';
26
31
  export { default as parserYaml } from 'yaml-eslint-parser';
27
32
  export { default as parserJsonc } from 'jsonc-eslint-parser';
28
33
 
29
- type MergedRules = MergeIntersection<EslintRules & Unprefix<ReactRules, 'react/'> & Unprefix<TypeScriptRules, '@typescript-eslint/'>>;
30
- type StylisticRules = Pick<MergedRules, 'array-bracket-newline' | 'array-bracket-spacing' | 'array-element-newline' | 'arrow-spacing' | 'block-spacing' | 'brace-style' | 'comma-dangle' | 'comma-spacing' | 'comma-style' | 'computed-property-spacing' | 'dot-location' | 'eol-last' | 'func-call-spacing' | 'function-call-argument-newline' | 'function-paren-newline' | 'generator-star-spacing' | 'implicit-arrow-linebreak' | 'indent' | 'jsx-quotes' | 'key-spacing' | 'keyword-spacing' | 'linebreak-style' | 'lines-around-comment' | 'lines-around-directive' | 'lines-between-class-members' | 'max-len' | 'max-statements-per-line' | 'multiline-ternary' | 'new-parens' | 'newline-after-var' | 'newline-before-return' | 'newline-per-chained-call' | 'no-confusing-arrow' | 'no-extra-parens' | 'no-extra-semi' | 'no-floating-decimal' | 'no-mixed-operators' | 'no-mixed-spaces-and-tabs' | 'no-multi-spaces' | 'no-multiple-empty-lines' | 'no-spaced-func' | 'no-tabs' | 'no-trailing-spaces' | 'no-whitespace-before-property' | 'nonblock-statement-body-position' | 'object-curly-newline' | 'object-curly-spacing' | 'object-property-newline' | 'one-var-declaration-per-line' | 'operator-linebreak' | 'padded-blocks' | 'padding-line-between-statements' | 'quote-props' | 'quotes' | 'rest-spread-spacing' | 'semi' | 'semi-spacing' | 'semi-style' | 'space-before-blocks' | 'space-before-function-paren' | 'space-in-parens' | 'space-infix-ops' | 'space-unary-ops' | 'spaced-comment' | 'switch-colon-spacing' | 'template-curly-spacing' | 'template-tag-spacing' | 'wrap-iife' | 'wrap-regex' | 'yield-star-spacing' | 'block-spacing' | 'brace-style' | 'comma-dangle' | 'comma-spacing' | 'func-call-spacing' | 'indent' | 'key-spacing' | 'keyword-spacing' | 'lines-around-comment' | 'lines-between-class-members' | 'member-delimiter-style' | 'object-curly-spacing' | 'padding-line-between-statements' | 'quotes' | 'semi' | 'space-before-blocks' | 'space-before-function-paren' | 'space-infix-ops' | 'type-annotation-spacing'>;
31
-
32
- type Rules = MergeIntersection<RenamePrefix<TypeScriptRules, '@typescript-eslint/', 'ts/'> & RenamePrefix<VitestRules, 'vitest/', 'test/'> & RenamePrefix<YmlRules, 'yml/', 'yaml/'> & RenamePrefix<NRules, 'n/', 'node/'> & Prefix<StylisticRules, 'style/'> & Prefix<Rules$1, 'antfu/'> & ImportRules & EslintRules & JsoncRules & VueRules & UnicornRules & EslintCommentsRules & {
34
+ type WrapRuleConfig<T extends {
35
+ [key: string]: any;
36
+ }> = {
37
+ [K in keyof T]: T[K] extends RuleConfig ? T[K] : RuleConfig<T[K]>;
38
+ };
39
+ type Rules = WrapRuleConfig<MergeIntersection<RenamePrefix<RuleOptions, '@typescript-eslint/', 'ts/'> & RenamePrefix<VitestRules, 'vitest/', 'test/'> & RenamePrefix<YmlRules, 'yml/', 'yaml/'> & RenamePrefix<NRules, 'n/', 'node/'> & Prefix<UnprefixedRuleOptions, 'style/'> & Prefix<Rules$1, 'antfu/'> & RuleOptions$1 & ImportRules & EslintRules & JsoncRules & VueRules & RuleOptions$2 & EslintCommentsRules & {
33
40
  'test/no-only-tests': RuleConfig<[]>;
34
- }>;
41
+ }>>;
35
42
  type ConfigItem = Omit<FlatESLintConfigItem<Rules, false>, 'plugins'> & {
36
43
  /**
37
44
  * Custom name of each config item
@@ -145,12 +152,6 @@ interface OptionsConfig extends OptionsComponentExts {
145
152
  * @default true
146
153
  */
147
154
  markdown?: boolean;
148
- /**
149
- * Enable SortKeys support.
150
- *
151
- * @default false
152
- */
153
- sortKeys?: boolean;
154
155
  /**
155
156
  * Enable stylistic rules.
156
157
  *
@@ -225,11 +226,11 @@ declare function yaml(options?: OptionsOverrides & OptionsStylistic): ConfigItem
225
226
  declare function test(options?: OptionsIsInEditor & OptionsOverrides): ConfigItem[];
226
227
 
227
228
  /**
228
- * Optional sort-keys plugin
229
+ * Optional perfectionist plugin for props and items sorting.
229
230
  *
230
- * @see https://github.com/namnm/eslint-plugin-sort-keys
231
+ * @see https://github.com/azat-io/eslint-plugin-perfectionist
231
232
  */
232
- declare function sortKeys(): ConfigItem[];
233
+ declare function perfectionist(): ConfigItem[];
233
234
 
234
235
  /**
235
236
  * Combine array and non-array configs into a single array.
@@ -262,4 +263,4 @@ declare const GLOB_TESTS: string[];
262
263
  declare const GLOB_ALL_SRC: string[];
263
264
  declare const GLOB_EXCLUDE: string[];
264
265
 
265
- export { ConfigItem, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, Rules, StylisticConfig, StylisticOverridesConfig, combine, comments, lincy as default, ignores, imports, javascript, jsdoc, jsonc, lincy, markdown, node, renameRules, sortKeys, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, vue, yaml };
266
+ export { ConfigItem, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, Rules, StylisticConfig, StylisticOverridesConfig, WrapRuleConfig, combine, comments, lincy as default, ignores, imports, javascript, jsdoc, jsonc, lincy, markdown, node, perfectionist, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, vue, yaml };
package/dist/index.d.ts CHANGED
@@ -2,9 +2,14 @@ import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
2
2
  import { ParserOptions } from '@typescript-eslint/parser';
3
3
  import * as parser from '@typescript-eslint/parser';
4
4
  export { parser as parserTs };
5
- import { MergeIntersection, EslintRules, Unprefix, ReactRules, TypeScriptRules, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ImportRules, JsoncRules, VueRules, UnicornRules, EslintCommentsRules, RuleConfig, FlatESLintConfigItem } from '@antfu/eslint-define-config';
5
+ import { RuleConfig, MergeIntersection, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ImportRules, EslintRules, JsoncRules, VueRules, EslintCommentsRules, FlatESLintConfigItem } from '@antfu/eslint-define-config';
6
+ import { RuleOptions as RuleOptions$1 } from '@eslint-types/jsdoc/types';
7
+ import { RuleOptions } from '@eslint-types/typescript-eslint/types';
8
+ import { RuleOptions as RuleOptions$2 } from '@eslint-types/unicorn/types';
6
9
  import { Rules as Rules$1 } from 'eslint-plugin-antfu';
7
10
  export { default as pluginAntfu } from 'eslint-plugin-antfu';
11
+ import { UnprefixedRuleOptions } from '@stylistic/eslint-plugin';
12
+ export { default as pluginStylistic } from '@stylistic/eslint-plugin';
8
13
  export { default as pluginComments } from 'eslint-plugin-eslint-comments';
9
14
  import * as eslintPluginI from 'eslint-plugin-i';
10
15
  export { eslintPluginI as pluginImport };
@@ -13,7 +18,6 @@ import * as eslintPluginJsonc from 'eslint-plugin-jsonc';
13
18
  export { eslintPluginJsonc as pluginJsonc };
14
19
  export { default as pluginMarkdown } from 'eslint-plugin-markdown';
15
20
  export { default as pluginNode } from 'eslint-plugin-n';
16
- export { default as pluginStylistic } from '@stylistic/eslint-plugin';
17
21
  export { default as pluginTs } from '@typescript-eslint/eslint-plugin';
18
22
  export { default as pluginUnicorn } from 'eslint-plugin-unicorn';
19
23
  export { default as pluginUnusedImports } from 'eslint-plugin-unused-imports';
@@ -22,16 +26,19 @@ import * as eslintPluginYml from 'eslint-plugin-yml';
22
26
  export { eslintPluginYml as pluginYaml };
23
27
  export { default as pluginNoOnlyTests } from 'eslint-plugin-no-only-tests';
24
28
  export { default as pluginSortKeys } from 'eslint-plugin-sort-keys';
29
+ export { default as pluginPerfectionist } from 'eslint-plugin-perfectionist';
25
30
  export { default as parserVue } from 'vue-eslint-parser';
26
31
  export { default as parserYaml } from 'yaml-eslint-parser';
27
32
  export { default as parserJsonc } from 'jsonc-eslint-parser';
28
33
 
29
- type MergedRules = MergeIntersection<EslintRules & Unprefix<ReactRules, 'react/'> & Unprefix<TypeScriptRules, '@typescript-eslint/'>>;
30
- type StylisticRules = Pick<MergedRules, 'array-bracket-newline' | 'array-bracket-spacing' | 'array-element-newline' | 'arrow-spacing' | 'block-spacing' | 'brace-style' | 'comma-dangle' | 'comma-spacing' | 'comma-style' | 'computed-property-spacing' | 'dot-location' | 'eol-last' | 'func-call-spacing' | 'function-call-argument-newline' | 'function-paren-newline' | 'generator-star-spacing' | 'implicit-arrow-linebreak' | 'indent' | 'jsx-quotes' | 'key-spacing' | 'keyword-spacing' | 'linebreak-style' | 'lines-around-comment' | 'lines-around-directive' | 'lines-between-class-members' | 'max-len' | 'max-statements-per-line' | 'multiline-ternary' | 'new-parens' | 'newline-after-var' | 'newline-before-return' | 'newline-per-chained-call' | 'no-confusing-arrow' | 'no-extra-parens' | 'no-extra-semi' | 'no-floating-decimal' | 'no-mixed-operators' | 'no-mixed-spaces-and-tabs' | 'no-multi-spaces' | 'no-multiple-empty-lines' | 'no-spaced-func' | 'no-tabs' | 'no-trailing-spaces' | 'no-whitespace-before-property' | 'nonblock-statement-body-position' | 'object-curly-newline' | 'object-curly-spacing' | 'object-property-newline' | 'one-var-declaration-per-line' | 'operator-linebreak' | 'padded-blocks' | 'padding-line-between-statements' | 'quote-props' | 'quotes' | 'rest-spread-spacing' | 'semi' | 'semi-spacing' | 'semi-style' | 'space-before-blocks' | 'space-before-function-paren' | 'space-in-parens' | 'space-infix-ops' | 'space-unary-ops' | 'spaced-comment' | 'switch-colon-spacing' | 'template-curly-spacing' | 'template-tag-spacing' | 'wrap-iife' | 'wrap-regex' | 'yield-star-spacing' | 'block-spacing' | 'brace-style' | 'comma-dangle' | 'comma-spacing' | 'func-call-spacing' | 'indent' | 'key-spacing' | 'keyword-spacing' | 'lines-around-comment' | 'lines-between-class-members' | 'member-delimiter-style' | 'object-curly-spacing' | 'padding-line-between-statements' | 'quotes' | 'semi' | 'space-before-blocks' | 'space-before-function-paren' | 'space-infix-ops' | 'type-annotation-spacing'>;
31
-
32
- type Rules = MergeIntersection<RenamePrefix<TypeScriptRules, '@typescript-eslint/', 'ts/'> & RenamePrefix<VitestRules, 'vitest/', 'test/'> & RenamePrefix<YmlRules, 'yml/', 'yaml/'> & RenamePrefix<NRules, 'n/', 'node/'> & Prefix<StylisticRules, 'style/'> & Prefix<Rules$1, 'antfu/'> & ImportRules & EslintRules & JsoncRules & VueRules & UnicornRules & EslintCommentsRules & {
34
+ type WrapRuleConfig<T extends {
35
+ [key: string]: any;
36
+ }> = {
37
+ [K in keyof T]: T[K] extends RuleConfig ? T[K] : RuleConfig<T[K]>;
38
+ };
39
+ type Rules = WrapRuleConfig<MergeIntersection<RenamePrefix<RuleOptions, '@typescript-eslint/', 'ts/'> & RenamePrefix<VitestRules, 'vitest/', 'test/'> & RenamePrefix<YmlRules, 'yml/', 'yaml/'> & RenamePrefix<NRules, 'n/', 'node/'> & Prefix<UnprefixedRuleOptions, 'style/'> & Prefix<Rules$1, 'antfu/'> & RuleOptions$1 & ImportRules & EslintRules & JsoncRules & VueRules & RuleOptions$2 & EslintCommentsRules & {
33
40
  'test/no-only-tests': RuleConfig<[]>;
34
- }>;
41
+ }>>;
35
42
  type ConfigItem = Omit<FlatESLintConfigItem<Rules, false>, 'plugins'> & {
36
43
  /**
37
44
  * Custom name of each config item
@@ -145,12 +152,6 @@ interface OptionsConfig extends OptionsComponentExts {
145
152
  * @default true
146
153
  */
147
154
  markdown?: boolean;
148
- /**
149
- * Enable SortKeys support.
150
- *
151
- * @default false
152
- */
153
- sortKeys?: boolean;
154
155
  /**
155
156
  * Enable stylistic rules.
156
157
  *
@@ -225,11 +226,11 @@ declare function yaml(options?: OptionsOverrides & OptionsStylistic): ConfigItem
225
226
  declare function test(options?: OptionsIsInEditor & OptionsOverrides): ConfigItem[];
226
227
 
227
228
  /**
228
- * Optional sort-keys plugin
229
+ * Optional perfectionist plugin for props and items sorting.
229
230
  *
230
- * @see https://github.com/namnm/eslint-plugin-sort-keys
231
+ * @see https://github.com/azat-io/eslint-plugin-perfectionist
231
232
  */
232
- declare function sortKeys(): ConfigItem[];
233
+ declare function perfectionist(): ConfigItem[];
233
234
 
234
235
  /**
235
236
  * Combine array and non-array configs into a single array.
@@ -262,4 +263,4 @@ declare const GLOB_TESTS: string[];
262
263
  declare const GLOB_ALL_SRC: string[];
263
264
  declare const GLOB_EXCLUDE: string[];
264
265
 
265
- export { ConfigItem, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, Rules, StylisticConfig, StylisticOverridesConfig, combine, comments, lincy as default, ignores, imports, javascript, jsdoc, jsonc, lincy, markdown, node, renameRules, sortKeys, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, vue, yaml };
266
+ export { ConfigItem, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsStylistic, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, Rules, StylisticConfig, StylisticOverridesConfig, WrapRuleConfig, combine, comments, lincy as default, ignores, imports, javascript, jsdoc, jsonc, lincy, markdown, node, perfectionist, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, vue, yaml };
package/dist/index.js CHANGED
@@ -20,10 +20,11 @@ import { default as default11 } from "eslint-plugin-vue";
20
20
  import * as pluginYaml from "eslint-plugin-yml";
21
21
  import { default as default12 } from "eslint-plugin-no-only-tests";
22
22
  import { default as default13 } from "eslint-plugin-sort-keys";
23
+ import { default as default14 } from "eslint-plugin-perfectionist";
23
24
  import * as parserTs from "@typescript-eslint/parser";
24
- import { default as default14 } from "vue-eslint-parser";
25
- import { default as default15 } from "yaml-eslint-parser";
26
- import { default as default16 } from "jsonc-eslint-parser";
25
+ import { default as default15 } from "vue-eslint-parser";
26
+ import { default as default16 } from "yaml-eslint-parser";
27
+ import { default as default17 } from "jsonc-eslint-parser";
27
28
 
28
29
  // src/configs/comments.ts
29
30
  function comments() {
@@ -184,7 +185,6 @@ function javascript(options = {}) {
184
185
  "accessor-pairs": ["error", { enforceForClassMembers: true, setWithoutGet: true }],
185
186
  "antfu/top-level-function": "error",
186
187
  "array-callback-return": "error",
187
- "arrow-parens": ["error", "as-needed", { requireForBlockBody: true }],
188
188
  "block-scoped-var": "error",
189
189
  "constructor-super": "error",
190
190
  "default-case-last": "error",
@@ -343,6 +343,7 @@ function javascript(options = {}) {
343
343
  memberSyntaxSortOrder: ["none", "all", "multiple", "single"]
344
344
  }
345
345
  ],
346
+ "style/arrow-parens": ["error", "as-needed", { requireForBlockBody: true }],
346
347
  "symbol-description": "error",
347
348
  "unicode-bom": ["error", "never"],
348
349
  "unused-imports/no-unused-imports": isInEditor ? "off" : "error",
@@ -404,8 +405,8 @@ function jsdoc(options = {}) {
404
405
  // src/configs/jsonc.ts
405
406
  function jsonc(options = {}) {
406
407
  const {
407
- stylistic: stylistic2 = true,
408
- overrides = {}
408
+ overrides = {},
409
+ stylistic: stylistic2 = true
409
410
  } = options;
410
411
  return [
411
412
  {
@@ -416,7 +417,7 @@ function jsonc(options = {}) {
416
417
  {
417
418
  files: [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
418
419
  languageOptions: {
419
- parser: default16
420
+ parser: default17
420
421
  },
421
422
  rules: {
422
423
  "jsonc/no-bigint-literals": "error",
@@ -780,8 +781,8 @@ function stylistic(options = {}) {
780
781
  } = options;
781
782
  const {
782
783
  indent = 4,
783
- quotes = "single",
784
- jsx = true
784
+ jsx = true,
785
+ quotes = "single"
785
786
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
786
787
  return [
787
788
  {
@@ -807,14 +808,9 @@ function stylistic(options = {}) {
807
808
  "style/indent": ["error", indent, {
808
809
  ArrayExpression: 1,
809
810
  CallExpression: { arguments: 1 },
811
+ flatTernaryExpressions: false,
810
812
  FunctionDeclaration: { body: 1, parameters: 1 },
811
813
  FunctionExpression: { body: 1, parameters: 1 },
812
- ImportDeclaration: 1,
813
- MemberExpression: 1,
814
- ObjectExpression: 1,
815
- SwitchCase: 1,
816
- VariableDeclarator: 1,
817
- flatTernaryExpressions: false,
818
814
  ignoreComments: false,
819
815
  ignoredNodes: [
820
816
  "TemplateLiteral *",
@@ -839,8 +835,13 @@ function stylistic(options = {}) {
839
835
  "FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
840
836
  "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
841
837
  ],
838
+ ImportDeclaration: 1,
839
+ MemberExpression: 1,
840
+ ObjectExpression: 1,
842
841
  offsetTernaryExpressions: true,
843
- outerIIFEBody: 1
842
+ outerIIFEBody: 1,
843
+ SwitchCase: 1,
844
+ VariableDeclarator: 1
844
845
  }],
845
846
  "style/key-spacing": ["error", { afterColon: true, beforeColon: false }],
846
847
  "style/keyword-spacing": ["error", { after: true, before: true }],
@@ -936,7 +937,7 @@ import process from "process";
936
937
 
937
938
  // src/utils.ts
938
939
  function combine(...configs) {
939
- return configs.flatMap((config) => Array.isArray(config) ? config : [config]);
940
+ return configs.flat();
940
941
  }
941
942
  function renameRules(rules, from, to) {
942
943
  return Object.fromEntries(
@@ -1142,7 +1143,7 @@ function vue(options = {}) {
1142
1143
  {
1143
1144
  files: [GLOB_VUE],
1144
1145
  languageOptions: {
1145
- parser: default14,
1146
+ parser: default15,
1146
1147
  parserOptions: {
1147
1148
  ecmaFeatures: {
1148
1149
  jsx: true
@@ -1270,7 +1271,7 @@ function yaml(options = {}) {
1270
1271
  {
1271
1272
  files: [GLOB_YAML],
1272
1273
  languageOptions: {
1273
- parser: default15
1274
+ parser: default16
1274
1275
  },
1275
1276
  rules: {
1276
1277
  "style/spaced-comment": "off",
@@ -1322,12 +1323,12 @@ function test(options = {}) {
1322
1323
  ];
1323
1324
  }
1324
1325
 
1325
- // src/configs/sort-keys.ts
1326
- function sortKeys() {
1326
+ // src/configs/perfectionist.ts
1327
+ function perfectionist() {
1327
1328
  return [
1328
1329
  {
1329
1330
  plugins: {
1330
- "sort-keys": default13
1331
+ perfectionist: default14
1331
1332
  }
1332
1333
  }
1333
1334
  ];
@@ -1352,13 +1353,12 @@ var VuePackages = [
1352
1353
  ];
1353
1354
  function lincy(options = {}, ...userConfigs) {
1354
1355
  const {
1355
- isInEditor = !!((process2.env.VSCODE_PID || process2.env.JETBRAINS_IDE) && !process2.env.CI),
1356
- vue: enableVue = VuePackages.some((i) => isPackageExists(i)),
1357
- typescript: enableTypeScript = isPackageExists("typescript"),
1356
+ componentExts = [],
1358
1357
  gitignore: enableGitignore = true,
1359
- sortKeys: enableSortKeys = false,
1358
+ isInEditor = !!((process2.env.VSCODE_PID || process2.env.JETBRAINS_IDE) && !process2.env.CI),
1360
1359
  overrides = {},
1361
- componentExts = []
1360
+ typescript: enableTypeScript = isPackageExists("typescript"),
1361
+ vue: enableVue = VuePackages.some((i) => isPackageExists(i))
1362
1362
  } = options;
1363
1363
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
1364
1364
  if (stylisticOptions && !("jsx" in stylisticOptions))
@@ -1388,10 +1388,10 @@ function lincy(options = {}, ...userConfigs) {
1388
1388
  imports({
1389
1389
  stylistic: stylisticOptions
1390
1390
  }),
1391
- unicorn()
1391
+ unicorn(),
1392
+ // Optional plugins (installed but not enabled by default)
1393
+ perfectionist()
1392
1394
  );
1393
- if (enableSortKeys)
1394
- configs.push(sortKeys());
1395
1395
  if (enableVue)
1396
1396
  componentExts.push("vue");
1397
1397
  if (enableTypeScript) {
@@ -1491,10 +1491,11 @@ export {
1491
1491
  lincy,
1492
1492
  markdown,
1493
1493
  node,
1494
- default16 as parserJsonc,
1494
+ default17 as parserJsonc,
1495
1495
  parserTs,
1496
- default14 as parserVue,
1497
- default15 as parserYaml,
1496
+ default15 as parserVue,
1497
+ default16 as parserYaml,
1498
+ perfectionist,
1498
1499
  default2 as pluginAntfu,
1499
1500
  default3 as pluginComments,
1500
1501
  pluginImport,
@@ -1503,6 +1504,7 @@ export {
1503
1504
  default5 as pluginMarkdown,
1504
1505
  default12 as pluginNoOnlyTests,
1505
1506
  default6 as pluginNode,
1507
+ default14 as pluginPerfectionist,
1506
1508
  default13 as pluginSortKeys,
1507
1509
  default7 as pluginStylistic,
1508
1510
  default8 as pluginTs,
@@ -1511,7 +1513,6 @@ export {
1511
1513
  default11 as pluginVue,
1512
1514
  pluginYaml,
1513
1515
  renameRules,
1514
- sortKeys,
1515
1516
  sortPackageJson,
1516
1517
  sortTsconfig,
1517
1518
  stylistic,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lincy/eslint-config",
3
3
  "type": "module",
4
- "version": "3.6.0",
4
+ "version": "3.7.0",
5
5
  "packageManager": "pnpm@8.7.6",
6
6
  "description": "LinCenYing's ESLint config",
7
7
  "author": "LinCenYing <lincenying@gmail.com> (https://github.com/lincenying/)",
@@ -26,13 +26,13 @@
26
26
  "scripts": {
27
27
  "build": "tsup src/index.ts --format esm,cjs --shims --clean --dts",
28
28
  "stub": "tsup src/index.ts --format esm",
29
- "lint": "pnpm run stub && eslint .",
30
- "lint:fix": "eslint . --fix",
31
29
  "postpublish": "simple-open-url https://npmmirror.com/package/@lincy/eslint-config",
32
30
  "prepublishOnly": "nr build",
33
31
  "release": "bumpp && npm publish -r --access public",
34
32
  "test": "vitest",
35
- "typecheck": "tsc --noEmit",
33
+ "lint": "pnpm run stub && eslint .",
34
+ "lint:fix": "eslint . --fix",
35
+ "lint:ts": "tsc --noEmit",
36
36
  "prepare": "sh simple-git-hooks.sh"
37
37
  },
38
38
  "peerDependencies": {
@@ -40,22 +40,23 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@antfu/eslint-define-config": "1.23.0-2",
43
- "@stylistic/eslint-plugin": "0.1.2",
44
- "@typescript-eslint/eslint-plugin": "^6.9.1",
45
- "@typescript-eslint/parser": "^6.9.1",
43
+ "@stylistic/eslint-plugin": "1.2.0",
44
+ "@typescript-eslint/eslint-plugin": "^6.11.0",
45
+ "@typescript-eslint/parser": "^6.11.0",
46
46
  "eslint-config-flat-gitignore": "^0.1.1",
47
- "eslint-plugin-antfu": "^1.0.1",
47
+ "eslint-plugin-antfu": "^1.0.2",
48
48
  "eslint-plugin-eslint-comments": "^3.2.0",
49
49
  "eslint-plugin-i": "^2.29.0",
50
- "eslint-plugin-jsdoc": "^46.8.2",
50
+ "eslint-plugin-jsdoc": "^46.9.0",
51
51
  "eslint-plugin-jsonc": "^2.10.0",
52
52
  "eslint-plugin-markdown": "^3.0.1",
53
- "eslint-plugin-n": "^16.2.0",
53
+ "eslint-plugin-n": "^16.3.1",
54
54
  "eslint-plugin-no-only-tests": "^3.1.0",
55
+ "eslint-plugin-perfectionist": "^2.3.0",
55
56
  "eslint-plugin-sort-keys": "^2.3.5",
56
57
  "eslint-plugin-unicorn": "^49.0.0",
57
58
  "eslint-plugin-unused-imports": "^3.0.0",
58
- "eslint-plugin-vitest": "^0.3.8",
59
+ "eslint-plugin-vitest": "^0.3.9",
59
60
  "eslint-plugin-vue": "^9.18.1",
60
61
  "eslint-plugin-yml": "^1.10.0",
61
62
  "globals": "^13.23.0",
@@ -65,16 +66,19 @@
65
66
  "yaml-eslint-parser": "^1.2.2"
66
67
  },
67
68
  "devDependencies": {
68
- "@antfu/ni": "^0.21.8",
69
+ "@antfu/ni": "^0.21.9",
70
+ "@eslint-types/jsdoc": "46.8.2-1",
71
+ "@eslint-types/typescript-eslint": "^6.9.1",
72
+ "@eslint-types/unicorn": "^49.0.0",
69
73
  "@lincy/eslint-config": "workspace:*",
70
- "@stylistic/eslint-plugin-migrate": "^0.1.2",
71
- "@types/eslint": "^8.44.6",
72
- "@types/node": "^20.8.10",
74
+ "@stylistic/eslint-plugin-migrate": "^1.2.0",
75
+ "@types/eslint": "^8.44.7",
76
+ "@types/node": "^20.9.0",
73
77
  "bumpp": "^9.2.0",
74
- "eslint": "^8.52.0",
75
- "eslint-flat-config-viewer": "^0.1.0",
76
- "esno": "^0.17.0",
77
- "lint-staged": "^15.0.2",
78
+ "eslint": "^8.53.0",
79
+ "eslint-flat-config-viewer": "^0.1.1",
80
+ "esno": "^4.0.0",
81
+ "lint-staged": "^15.1.0",
78
82
  "rimraf": "^5.0.5",
79
83
  "simple-git-hooks": "^2.9.0",
80
84
  "simple-open-url": "^3.0.1",