@antfu/eslint-config 2.2.2 → 2.3.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
@@ -267,17 +267,17 @@ Check out the [configs](https://github.com/antfu/eslint-config/blob/main/src/con
267
267
 
268
268
  ### Plugins Renaming
269
269
 
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
-
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) |
270
+ 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
+ | 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) |
281
281
 
282
282
  When you want to override rules, or disable them inline, you need to update to the new prefix:
283
283
 
@@ -337,9 +337,36 @@ export default antfu({
337
337
 
338
338
  We provide some optional configs for specific use cases, that we don't include their dependencies by default.
339
339
 
340
+ #### Formatters
341
+
342
+ > [!WARNING]
343
+ > Experimental feature, changes might not follow semver.
344
+
345
+ 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).
346
+
347
+ ```js
348
+ // eslint.config.js
349
+ import antfu from '@antfu/eslint-config'
350
+
351
+ export default antfu({
352
+ formatters: {
353
+ css: true, // by default use Prettier
354
+ html: true, // by default use Prettier
355
+ toml: 'dprint', // use dprint for TOML
356
+ markdown: 'prettier' // use prettier for markdown
357
+ }
358
+ })
359
+ ```
360
+
361
+ Running `npx eslint` should prompt you to install the required dependencies, otherwise, you can install them manually:
362
+
363
+ ```bash
364
+ npm i -D eslint-plugin-format
365
+ ```
366
+
340
367
  #### React
341
368
 
342
- To enable React support you need to explicitly turn it on:
369
+ To enable React support, you need to explicitly turn it on:
343
370
 
344
371
  ```js
345
372
  // eslint.config.js
@@ -383,7 +410,7 @@ This config also provides some optional plugins/rules for extended usages.
383
410
 
384
411
  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
412
 
386
- The plugin is installed but no rules are enabled by default.
413
+ The plugin is installed but no rules are enabled by default.
387
414
 
388
415
  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
416
 
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.0";
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",
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.0";
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",
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,11 +777,10 @@ 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
  ]);
764
785
  const {
765
786
  indent,
@@ -769,9 +790,6 @@ async function prettier(options = {}, stylistic2 = {}) {
769
790
  ...StylisticConfigDefaults,
770
791
  ...stylistic2
771
792
  };
772
- const {
773
- usePrettierrc = false
774
- } = options;
775
793
  const prettierOptions = Object.assign(
776
794
  {
777
795
  semi,
@@ -780,53 +798,137 @@ async function prettier(options = {}, stylistic2 = {}) {
780
798
  trailingComma: "all",
781
799
  useTabs: indent === "tab"
782
800
  },
783
- options.options || {}
801
+ options.prettierOptions || {}
784
802
  );
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 [
803
+ const dprintOptions = Object.assign(
804
+ {
805
+ indentWidth: typeof indent === "number" ? indent : 2,
806
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
807
+ useTabs: indent === "tab"
808
+ },
809
+ options.dprintOptions || {}
810
+ );
811
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
812
+ const configs = [
802
813
  {
803
- name: "antfu:prettier:setup",
814
+ name: "antfu:formatters:setup",
804
815
  plugins: {
805
- prettier: pluginPrettier
816
+ format: pluginFormat
806
817
  }
807
- },
808
- ...Object.entries(rules).map(([name, files]) => ({
809
- files,
818
+ }
819
+ ];
820
+ if (options.css) {
821
+ configs.push(
822
+ {
823
+ files: [GLOB_CSS, GLOB_POSTCSS],
824
+ languageOptions: {
825
+ parser: pluginFormat.parserPlain
826
+ },
827
+ name: "antfu:formatter:css",
828
+ rules: {
829
+ "format/prettier": [
830
+ "error",
831
+ {
832
+ ...prettierOptions,
833
+ parser: "css"
834
+ }
835
+ ]
836
+ }
837
+ },
838
+ {
839
+ files: [GLOB_SCSS],
840
+ languageOptions: {
841
+ parser: pluginFormat.parserPlain
842
+ },
843
+ name: "antfu:formatter:scss",
844
+ rules: {
845
+ "format/prettier": [
846
+ "error",
847
+ {
848
+ ...prettierOptions,
849
+ parser: "scss"
850
+ }
851
+ ]
852
+ }
853
+ },
854
+ {
855
+ files: [GLOB_LESS],
856
+ languageOptions: {
857
+ parser: pluginFormat.parserPlain
858
+ },
859
+ name: "antfu:formatter:less",
860
+ rules: {
861
+ "format/prettier": [
862
+ "error",
863
+ {
864
+ ...prettierOptions,
865
+ parser: "less"
866
+ }
867
+ ]
868
+ }
869
+ }
870
+ );
871
+ }
872
+ if (options.html) {
873
+ configs.push({
874
+ files: ["**/*.html"],
810
875
  languageOptions: {
811
- parser: parserPlain
876
+ parser: pluginFormat.parserPlain
812
877
  },
813
- name: `antfu:prettier:${name}`,
878
+ name: "antfu:formatter:html",
814
879
  rules: {
815
- "prettier/prettier": [
880
+ "format/prettier": [
816
881
  "error",
817
882
  {
818
883
  ...prettierOptions,
819
- embeddedLanguageFormatting: name === "html" ? "auto" : "off",
820
- parser: name
821
- },
884
+ parser: "html"
885
+ }
886
+ ]
887
+ }
888
+ });
889
+ }
890
+ if (options.toml) {
891
+ configs.push({
892
+ files: ["**/*.toml"],
893
+ languageOptions: {
894
+ parser: pluginFormat.parserPlain
895
+ },
896
+ name: "antfu:formatter:toml",
897
+ rules: {
898
+ "format/dprint": [
899
+ "error",
822
900
  {
823
- fullControl: true,
824
- usePrettierrc
901
+ ...dprintOptions,
902
+ language: "toml"
825
903
  }
826
904
  ]
827
905
  }
828
- }))
829
- ];
906
+ });
907
+ }
908
+ if (options.markdown) {
909
+ const formater = options.markdown === true ? "prettier" : options.markdown;
910
+ configs.push({
911
+ files: ["**/*.__markdown_content__"],
912
+ languageOptions: {
913
+ parser: pluginFormat.parserPlain
914
+ },
915
+ name: "antfu:formatter:markdown",
916
+ rules: {
917
+ [`format/${formater}`]: [
918
+ "error",
919
+ formater === "prettier" ? {
920
+ ...prettierOptions,
921
+ embeddedLanguageFormatting: "off",
922
+ parser: "markdown"
923
+ } : {
924
+ ...dprintOptions,
925
+ language: "markdown"
926
+ }
927
+ ]
928
+ }
929
+ });
930
+ }
931
+ return configs;
830
932
  }
831
933
 
832
934
  // src/configs/react.ts
@@ -1686,14 +1788,19 @@ async function antfu(options = {}, ...userConfigs) {
1686
1788
  }));
1687
1789
  }
1688
1790
  if (options.markdown ?? true) {
1689
- configs.push(markdown({
1690
- componentExts,
1691
- overrides: overrides.markdown
1692
- }));
1791
+ configs.push(
1792
+ markdown(
1793
+ {
1794
+ componentExts,
1795
+ overrides: overrides.markdown
1796
+ },
1797
+ !!options.formatters?.markdown
1798
+ )
1799
+ );
1693
1800
  }
1694
- if (options.prettier) {
1695
- configs.push(prettier(
1696
- options.prettier,
1801
+ if (options.formatters) {
1802
+ configs.push(formatters(
1803
+ options.formatters,
1697
1804
  typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1698
1805
  ));
1699
1806
  }
@@ -1743,6 +1850,7 @@ var src_default = antfu;
1743
1850
  combine,
1744
1851
  comments,
1745
1852
  ensurePackages,
1853
+ formatters,
1746
1854
  ignores,
1747
1855
  imports,
1748
1856
  interopDefault,
@@ -1752,7 +1860,6 @@ var src_default = antfu;
1752
1860
  markdown,
1753
1861
  node,
1754
1862
  perfectionist,
1755
- prettier,
1756
1863
  react,
1757
1864
  renameRules,
1758
1865
  sortPackageJson,
package/dist/index.d.cts CHANGED
@@ -130,37 +130,45 @@ 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.
154
+ *
155
+ * Support both Prettier and dprint.
148
156
  *
149
- * The key is the parser in prettier, the value is the glob pattern.
157
+ * When set to `true`, it will use Prettier.
150
158
  */
151
- customFiles?: Record<string, string[]>;
159
+ markdown?: 'prettier' | 'dprint' | boolean;
152
160
  /**
153
161
  * Custom options for Prettier.
154
162
  *
155
163
  * By default it's controlled by our own config.
156
164
  */
157
- options?: VendoredPrettierOptions;
165
+ prettierOptions?: VendoredPrettierOptions;
158
166
  /**
159
- * Use the prettierrc file.
167
+ * Custom options for dprint.
160
168
  *
161
- * @default false
169
+ * By default it's controlled by our own config.
162
170
  */
163
- usePrettierrc?: boolean;
171
+ dprintOptions?: boolean;
164
172
  }
165
173
  interface OptionsComponentExts {
166
174
  /**
@@ -293,14 +301,14 @@ interface OptionsConfig extends OptionsComponentExts {
293
301
  */
294
302
  unocss?: boolean | OptionsUnoCSS;
295
303
  /**
296
- * Use Prettier to format files that not supported by ESLint.
304
+ * Use external formatters to format files.
297
305
  *
298
306
  * Requires installing:
299
- * - `eslint-plugin-prettier`
307
+ * - `eslint-plugin-format`
300
308
  *
301
309
  * @default false
302
310
  */
303
- prettier?: OptionsPrettier;
311
+ formatters?: OptionsFormatters;
304
312
  /**
305
313
  * Control to disable some rules in editors.
306
314
  * @default auto-detect based on the process.env
@@ -338,7 +346,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
338
346
 
339
347
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
340
348
 
341
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
349
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
342
350
 
343
351
  declare function node(): Promise<FlatConfigItem[]>;
344
352
 
@@ -349,10 +357,7 @@ declare function node(): Promise<FlatConfigItem[]>;
349
357
  */
350
358
  declare function perfectionist(): Promise<FlatConfigItem[]>;
351
359
 
352
- /**
353
- * @deprecated
354
- */
355
- declare function prettier(options?: OptionsPrettier, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
360
+ declare function formatters(options?: OptionsFormatters, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
356
361
 
357
362
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
358
363
 
@@ -421,4 +426,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
421
426
  } ? U : T>;
422
427
  declare function ensurePackages(packages: string[]): Promise<void>;
423
428
 
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 };
429
+ 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,45 @@ 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.
154
+ *
155
+ * Support both Prettier and dprint.
148
156
  *
149
- * The key is the parser in prettier, the value is the glob pattern.
157
+ * When set to `true`, it will use Prettier.
150
158
  */
151
- customFiles?: Record<string, string[]>;
159
+ markdown?: 'prettier' | 'dprint' | boolean;
152
160
  /**
153
161
  * Custom options for Prettier.
154
162
  *
155
163
  * By default it's controlled by our own config.
156
164
  */
157
- options?: VendoredPrettierOptions;
165
+ prettierOptions?: VendoredPrettierOptions;
158
166
  /**
159
- * Use the prettierrc file.
167
+ * Custom options for dprint.
160
168
  *
161
- * @default false
169
+ * By default it's controlled by our own config.
162
170
  */
163
- usePrettierrc?: boolean;
171
+ dprintOptions?: boolean;
164
172
  }
165
173
  interface OptionsComponentExts {
166
174
  /**
@@ -293,14 +301,14 @@ interface OptionsConfig extends OptionsComponentExts {
293
301
  */
294
302
  unocss?: boolean | OptionsUnoCSS;
295
303
  /**
296
- * Use Prettier to format files that not supported by ESLint.
304
+ * Use external formatters to format files.
297
305
  *
298
306
  * Requires installing:
299
- * - `eslint-plugin-prettier`
307
+ * - `eslint-plugin-format`
300
308
  *
301
309
  * @default false
302
310
  */
303
- prettier?: OptionsPrettier;
311
+ formatters?: OptionsFormatters;
304
312
  /**
305
313
  * Control to disable some rules in editors.
306
314
  * @default auto-detect based on the process.env
@@ -338,7 +346,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
338
346
 
339
347
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
340
348
 
341
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
349
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
342
350
 
343
351
  declare function node(): Promise<FlatConfigItem[]>;
344
352
 
@@ -349,10 +357,7 @@ declare function node(): Promise<FlatConfigItem[]>;
349
357
  */
350
358
  declare function perfectionist(): Promise<FlatConfigItem[]>;
351
359
 
352
- /**
353
- * @deprecated
354
- */
355
- declare function prettier(options?: OptionsPrettier, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
360
+ declare function formatters(options?: OptionsFormatters, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
356
361
 
357
362
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
358
363
 
@@ -421,4 +426,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
421
426
  } ? U : T>;
422
427
  declare function ensurePackages(packages: string[]): Promise<void>;
423
428
 
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 };
429
+ 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,11 +691,10 @@ 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
  ]);
678
699
  const {
679
700
  indent,
@@ -683,9 +704,6 @@ async function prettier(options = {}, stylistic2 = {}) {
683
704
  ...StylisticConfigDefaults,
684
705
  ...stylistic2
685
706
  };
686
- const {
687
- usePrettierrc = false
688
- } = options;
689
707
  const prettierOptions = Object.assign(
690
708
  {
691
709
  semi,
@@ -694,53 +712,137 @@ async function prettier(options = {}, stylistic2 = {}) {
694
712
  trailingComma: "all",
695
713
  useTabs: indent === "tab"
696
714
  },
697
- options.options || {}
715
+ options.prettierOptions || {}
698
716
  );
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 [
717
+ const dprintOptions = Object.assign(
718
+ {
719
+ indentWidth: typeof indent === "number" ? indent : 2,
720
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
721
+ useTabs: indent === "tab"
722
+ },
723
+ options.dprintOptions || {}
724
+ );
725
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
726
+ const configs = [
716
727
  {
717
- name: "antfu:prettier:setup",
728
+ name: "antfu:formatters:setup",
718
729
  plugins: {
719
- prettier: pluginPrettier
730
+ format: pluginFormat
720
731
  }
721
- },
722
- ...Object.entries(rules).map(([name, files]) => ({
723
- files,
732
+ }
733
+ ];
734
+ if (options.css) {
735
+ configs.push(
736
+ {
737
+ files: [GLOB_CSS, GLOB_POSTCSS],
738
+ languageOptions: {
739
+ parser: pluginFormat.parserPlain
740
+ },
741
+ name: "antfu:formatter:css",
742
+ rules: {
743
+ "format/prettier": [
744
+ "error",
745
+ {
746
+ ...prettierOptions,
747
+ parser: "css"
748
+ }
749
+ ]
750
+ }
751
+ },
752
+ {
753
+ files: [GLOB_SCSS],
754
+ languageOptions: {
755
+ parser: pluginFormat.parserPlain
756
+ },
757
+ name: "antfu:formatter:scss",
758
+ rules: {
759
+ "format/prettier": [
760
+ "error",
761
+ {
762
+ ...prettierOptions,
763
+ parser: "scss"
764
+ }
765
+ ]
766
+ }
767
+ },
768
+ {
769
+ files: [GLOB_LESS],
770
+ languageOptions: {
771
+ parser: pluginFormat.parserPlain
772
+ },
773
+ name: "antfu:formatter:less",
774
+ rules: {
775
+ "format/prettier": [
776
+ "error",
777
+ {
778
+ ...prettierOptions,
779
+ parser: "less"
780
+ }
781
+ ]
782
+ }
783
+ }
784
+ );
785
+ }
786
+ if (options.html) {
787
+ configs.push({
788
+ files: ["**/*.html"],
724
789
  languageOptions: {
725
- parser: parserPlain
790
+ parser: pluginFormat.parserPlain
726
791
  },
727
- name: `antfu:prettier:${name}`,
792
+ name: "antfu:formatter:html",
728
793
  rules: {
729
- "prettier/prettier": [
794
+ "format/prettier": [
730
795
  "error",
731
796
  {
732
797
  ...prettierOptions,
733
- embeddedLanguageFormatting: name === "html" ? "auto" : "off",
734
- parser: name
735
- },
798
+ parser: "html"
799
+ }
800
+ ]
801
+ }
802
+ });
803
+ }
804
+ if (options.toml) {
805
+ configs.push({
806
+ files: ["**/*.toml"],
807
+ languageOptions: {
808
+ parser: pluginFormat.parserPlain
809
+ },
810
+ name: "antfu:formatter:toml",
811
+ rules: {
812
+ "format/dprint": [
813
+ "error",
736
814
  {
737
- fullControl: true,
738
- usePrettierrc
815
+ ...dprintOptions,
816
+ language: "toml"
739
817
  }
740
818
  ]
741
819
  }
742
- }))
743
- ];
820
+ });
821
+ }
822
+ if (options.markdown) {
823
+ const formater = options.markdown === true ? "prettier" : options.markdown;
824
+ configs.push({
825
+ files: ["**/*.__markdown_content__"],
826
+ languageOptions: {
827
+ parser: pluginFormat.parserPlain
828
+ },
829
+ name: "antfu:formatter:markdown",
830
+ rules: {
831
+ [`format/${formater}`]: [
832
+ "error",
833
+ formater === "prettier" ? {
834
+ ...prettierOptions,
835
+ embeddedLanguageFormatting: "off",
836
+ parser: "markdown"
837
+ } : {
838
+ ...dprintOptions,
839
+ language: "markdown"
840
+ }
841
+ ]
842
+ }
843
+ });
844
+ }
845
+ return configs;
744
846
  }
745
847
 
746
848
  // src/configs/react.ts
@@ -1600,14 +1702,19 @@ async function antfu(options = {}, ...userConfigs) {
1600
1702
  }));
1601
1703
  }
1602
1704
  if (options.markdown ?? true) {
1603
- configs.push(markdown({
1604
- componentExts,
1605
- overrides: overrides.markdown
1606
- }));
1705
+ configs.push(
1706
+ markdown(
1707
+ {
1708
+ componentExts,
1709
+ overrides: overrides.markdown
1710
+ },
1711
+ !!options.formatters?.markdown
1712
+ )
1713
+ );
1607
1714
  }
1608
- if (options.prettier) {
1609
- configs.push(prettier(
1610
- options.prettier,
1715
+ if (options.formatters) {
1716
+ configs.push(formatters(
1717
+ options.formatters,
1611
1718
  typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1612
1719
  ));
1613
1720
  }
@@ -1657,6 +1764,7 @@ export {
1657
1764
  comments,
1658
1765
  src_default as default,
1659
1766
  ensurePackages,
1767
+ formatters,
1660
1768
  ignores,
1661
1769
  imports,
1662
1770
  interopDefault,
@@ -1666,7 +1774,6 @@ export {
1666
1774
  markdown,
1667
1775
  node,
1668
1776
  perfectionist,
1669
- prettier,
1670
1777
  react,
1671
1778
  renameRules,
1672
1779
  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.0",
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.0"
114
114
  },
115
115
  "simple-git-hooks": {
116
116
  "pre-commit": "pnpm lint-staged"