@antfu/eslint-config 2.2.2 → 2.3.1

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
@@ -120,6 +120,7 @@ Add the following settings to your `.vscode/settings.json`:
120
120
  // Silent the stylistic rules in you IDE, but still auto fix them
121
121
  "eslint.rules.customizations": [
122
122
  { "rule": "style/*", "severity": "off" },
123
+ { "rule": "format/*", "severity": "off" },
123
124
  { "rule": "*-indent", "severity": "off" },
124
125
  { "rule": "*-spacing", "severity": "off" },
125
126
  { "rule": "*-spaces", "severity": "off" },
@@ -267,17 +268,17 @@ Check out the [configs](https://github.com/antfu/eslint-config/blob/main/src/con
267
268
 
268
269
  ### Plugins Renaming
269
270
 
270
- Since flat config requires us to explicitly provide the plugin names (instead of mandatory convention from npm package name), we renamed some plugins to make overall scope more consistent and easier to write.
271
+ Since flat config requires us to explicitly provide the plugin names (instead of the mandatory convention from npm package name), we renamed some plugins to make the overall scope more consistent and easier to write.
271
272
 
272
- | New Prefix | Original Prefix | Source Plugin |
273
- | --- | --- | --- |
274
- | `import/*` | `i/*` | [eslint-plugin-i](https://github.com/un-es/eslint-plugin-i) |
275
- | `node/*` | `n/*` | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) |
276
- | `yaml/*` | `yml/*` | [eslint-plugin-yml](https://github.com/ota-meshi/eslint-plugin-yml) |
277
- | `ts/*` | `@typescript-eslint/*` | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint) |
278
- | `style/*` | `@stylistic/*` | [@stylistic/eslint-plugin](https://github.com/eslint-stylistic/eslint-stylistic) |
279
- | `test/*` | `vitest/*` | [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) |
280
- | `test/*` | `no-only-tests/*` | [eslint-plugin-no-only-tests](https://github.com/levibuzolic/eslint-plugin-no-only-tests) |
273
+ | New Prefix | Original Prefix | Source Plugin |
274
+ | ---------- | ---------------------- | ------------------------------------------------------------------------------------------ |
275
+ | `import/*` | `i/*` | [eslint-plugin-i](https://github.com/un-es/eslint-plugin-i) |
276
+ | `node/*` | `n/*` | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) |
277
+ | `yaml/*` | `yml/*` | [eslint-plugin-yml](https://github.com/ota-meshi/eslint-plugin-yml) |
278
+ | `ts/*` | `@typescript-eslint/*` | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint) |
279
+ | `style/*` | `@stylistic/*` | [@stylistic/eslint-plugin](https://github.com/eslint-stylistic/eslint-stylistic) |
280
+ | `test/*` | `vitest/*` | [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) |
281
+ | `test/*` | `no-only-tests/*` | [eslint-plugin-no-only-tests](https://github.com/levibuzolic/eslint-plugin-no-only-tests) |
281
282
 
282
283
  When you want to override rules, or disable them inline, you need to update to the new prefix:
283
284
 
@@ -337,9 +338,36 @@ export default antfu({
337
338
 
338
339
  We provide some optional configs for specific use cases, that we don't include their dependencies by default.
339
340
 
341
+ #### Formatters
342
+
343
+ > [!WARNING]
344
+ > Experimental feature, changes might not follow semver.
345
+
346
+ Use external formatters to format files that ESLint cannot handle yet (`.css`, `.html`, etc). Powered by [`eslint-plugin-format`](https://github.com/antfu/eslint-plugin-format).
347
+
348
+ ```js
349
+ // eslint.config.js
350
+ import antfu from '@antfu/eslint-config'
351
+
352
+ export default antfu({
353
+ formatters: {
354
+ css: true, // by default use Prettier
355
+ html: true, // by default use Prettier
356
+ toml: 'dprint', // use dprint for TOML
357
+ markdown: 'prettier' // use prettier for markdown
358
+ }
359
+ })
360
+ ```
361
+
362
+ Running `npx eslint` should prompt you to install the required dependencies, otherwise, you can install them manually:
363
+
364
+ ```bash
365
+ npm i -D eslint-plugin-format
366
+ ```
367
+
340
368
  #### React
341
369
 
342
- To enable React support you need to explicitly turn it on:
370
+ To enable React support, you need to explicitly turn it on:
343
371
 
344
372
  ```js
345
373
  // eslint.config.js
@@ -383,7 +411,7 @@ This config also provides some optional plugins/rules for extended usages.
383
411
 
384
412
  This plugin [`eslint-plugin-perfectionist`](https://github.com/azat-io/eslint-plugin-perfectionist) allows you to sorted object keys, imports, etc, with auto-fix.
385
413
 
386
- The plugin is installed but no rules are enabled by default.
414
+ The plugin is installed but no rules are enabled by default.
387
415
 
388
416
  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).
389
417
 
package/dist/cli.cjs CHANGED
@@ -46,7 +46,7 @@ var import_parse_gitignore = __toESM(require("parse-gitignore"), 1);
46
46
  var import_picocolors = __toESM(require("picocolors"), 1);
47
47
 
48
48
  // package.json
49
- var version = "2.2.2";
49
+ var version = "2.3.1";
50
50
  var devDependencies = {
51
51
  "@antfu/eslint-config": "workspace:*",
52
52
  "@antfu/eslint-plugin-prettier": "^5.0.1-1",
@@ -54,13 +54,14 @@ var devDependencies = {
54
54
  "@stylistic/eslint-plugin-migrate": "^1.4.1",
55
55
  "@types/eslint": "^8.44.8",
56
56
  "@types/fs-extra": "^11.0.4",
57
- "@types/node": "^20.10.2",
57
+ "@types/node": "^20.10.3",
58
58
  "@types/prompts": "^2.4.9",
59
59
  "@types/yargs": "^17.0.32",
60
60
  "@unocss/eslint-plugin": "^0.58.0",
61
61
  bumpp: "^9.2.0",
62
62
  eslint: "^8.55.0",
63
63
  "eslint-flat-config-viewer": "^0.1.3",
64
+ "eslint-plugin-format": "^0.0.1",
64
65
  "eslint-plugin-react": "^7.33.2",
65
66
  "eslint-plugin-react-hooks": "^4.6.0",
66
67
  "eslint-plugin-react-refresh": "^0.4.5",
@@ -68,7 +69,7 @@ var devDependencies = {
68
69
  execa: "^8.0.1",
69
70
  "fast-glob": "^3.3.2",
70
71
  "fs-extra": "^11.2.0",
71
- "lint-staged": "^15.1.0",
72
+ "lint-staged": "^15.2.0",
72
73
  rimraf: "^5.0.5",
73
74
  "simple-git-hooks": "^2.9.0",
74
75
  tsup: "^8.0.1",
@@ -99,7 +100,7 @@ var vscodeSettingsString = `
99
100
  // Silent the stylistic rules in you IDE, but still auto fix them
100
101
  "eslint.rules.customizations": [
101
102
  { "rule": "style/*", "severity": "off" },
102
- { "rule": "prettier/*", "severity": "off" },
103
+ { "rule": "format/*", "severity": "off" },
103
104
  { "rule": "*-indent", "severity": "off" },
104
105
  { "rule": "*-spacing", "severity": "off" },
105
106
  { "rule": "*-spaces", "severity": "off" },
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ import parse from "parse-gitignore";
17
17
  import c from "picocolors";
18
18
 
19
19
  // package.json
20
- var version = "2.2.2";
20
+ var version = "2.3.1";
21
21
  var devDependencies = {
22
22
  "@antfu/eslint-config": "workspace:*",
23
23
  "@antfu/eslint-plugin-prettier": "^5.0.1-1",
@@ -25,13 +25,14 @@ var devDependencies = {
25
25
  "@stylistic/eslint-plugin-migrate": "^1.4.1",
26
26
  "@types/eslint": "^8.44.8",
27
27
  "@types/fs-extra": "^11.0.4",
28
- "@types/node": "^20.10.2",
28
+ "@types/node": "^20.10.3",
29
29
  "@types/prompts": "^2.4.9",
30
30
  "@types/yargs": "^17.0.32",
31
31
  "@unocss/eslint-plugin": "^0.58.0",
32
32
  bumpp: "^9.2.0",
33
33
  eslint: "^8.55.0",
34
34
  "eslint-flat-config-viewer": "^0.1.3",
35
+ "eslint-plugin-format": "^0.0.1",
35
36
  "eslint-plugin-react": "^7.33.2",
36
37
  "eslint-plugin-react-hooks": "^4.6.0",
37
38
  "eslint-plugin-react-refresh": "^0.4.5",
@@ -39,7 +40,7 @@ var devDependencies = {
39
40
  execa: "^8.0.1",
40
41
  "fast-glob": "^3.3.2",
41
42
  "fs-extra": "^11.2.0",
42
- "lint-staged": "^15.1.0",
43
+ "lint-staged": "^15.2.0",
43
44
  rimraf: "^5.0.5",
44
45
  "simple-git-hooks": "^2.9.0",
45
46
  tsup: "^8.0.1",
@@ -70,7 +71,7 @@ var vscodeSettingsString = `
70
71
  // Silent the stylistic rules in you IDE, but still auto fix them
71
72
  "eslint.rules.customizations": [
72
73
  { "rule": "style/*", "severity": "off" },
73
- { "rule": "prettier/*", "severity": "off" },
74
+ { "rule": "format/*", "severity": "off" },
74
75
  { "rule": "*-indent", "severity": "off" },
75
76
  { "rule": "*-spacing", "severity": "off" },
76
77
  { "rule": "*-spaces", "severity": "off" },
package/dist/index.cjs CHANGED
@@ -59,6 +59,7 @@ __export(src_exports, {
59
59
  comments: () => comments,
60
60
  default: () => src_default,
61
61
  ensurePackages: () => ensurePackages,
62
+ formatters: () => formatters,
62
63
  ignores: () => ignores,
63
64
  imports: () => imports,
64
65
  interopDefault: () => interopDefault,
@@ -68,7 +69,6 @@ __export(src_exports, {
68
69
  markdown: () => markdown,
69
70
  node: () => node,
70
71
  perfectionist: () => perfectionist,
71
- prettier: () => prettier,
72
72
  react: () => react,
73
73
  renameRules: () => renameRules,
74
74
  sortPackageJson: () => sortPackageJson,
@@ -595,25 +595,47 @@ async function jsonc(options = {}) {
595
595
  }
596
596
 
597
597
  // src/configs/markdown.ts
598
- async function markdown(options = {}) {
598
+ async function markdown(options = {}, formatMarkdown = false) {
599
599
  const {
600
600
  componentExts = [],
601
601
  files = [GLOB_MARKDOWN],
602
602
  overrides = {}
603
603
  } = options;
604
+ const markdown2 = await interopDefault(import("eslint-plugin-markdown"));
605
+ const baseProcessor = markdown2.processors.markdown;
606
+ const processor = !formatMarkdown ? baseProcessor : {
607
+ ...baseProcessor,
608
+ postprocess(messages, filename) {
609
+ const markdownContent = messages.pop();
610
+ const codeSnippets = baseProcessor.postprocess(messages, filename);
611
+ return [
612
+ ...markdownContent || [],
613
+ ...codeSnippets || []
614
+ ];
615
+ },
616
+ preprocess(text, filename) {
617
+ const result = baseProcessor.preprocess(text, filename);
618
+ return [
619
+ ...result,
620
+ {
621
+ filename: ".__markdown_content__",
622
+ text
623
+ }
624
+ ];
625
+ }
626
+ };
604
627
  return [
605
628
  {
606
629
  name: "antfu:markdown:setup",
607
630
  plugins: {
608
- // @ts-expect-error missing types
609
- markdown: await interopDefault(import("eslint-plugin-markdown"))
631
+ markdown: markdown2
610
632
  }
611
633
  },
612
634
  {
613
635
  files,
614
636
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
615
637
  name: "antfu:markdown:processor",
616
- processor: "markdown/markdown"
638
+ processor
617
639
  },
618
640
  {
619
641
  files: [
@@ -755,12 +777,20 @@ async function stylistic(options = {}) {
755
777
  ];
756
778
  }
757
779
 
758
- // src/configs/prettier.ts
759
- async function prettier(options = {}, stylistic2 = {}) {
760
- console.warn("@antfu/eslint-config: `prettier` option is deprecated, please do not use it anymore. We will find better formatters to support that in the future.");
780
+ // src/configs/formatters.ts
781
+ async function formatters(options = {}, stylistic2 = {}) {
761
782
  await ensurePackages([
762
- "@antfu/eslint-plugin-prettier"
783
+ "eslint-plugin-format"
763
784
  ]);
785
+ if (options === true) {
786
+ options = {
787
+ css: true,
788
+ graphql: true,
789
+ html: true,
790
+ markdown: true,
791
+ toml: true
792
+ };
793
+ }
764
794
  const {
765
795
  indent,
766
796
  quotes,
@@ -769,9 +799,6 @@ async function prettier(options = {}, stylistic2 = {}) {
769
799
  ...StylisticConfigDefaults,
770
800
  ...stylistic2
771
801
  };
772
- const {
773
- usePrettierrc = false
774
- } = options;
775
802
  const prettierOptions = Object.assign(
776
803
  {
777
804
  semi,
@@ -780,53 +807,155 @@ async function prettier(options = {}, stylistic2 = {}) {
780
807
  trailingComma: "all",
781
808
  useTabs: indent === "tab"
782
809
  },
783
- options.options || {}
810
+ options.prettierOptions || {}
784
811
  );
785
- const rules = {
786
- ...options.customFiles || {}
787
- };
788
- if (options.css) {
789
- rules.css || (rules.css = [GLOB_CSS, GLOB_POSTCSS]);
790
- rules.less || (rules.less = [GLOB_LESS]);
791
- rules.scss || (rules.scss = [GLOB_SCSS]);
792
- }
793
- if (options.html)
794
- rules.html || (rules.html = ["**/*.html", "**/*.htm"]);
795
- if (options.graphql)
796
- rules.graphql || (rules.graphql = ["**/*.graphql", "**/*.gql"]);
797
- if (!Object.keys(rules).length)
798
- throw new Error("No languages specified for Prettier");
799
- const pluginPrettier = await interopDefault(import("@antfu/eslint-plugin-prettier"));
800
- const parserPlain = await interopDefault(import("eslint-parser-plain"));
801
- return [
812
+ const dprintOptions = Object.assign(
813
+ {
814
+ indentWidth: typeof indent === "number" ? indent : 2,
815
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
816
+ useTabs: indent === "tab"
817
+ },
818
+ options.dprintOptions || {}
819
+ );
820
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
821
+ const configs = [
802
822
  {
803
- name: "antfu:prettier:setup",
823
+ name: "antfu:formatters:setup",
804
824
  plugins: {
805
- prettier: pluginPrettier
825
+ format: pluginFormat
806
826
  }
807
- },
808
- ...Object.entries(rules).map(([name, files]) => ({
809
- files,
827
+ }
828
+ ];
829
+ if (options.css) {
830
+ configs.push(
831
+ {
832
+ files: [GLOB_CSS, GLOB_POSTCSS],
833
+ languageOptions: {
834
+ parser: pluginFormat.parserPlain
835
+ },
836
+ name: "antfu:formatter:css",
837
+ rules: {
838
+ "format/prettier": [
839
+ "error",
840
+ {
841
+ ...prettierOptions,
842
+ parser: "css"
843
+ }
844
+ ]
845
+ }
846
+ },
847
+ {
848
+ files: [GLOB_SCSS],
849
+ languageOptions: {
850
+ parser: pluginFormat.parserPlain
851
+ },
852
+ name: "antfu:formatter:scss",
853
+ rules: {
854
+ "format/prettier": [
855
+ "error",
856
+ {
857
+ ...prettierOptions,
858
+ parser: "scss"
859
+ }
860
+ ]
861
+ }
862
+ },
863
+ {
864
+ files: [GLOB_LESS],
865
+ languageOptions: {
866
+ parser: pluginFormat.parserPlain
867
+ },
868
+ name: "antfu:formatter:less",
869
+ rules: {
870
+ "format/prettier": [
871
+ "error",
872
+ {
873
+ ...prettierOptions,
874
+ parser: "less"
875
+ }
876
+ ]
877
+ }
878
+ }
879
+ );
880
+ }
881
+ if (options.html) {
882
+ configs.push({
883
+ files: ["**/*.html"],
810
884
  languageOptions: {
811
- parser: parserPlain
885
+ parser: pluginFormat.parserPlain
812
886
  },
813
- name: `antfu:prettier:${name}`,
887
+ name: "antfu:formatter:html",
814
888
  rules: {
815
- "prettier/prettier": [
889
+ "format/prettier": [
816
890
  "error",
817
891
  {
818
892
  ...prettierOptions,
819
- embeddedLanguageFormatting: name === "html" ? "auto" : "off",
820
- parser: name
821
- },
893
+ parser: "html"
894
+ }
895
+ ]
896
+ }
897
+ });
898
+ }
899
+ if (options.toml) {
900
+ configs.push({
901
+ files: ["**/*.toml"],
902
+ languageOptions: {
903
+ parser: pluginFormat.parserPlain
904
+ },
905
+ name: "antfu:formatter:toml",
906
+ rules: {
907
+ "format/dprint": [
908
+ "error",
822
909
  {
823
- fullControl: true,
824
- usePrettierrc
910
+ ...dprintOptions,
911
+ language: "toml"
825
912
  }
826
913
  ]
827
914
  }
828
- }))
829
- ];
915
+ });
916
+ }
917
+ if (options.markdown) {
918
+ const formater = options.markdown === true ? "prettier" : options.markdown;
919
+ configs.push({
920
+ files: ["**/*.__markdown_content__"],
921
+ languageOptions: {
922
+ parser: pluginFormat.parserPlain
923
+ },
924
+ name: "antfu:formatter:markdown",
925
+ rules: {
926
+ [`format/${formater}`]: [
927
+ "error",
928
+ formater === "prettier" ? {
929
+ ...prettierOptions,
930
+ embeddedLanguageFormatting: "off",
931
+ parser: "markdown"
932
+ } : {
933
+ ...dprintOptions,
934
+ language: "markdown"
935
+ }
936
+ ]
937
+ }
938
+ });
939
+ }
940
+ if (options.graphql) {
941
+ configs.push({
942
+ files: ["**/*.graphql"],
943
+ languageOptions: {
944
+ parser: pluginFormat.parserPlain
945
+ },
946
+ name: "antfu:formatter:graphql",
947
+ rules: {
948
+ "format/prettier": [
949
+ "error",
950
+ {
951
+ ...prettierOptions,
952
+ parser: "graphql"
953
+ }
954
+ ]
955
+ }
956
+ });
957
+ }
958
+ return configs;
830
959
  }
831
960
 
832
961
  // src/configs/react.ts
@@ -1686,14 +1815,19 @@ async function antfu(options = {}, ...userConfigs) {
1686
1815
  }));
1687
1816
  }
1688
1817
  if (options.markdown ?? true) {
1689
- configs.push(markdown({
1690
- componentExts,
1691
- overrides: overrides.markdown
1692
- }));
1818
+ configs.push(
1819
+ markdown(
1820
+ {
1821
+ componentExts,
1822
+ overrides: overrides.markdown
1823
+ },
1824
+ options.formatters === true || !!(options.formatters || {})?.markdown
1825
+ )
1826
+ );
1693
1827
  }
1694
- if (options.prettier) {
1695
- configs.push(prettier(
1696
- options.prettier,
1828
+ if (options.formatters) {
1829
+ configs.push(formatters(
1830
+ options.formatters,
1697
1831
  typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1698
1832
  ));
1699
1833
  }
@@ -1743,6 +1877,7 @@ var src_default = antfu;
1743
1877
  combine,
1744
1878
  comments,
1745
1879
  ensurePackages,
1880
+ formatters,
1746
1881
  ignores,
1747
1882
  imports,
1748
1883
  interopDefault,
@@ -1752,7 +1887,6 @@ var src_default = antfu;
1752
1887
  markdown,
1753
1888
  node,
1754
1889
  perfectionist,
1755
- prettier,
1756
1890
  react,
1757
1891
  renameRules,
1758
1892
  sortPackageJson,
package/dist/index.d.cts CHANGED
@@ -130,37 +130,49 @@ interface OptionsFiles {
130
130
  */
131
131
  files?: string[];
132
132
  }
133
- interface OptionsPrettier {
133
+ interface OptionsFormatters {
134
134
  /**
135
- * Enable Prettier support for CSS, Less, Sass, and SCSS.
135
+ * Enable formatting support for CSS, Less, Sass, and SCSS.
136
+ *
137
+ * Currently only support Prettier.
136
138
  */
137
- css?: boolean;
139
+ css?: 'prettier' | boolean;
138
140
  /**
139
- * Enable Prettier support for HTML.
141
+ * Enable formatting support for HTML.
142
+ *
143
+ * Currently only support Prettier.
140
144
  */
141
- html?: boolean;
145
+ html?: 'prettier' | boolean;
142
146
  /**
143
- * Enable Prettier support for GraphQL.
147
+ * Enable formatting support for TOML.
148
+ *
149
+ * Currently only support dprint.
144
150
  */
145
- graphql?: boolean;
151
+ toml?: 'dprint' | boolean;
146
152
  /**
147
- * Custom files to apply Prettier.
153
+ * Enable formatting support for Markdown.
148
154
  *
149
- * The key is the parser in prettier, the value is the glob pattern.
155
+ * Support both Prettier and dprint.
156
+ *
157
+ * When set to `true`, it will use Prettier.
158
+ */
159
+ markdown?: 'prettier' | 'dprint' | boolean;
160
+ /**
161
+ * Enable formatting support for GraphQL.
150
162
  */
151
- customFiles?: Record<string, string[]>;
163
+ graphql?: 'prettier' | boolean;
152
164
  /**
153
165
  * Custom options for Prettier.
154
166
  *
155
167
  * By default it's controlled by our own config.
156
168
  */
157
- options?: VendoredPrettierOptions;
169
+ prettierOptions?: VendoredPrettierOptions;
158
170
  /**
159
- * Use the prettierrc file.
171
+ * Custom options for dprint.
160
172
  *
161
- * @default false
173
+ * By default it's controlled by our own config.
162
174
  */
163
- usePrettierrc?: boolean;
175
+ dprintOptions?: boolean;
164
176
  }
165
177
  interface OptionsComponentExts {
166
178
  /**
@@ -293,14 +305,16 @@ interface OptionsConfig extends OptionsComponentExts {
293
305
  */
294
306
  unocss?: boolean | OptionsUnoCSS;
295
307
  /**
296
- * Use Prettier to format files that not supported by ESLint.
308
+ * Use external formatters to format files.
297
309
  *
298
310
  * Requires installing:
299
- * - `eslint-plugin-prettier`
311
+ * - `eslint-plugin-format`
312
+ *
313
+ * When set to `true`, it will enable all formatters.
300
314
  *
301
315
  * @default false
302
316
  */
303
- prettier?: OptionsPrettier;
317
+ formatters?: boolean | OptionsFormatters;
304
318
  /**
305
319
  * Control to disable some rules in editors.
306
320
  * @default auto-detect based on the process.env
@@ -338,7 +352,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
338
352
 
339
353
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
340
354
 
341
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
355
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
342
356
 
343
357
  declare function node(): Promise<FlatConfigItem[]>;
344
358
 
@@ -349,10 +363,7 @@ declare function node(): Promise<FlatConfigItem[]>;
349
363
  */
350
364
  declare function perfectionist(): Promise<FlatConfigItem[]>;
351
365
 
352
- /**
353
- * @deprecated
354
- */
355
- declare function prettier(options?: OptionsPrettier, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
366
+ declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
356
367
 
357
368
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
358
369
 
@@ -421,4 +432,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
421
432
  } ? U : T>;
422
433
  declare function ensurePackages(packages: string[]): Promise<void>;
423
434
 
424
- export { type Awaitable, type FlatConfigItem, 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_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, type OptionsComponentExts, type OptionsConfig, type OptionsFiles, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsPrettier, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsUnoCSS, type Rules, type StylisticConfig, StylisticConfigDefaults, type UserConfigItem, type WrapRuleConfig, antfu, combine, comments, antfu as default, ensurePackages, ignores, imports, interopDefault, javascript, jsdoc, jsonc, markdown, node, perfectionist, prettier, react, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, unocss, vue, yaml };
435
+ export { type Awaitable, type FlatConfigItem, 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_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, type OptionsComponentExts, type OptionsConfig, type OptionsFiles, type OptionsFormatters, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsUnoCSS, type Rules, type StylisticConfig, StylisticConfigDefaults, type UserConfigItem, type WrapRuleConfig, antfu, combine, comments, antfu as default, ensurePackages, formatters, ignores, imports, interopDefault, javascript, jsdoc, jsonc, markdown, node, perfectionist, react, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, unocss, vue, yaml };
package/dist/index.d.ts CHANGED
@@ -130,37 +130,49 @@ interface OptionsFiles {
130
130
  */
131
131
  files?: string[];
132
132
  }
133
- interface OptionsPrettier {
133
+ interface OptionsFormatters {
134
134
  /**
135
- * Enable Prettier support for CSS, Less, Sass, and SCSS.
135
+ * Enable formatting support for CSS, Less, Sass, and SCSS.
136
+ *
137
+ * Currently only support Prettier.
136
138
  */
137
- css?: boolean;
139
+ css?: 'prettier' | boolean;
138
140
  /**
139
- * Enable Prettier support for HTML.
141
+ * Enable formatting support for HTML.
142
+ *
143
+ * Currently only support Prettier.
140
144
  */
141
- html?: boolean;
145
+ html?: 'prettier' | boolean;
142
146
  /**
143
- * Enable Prettier support for GraphQL.
147
+ * Enable formatting support for TOML.
148
+ *
149
+ * Currently only support dprint.
144
150
  */
145
- graphql?: boolean;
151
+ toml?: 'dprint' | boolean;
146
152
  /**
147
- * Custom files to apply Prettier.
153
+ * Enable formatting support for Markdown.
148
154
  *
149
- * The key is the parser in prettier, the value is the glob pattern.
155
+ * Support both Prettier and dprint.
156
+ *
157
+ * When set to `true`, it will use Prettier.
158
+ */
159
+ markdown?: 'prettier' | 'dprint' | boolean;
160
+ /**
161
+ * Enable formatting support for GraphQL.
150
162
  */
151
- customFiles?: Record<string, string[]>;
163
+ graphql?: 'prettier' | boolean;
152
164
  /**
153
165
  * Custom options for Prettier.
154
166
  *
155
167
  * By default it's controlled by our own config.
156
168
  */
157
- options?: VendoredPrettierOptions;
169
+ prettierOptions?: VendoredPrettierOptions;
158
170
  /**
159
- * Use the prettierrc file.
171
+ * Custom options for dprint.
160
172
  *
161
- * @default false
173
+ * By default it's controlled by our own config.
162
174
  */
163
- usePrettierrc?: boolean;
175
+ dprintOptions?: boolean;
164
176
  }
165
177
  interface OptionsComponentExts {
166
178
  /**
@@ -293,14 +305,16 @@ interface OptionsConfig extends OptionsComponentExts {
293
305
  */
294
306
  unocss?: boolean | OptionsUnoCSS;
295
307
  /**
296
- * Use Prettier to format files that not supported by ESLint.
308
+ * Use external formatters to format files.
297
309
  *
298
310
  * Requires installing:
299
- * - `eslint-plugin-prettier`
311
+ * - `eslint-plugin-format`
312
+ *
313
+ * When set to `true`, it will enable all formatters.
300
314
  *
301
315
  * @default false
302
316
  */
303
- prettier?: OptionsPrettier;
317
+ formatters?: boolean | OptionsFormatters;
304
318
  /**
305
319
  * Control to disable some rules in editors.
306
320
  * @default auto-detect based on the process.env
@@ -338,7 +352,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
338
352
 
339
353
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
340
354
 
341
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
355
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
342
356
 
343
357
  declare function node(): Promise<FlatConfigItem[]>;
344
358
 
@@ -349,10 +363,7 @@ declare function node(): Promise<FlatConfigItem[]>;
349
363
  */
350
364
  declare function perfectionist(): Promise<FlatConfigItem[]>;
351
365
 
352
- /**
353
- * @deprecated
354
- */
355
- declare function prettier(options?: OptionsPrettier, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
366
+ declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
356
367
 
357
368
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
358
369
 
@@ -421,4 +432,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
421
432
  } ? U : T>;
422
433
  declare function ensurePackages(packages: string[]): Promise<void>;
423
434
 
424
- export { type Awaitable, type FlatConfigItem, 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_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, type OptionsComponentExts, type OptionsConfig, type OptionsFiles, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsPrettier, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsUnoCSS, type Rules, type StylisticConfig, StylisticConfigDefaults, type UserConfigItem, type WrapRuleConfig, antfu, combine, comments, antfu as default, ensurePackages, ignores, imports, interopDefault, javascript, jsdoc, jsonc, markdown, node, perfectionist, prettier, react, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, unocss, vue, yaml };
435
+ export { type Awaitable, type FlatConfigItem, 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_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_TESTS, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_YAML, type OptionsComponentExts, type OptionsConfig, type OptionsFiles, type OptionsFormatters, type OptionsHasTypeScript, type OptionsIsInEditor, type OptionsOverrides, type OptionsStylistic, type OptionsTypeScriptParserOptions, type OptionsTypeScriptWithTypes, type OptionsUnoCSS, type Rules, type StylisticConfig, StylisticConfigDefaults, type UserConfigItem, type WrapRuleConfig, antfu, combine, comments, antfu as default, ensurePackages, formatters, ignores, imports, interopDefault, javascript, jsdoc, jsonc, markdown, node, perfectionist, react, renameRules, sortPackageJson, sortTsconfig, stylistic, test, toArray, typescript, unicorn, unocss, vue, yaml };
package/dist/index.js CHANGED
@@ -509,25 +509,47 @@ async function jsonc(options = {}) {
509
509
  }
510
510
 
511
511
  // src/configs/markdown.ts
512
- async function markdown(options = {}) {
512
+ async function markdown(options = {}, formatMarkdown = false) {
513
513
  const {
514
514
  componentExts = [],
515
515
  files = [GLOB_MARKDOWN],
516
516
  overrides = {}
517
517
  } = options;
518
+ const markdown2 = await interopDefault(import("eslint-plugin-markdown"));
519
+ const baseProcessor = markdown2.processors.markdown;
520
+ const processor = !formatMarkdown ? baseProcessor : {
521
+ ...baseProcessor,
522
+ postprocess(messages, filename) {
523
+ const markdownContent = messages.pop();
524
+ const codeSnippets = baseProcessor.postprocess(messages, filename);
525
+ return [
526
+ ...markdownContent || [],
527
+ ...codeSnippets || []
528
+ ];
529
+ },
530
+ preprocess(text, filename) {
531
+ const result = baseProcessor.preprocess(text, filename);
532
+ return [
533
+ ...result,
534
+ {
535
+ filename: ".__markdown_content__",
536
+ text
537
+ }
538
+ ];
539
+ }
540
+ };
518
541
  return [
519
542
  {
520
543
  name: "antfu:markdown:setup",
521
544
  plugins: {
522
- // @ts-expect-error missing types
523
- markdown: await interopDefault(import("eslint-plugin-markdown"))
545
+ markdown: markdown2
524
546
  }
525
547
  },
526
548
  {
527
549
  files,
528
550
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
529
551
  name: "antfu:markdown:processor",
530
- processor: "markdown/markdown"
552
+ processor
531
553
  },
532
554
  {
533
555
  files: [
@@ -669,12 +691,20 @@ async function stylistic(options = {}) {
669
691
  ];
670
692
  }
671
693
 
672
- // src/configs/prettier.ts
673
- async function prettier(options = {}, stylistic2 = {}) {
674
- console.warn("@antfu/eslint-config: `prettier` option is deprecated, please do not use it anymore. We will find better formatters to support that in the future.");
694
+ // src/configs/formatters.ts
695
+ async function formatters(options = {}, stylistic2 = {}) {
675
696
  await ensurePackages([
676
- "@antfu/eslint-plugin-prettier"
697
+ "eslint-plugin-format"
677
698
  ]);
699
+ if (options === true) {
700
+ options = {
701
+ css: true,
702
+ graphql: true,
703
+ html: true,
704
+ markdown: true,
705
+ toml: true
706
+ };
707
+ }
678
708
  const {
679
709
  indent,
680
710
  quotes,
@@ -683,9 +713,6 @@ async function prettier(options = {}, stylistic2 = {}) {
683
713
  ...StylisticConfigDefaults,
684
714
  ...stylistic2
685
715
  };
686
- const {
687
- usePrettierrc = false
688
- } = options;
689
716
  const prettierOptions = Object.assign(
690
717
  {
691
718
  semi,
@@ -694,53 +721,155 @@ async function prettier(options = {}, stylistic2 = {}) {
694
721
  trailingComma: "all",
695
722
  useTabs: indent === "tab"
696
723
  },
697
- options.options || {}
724
+ options.prettierOptions || {}
698
725
  );
699
- const rules = {
700
- ...options.customFiles || {}
701
- };
702
- if (options.css) {
703
- rules.css || (rules.css = [GLOB_CSS, GLOB_POSTCSS]);
704
- rules.less || (rules.less = [GLOB_LESS]);
705
- rules.scss || (rules.scss = [GLOB_SCSS]);
706
- }
707
- if (options.html)
708
- rules.html || (rules.html = ["**/*.html", "**/*.htm"]);
709
- if (options.graphql)
710
- rules.graphql || (rules.graphql = ["**/*.graphql", "**/*.gql"]);
711
- if (!Object.keys(rules).length)
712
- throw new Error("No languages specified for Prettier");
713
- const pluginPrettier = await interopDefault(import("@antfu/eslint-plugin-prettier"));
714
- const parserPlain = await interopDefault(import("eslint-parser-plain"));
715
- return [
726
+ const dprintOptions = Object.assign(
727
+ {
728
+ indentWidth: typeof indent === "number" ? indent : 2,
729
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
730
+ useTabs: indent === "tab"
731
+ },
732
+ options.dprintOptions || {}
733
+ );
734
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
735
+ const configs = [
716
736
  {
717
- name: "antfu:prettier:setup",
737
+ name: "antfu:formatters:setup",
718
738
  plugins: {
719
- prettier: pluginPrettier
739
+ format: pluginFormat
720
740
  }
721
- },
722
- ...Object.entries(rules).map(([name, files]) => ({
723
- files,
741
+ }
742
+ ];
743
+ if (options.css) {
744
+ configs.push(
745
+ {
746
+ files: [GLOB_CSS, GLOB_POSTCSS],
747
+ languageOptions: {
748
+ parser: pluginFormat.parserPlain
749
+ },
750
+ name: "antfu:formatter:css",
751
+ rules: {
752
+ "format/prettier": [
753
+ "error",
754
+ {
755
+ ...prettierOptions,
756
+ parser: "css"
757
+ }
758
+ ]
759
+ }
760
+ },
761
+ {
762
+ files: [GLOB_SCSS],
763
+ languageOptions: {
764
+ parser: pluginFormat.parserPlain
765
+ },
766
+ name: "antfu:formatter:scss",
767
+ rules: {
768
+ "format/prettier": [
769
+ "error",
770
+ {
771
+ ...prettierOptions,
772
+ parser: "scss"
773
+ }
774
+ ]
775
+ }
776
+ },
777
+ {
778
+ files: [GLOB_LESS],
779
+ languageOptions: {
780
+ parser: pluginFormat.parserPlain
781
+ },
782
+ name: "antfu:formatter:less",
783
+ rules: {
784
+ "format/prettier": [
785
+ "error",
786
+ {
787
+ ...prettierOptions,
788
+ parser: "less"
789
+ }
790
+ ]
791
+ }
792
+ }
793
+ );
794
+ }
795
+ if (options.html) {
796
+ configs.push({
797
+ files: ["**/*.html"],
724
798
  languageOptions: {
725
- parser: parserPlain
799
+ parser: pluginFormat.parserPlain
726
800
  },
727
- name: `antfu:prettier:${name}`,
801
+ name: "antfu:formatter:html",
728
802
  rules: {
729
- "prettier/prettier": [
803
+ "format/prettier": [
730
804
  "error",
731
805
  {
732
806
  ...prettierOptions,
733
- embeddedLanguageFormatting: name === "html" ? "auto" : "off",
734
- parser: name
735
- },
807
+ parser: "html"
808
+ }
809
+ ]
810
+ }
811
+ });
812
+ }
813
+ if (options.toml) {
814
+ configs.push({
815
+ files: ["**/*.toml"],
816
+ languageOptions: {
817
+ parser: pluginFormat.parserPlain
818
+ },
819
+ name: "antfu:formatter:toml",
820
+ rules: {
821
+ "format/dprint": [
822
+ "error",
736
823
  {
737
- fullControl: true,
738
- usePrettierrc
824
+ ...dprintOptions,
825
+ language: "toml"
739
826
  }
740
827
  ]
741
828
  }
742
- }))
743
- ];
829
+ });
830
+ }
831
+ if (options.markdown) {
832
+ const formater = options.markdown === true ? "prettier" : options.markdown;
833
+ configs.push({
834
+ files: ["**/*.__markdown_content__"],
835
+ languageOptions: {
836
+ parser: pluginFormat.parserPlain
837
+ },
838
+ name: "antfu:formatter:markdown",
839
+ rules: {
840
+ [`format/${formater}`]: [
841
+ "error",
842
+ formater === "prettier" ? {
843
+ ...prettierOptions,
844
+ embeddedLanguageFormatting: "off",
845
+ parser: "markdown"
846
+ } : {
847
+ ...dprintOptions,
848
+ language: "markdown"
849
+ }
850
+ ]
851
+ }
852
+ });
853
+ }
854
+ if (options.graphql) {
855
+ configs.push({
856
+ files: ["**/*.graphql"],
857
+ languageOptions: {
858
+ parser: pluginFormat.parserPlain
859
+ },
860
+ name: "antfu:formatter:graphql",
861
+ rules: {
862
+ "format/prettier": [
863
+ "error",
864
+ {
865
+ ...prettierOptions,
866
+ parser: "graphql"
867
+ }
868
+ ]
869
+ }
870
+ });
871
+ }
872
+ return configs;
744
873
  }
745
874
 
746
875
  // src/configs/react.ts
@@ -1600,14 +1729,19 @@ async function antfu(options = {}, ...userConfigs) {
1600
1729
  }));
1601
1730
  }
1602
1731
  if (options.markdown ?? true) {
1603
- configs.push(markdown({
1604
- componentExts,
1605
- overrides: overrides.markdown
1606
- }));
1732
+ configs.push(
1733
+ markdown(
1734
+ {
1735
+ componentExts,
1736
+ overrides: overrides.markdown
1737
+ },
1738
+ options.formatters === true || !!(options.formatters || {})?.markdown
1739
+ )
1740
+ );
1607
1741
  }
1608
- if (options.prettier) {
1609
- configs.push(prettier(
1610
- options.prettier,
1742
+ if (options.formatters) {
1743
+ configs.push(formatters(
1744
+ options.formatters,
1611
1745
  typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1612
1746
  ));
1613
1747
  }
@@ -1657,6 +1791,7 @@ export {
1657
1791
  comments,
1658
1792
  src_default as default,
1659
1793
  ensurePackages,
1794
+ formatters,
1660
1795
  ignores,
1661
1796
  imports,
1662
1797
  interopDefault,
@@ -1666,7 +1801,6 @@ export {
1666
1801
  markdown,
1667
1802
  node,
1668
1803
  perfectionist,
1669
- prettier,
1670
1804
  react,
1671
1805
  renameRules,
1672
1806
  sortPackageJson,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@antfu/eslint-config",
3
3
  "type": "module",
4
- "version": "2.2.2",
4
+ "version": "2.3.1",
5
5
  "packageManager": "pnpm@8.11.0",
6
6
  "description": "Anthony's ESLint config",
7
7
  "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
@@ -25,15 +25,15 @@
25
25
  "dist"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@antfu/eslint-plugin-prettier": "^5.0.1-1",
29
28
  "@unocss/eslint-plugin": ">=0.50.0",
30
29
  "eslint": ">=8.40.0",
30
+ "eslint-plugin-format": "^0.0.1",
31
31
  "eslint-plugin-react": "^7.33.2",
32
32
  "eslint-plugin-react-hooks": "^4.6.0",
33
33
  "eslint-plugin-react-refresh": "^0.4.4"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
- "@antfu/eslint-plugin-prettier": {
36
+ "eslint-plugin-format": {
37
37
  "optional": true
38
38
  },
39
39
  "@unocss/eslint-plugin": {
@@ -59,8 +59,7 @@
59
59
  "@typescript-eslint/eslint-plugin": "^6.13.1",
60
60
  "@typescript-eslint/parser": "^6.13.1",
61
61
  "eslint-config-flat-gitignore": "^0.1.2",
62
- "eslint-parser-plain": "^0.1.0",
63
- "eslint-plugin-antfu": "^1.0.13",
62
+ "eslint-plugin-antfu": "^2.0.0",
64
63
  "eslint-plugin-eslint-comments": "^3.2.0",
65
64
  "eslint-plugin-i": "^2.29.0",
66
65
  "eslint-plugin-jsdoc": "^46.9.0",
@@ -90,13 +89,14 @@
90
89
  "@stylistic/eslint-plugin-migrate": "^1.4.1",
91
90
  "@types/eslint": "^8.44.8",
92
91
  "@types/fs-extra": "^11.0.4",
93
- "@types/node": "^20.10.2",
92
+ "@types/node": "^20.10.3",
94
93
  "@types/prompts": "^2.4.9",
95
94
  "@types/yargs": "^17.0.32",
96
95
  "@unocss/eslint-plugin": "^0.58.0",
97
96
  "bumpp": "^9.2.0",
98
97
  "eslint": "^8.55.0",
99
98
  "eslint-flat-config-viewer": "^0.1.3",
99
+ "eslint-plugin-format": "^0.0.1",
100
100
  "eslint-plugin-react": "^7.33.2",
101
101
  "eslint-plugin-react-hooks": "^4.6.0",
102
102
  "eslint-plugin-react-refresh": "^0.4.5",
@@ -104,13 +104,13 @@
104
104
  "execa": "^8.0.1",
105
105
  "fast-glob": "^3.3.2",
106
106
  "fs-extra": "^11.2.0",
107
- "lint-staged": "^15.1.0",
107
+ "lint-staged": "^15.2.0",
108
108
  "rimraf": "^5.0.5",
109
109
  "simple-git-hooks": "^2.9.0",
110
110
  "tsup": "^8.0.1",
111
111
  "typescript": "^5.3.2",
112
112
  "vitest": "^0.34.6",
113
- "@antfu/eslint-config": "2.2.2"
113
+ "@antfu/eslint-config": "2.3.1"
114
114
  },
115
115
  "simple-git-hooks": {
116
116
  "pre-commit": "pnpm lint-staged"