@antfu/eslint-config 2.3.4 → 2.4.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
@@ -12,6 +12,7 @@
12
12
  - [ESLint Flat config](https://eslint.org/docs/latest/use/configure/configuration-files-new), compose easily!
13
13
  - Using [ESLint Stylistic](https://github.com/eslint-stylistic/eslint-stylistic)
14
14
  - Respects `.gitignore` by default
15
+ - Optional [formatters](#formatters) support for CSS, HTML, TOML, etc.
15
16
  - **Style principle**: Minimal for reading, stable for diff, consistent
16
17
 
17
18
  > [!IMPORTANT]
@@ -220,7 +221,7 @@ Going more advanced, you can also import fine-grained configs and compose them a
220
221
  <details>
221
222
  <summary>Advanced Example</summary>
222
223
 
223
- We don't recommend using this style in general usages, as there are shared options between configs and might need extra care to make them consistent.
224
+ We wouldn't recommend using this style in general unless you know exactly what they are doing, as there are shared options between configs and might need extra care to make them consistent.
224
225
 
225
226
  ```js
226
227
  // eslint.config.js
@@ -351,10 +352,27 @@ import antfu from '@antfu/eslint-config'
351
352
 
352
353
  export default antfu({
353
354
  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
355
+ /**
356
+ * Format CSS, LESS, SCSS files, also the `<style>` blocks in Vue
357
+ * By default uses Prettier
358
+ */
359
+ css: true,
360
+ /**
361
+ * Format HTML files
362
+ * By default uses Prettier
363
+ */
364
+ html: true,
365
+ /**
366
+ * Format TOML files
367
+ * Currently only supports dprint
368
+ */
369
+ toml: 'dprint',
370
+ /**
371
+ * Format Markdown files
372
+ * Supports Prettier and dprint
373
+ * By default uses Prettier
374
+ */
375
+ markdown: 'prettier'
358
376
  }
359
377
  })
360
378
  ```
@@ -504,9 +522,17 @@ If you enjoy this code style, and would like to mention it in your project, here
504
522
 
505
523
  [Why I don't use Prettier](https://antfu.me/posts/why-not-prettier)
506
524
 
525
+ Well, you can still use Prettier to format files that are not supported well by ESLint yet, such as `.css`, `.html`, etc. See [formatters](#formatters) for more details.
526
+
527
+ ### dprint?
528
+
529
+ [dprint](https://dprint.dev/) is also a great formatter that with more abilities to customize. However, it's in the same model as Prettier which reads the AST and reprints the code from scratch. This means it's similar to Prettier, which ignores the original line breaks and might also cause the inconsistent diff. So in general, we prefer to use ESLint to format and lint JavaScript/TypeScript code.
530
+
531
+ Meanwhile, we do have dprint integrations for formatting other files such as `.toml` and `.md`. See [formatters](#formatters) for more details.
532
+
507
533
  ### How to format CSS?
508
534
 
509
- This config does NOT lint CSS. I personally use [UnoCSS](https://github.com/unocss/unocss) so I don't write CSS. For better linting, we recommend trying [stylelint](https://stylelint.io/).
535
+ You can opt-in to the [`formatters`](#formatters) feature to format your CSS. Note that it's only doing formatting, but not linting. If you want proper linting support, give [`stylelint`](https://stylelint.io/) a try.
510
536
 
511
537
  ### I prefer XXX...
512
538
 
@@ -516,7 +542,7 @@ Sure, you can configure and override rules locally in your project to fit your n
516
542
 
517
543
  - [antfu/dotfiles](https://github.com/antfu/dotfiles) - My dotfiles
518
544
  - [antfu/vscode-settings](https://github.com/antfu/vscode-settings) - My VS Code settings
519
- - [antfu/ts-starter](https://github.com/antfu/ts-starter) - My starter template for TypeScript library
545
+ - [antfu/starter-ts](https://github.com/antfu/starter-ts) - My starter template for TypeScript library
520
546
  - [antfu/vitesse](https://github.com/antfu/vitesse) - My starter template for Vue & Vite app
521
547
 
522
548
  ## License
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.3.4";
49
+ var version = "2.4.0";
50
50
  var devDependencies = {
51
51
  "@antfu/eslint-config": "workspace:*",
52
52
  "@antfu/eslint-plugin-prettier": "^5.0.1-1",
@@ -54,7 +54,7 @@ var devDependencies = {
54
54
  "@stylistic/eslint-plugin-migrate": "^1.5.0",
55
55
  "@types/eslint": "^8.44.8",
56
56
  "@types/fs-extra": "^11.0.4",
57
- "@types/node": "^20.10.3",
57
+ "@types/node": "^20.10.4",
58
58
  "@types/prompts": "^2.4.9",
59
59
  "@types/yargs": "^17.0.32",
60
60
  "@unocss/eslint-plugin": "^0.58.0",
@@ -73,8 +73,9 @@ var devDependencies = {
73
73
  rimraf: "^5.0.5",
74
74
  "simple-git-hooks": "^2.9.0",
75
75
  tsup: "^8.0.1",
76
- typescript: "^5.3.2",
77
- vitest: "^1.0.1"
76
+ typescript: "^5.3.3",
77
+ vitest: "^1.0.2",
78
+ vue: "^3.3.10"
78
79
  };
79
80
 
80
81
  // src/cli/constants.ts
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.3.4";
20
+ var version = "2.4.0";
21
21
  var devDependencies = {
22
22
  "@antfu/eslint-config": "workspace:*",
23
23
  "@antfu/eslint-plugin-prettier": "^5.0.1-1",
@@ -25,7 +25,7 @@ var devDependencies = {
25
25
  "@stylistic/eslint-plugin-migrate": "^1.5.0",
26
26
  "@types/eslint": "^8.44.8",
27
27
  "@types/fs-extra": "^11.0.4",
28
- "@types/node": "^20.10.3",
28
+ "@types/node": "^20.10.4",
29
29
  "@types/prompts": "^2.4.9",
30
30
  "@types/yargs": "^17.0.32",
31
31
  "@unocss/eslint-plugin": "^0.58.0",
@@ -44,8 +44,9 @@ var devDependencies = {
44
44
  rimraf: "^5.0.5",
45
45
  "simple-git-hooks": "^2.9.0",
46
46
  tsup: "^8.0.1",
47
- typescript: "^5.3.2",
48
- vitest: "^1.0.1"
47
+ typescript: "^5.3.3",
48
+ vitest: "^1.0.2",
49
+ vue: "^3.3.10"
49
50
  };
50
51
 
51
52
  // src/cli/constants.ts
package/dist/index.cjs CHANGED
@@ -595,44 +595,15 @@ async function jsonc(options = {}) {
595
595
  }
596
596
 
597
597
  // src/configs/markdown.ts
598
- async function markdown(options = {}, formatMarkdown = false) {
598
+ var parserPlain = __toESM(require("eslint-parser-plain"), 1);
599
+ var import_eslint_merge_processors = require("eslint-merge-processors");
600
+ async function markdown(options = {}) {
599
601
  const {
600
602
  componentExts = [],
601
603
  files = [GLOB_MARKDOWN],
602
604
  overrides = {}
603
605
  } = options;
604
606
  const markdown2 = await interopDefault(import("eslint-plugin-markdown"));
605
- const baseProcessor = markdown2.processors.markdown;
606
- const processor = !formatMarkdown ? {
607
- meta: {
608
- name: "markdown-processor"
609
- },
610
- supportsAutofix: true,
611
- ...baseProcessor
612
- } : {
613
- meta: {
614
- name: "markdown-processor-with-content"
615
- },
616
- postprocess(messages, filename) {
617
- const markdownContent = messages.pop();
618
- const codeSnippets = baseProcessor.postprocess(messages, filename);
619
- return [
620
- ...markdownContent || [],
621
- ...codeSnippets || []
622
- ];
623
- },
624
- preprocess(text, filename) {
625
- const result = baseProcessor.preprocess(text, filename);
626
- return [
627
- ...result,
628
- {
629
- filename: ".__markdown_content__",
630
- text
631
- }
632
- ];
633
- },
634
- supportsAutofix: true
635
- };
636
607
  return [
637
608
  {
638
609
  name: "antfu:markdown:setup",
@@ -644,7 +615,20 @@ async function markdown(options = {}, formatMarkdown = false) {
644
615
  files,
645
616
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
646
617
  name: "antfu:markdown:processor",
647
- processor
618
+ // `eslint-plugin-markdown` only creates virtual files for code blocks,
619
+ // but not the markdown file itself. We use `eslint-merge-processors` to
620
+ // add a pass-through processor for the markdown file itself.
621
+ processor: (0, import_eslint_merge_processors.mergeProcessors)([
622
+ markdown2.processors.markdown,
623
+ import_eslint_merge_processors.processorPassThrough
624
+ ])
625
+ },
626
+ {
627
+ files,
628
+ languageOptions: {
629
+ parser: parserPlain
630
+ },
631
+ name: "antfu:markdown:parser"
648
632
  },
649
633
  {
650
634
  files: [
@@ -742,6 +726,9 @@ async function perfectionist() {
742
726
  ];
743
727
  }
744
728
 
729
+ // src/configs/formatters.ts
730
+ var parserPlain2 = __toESM(require("eslint-parser-plain"), 1);
731
+
745
732
  // src/configs/stylistic.ts
746
733
  var StylisticConfigDefaults = {
747
734
  indent: 2,
@@ -787,7 +774,7 @@ async function stylistic(options = {}) {
787
774
  }
788
775
 
789
776
  // src/configs/formatters.ts
790
- async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true) {
777
+ async function formatters(options = {}, stylistic2 = {}) {
791
778
  await ensurePackages([
792
779
  "eslint-plugin-format"
793
780
  ]);
@@ -840,7 +827,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
840
827
  {
841
828
  files: [GLOB_CSS, GLOB_POSTCSS],
842
829
  languageOptions: {
843
- parser: pluginFormat.parserPlain
830
+ parser: parserPlain2
844
831
  },
845
832
  name: "antfu:formatter:css",
846
833
  rules: {
@@ -856,7 +843,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
856
843
  {
857
844
  files: [GLOB_SCSS],
858
845
  languageOptions: {
859
- parser: pluginFormat.parserPlain
846
+ parser: parserPlain2
860
847
  },
861
848
  name: "antfu:formatter:scss",
862
849
  rules: {
@@ -872,7 +859,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
872
859
  {
873
860
  files: [GLOB_LESS],
874
861
  languageOptions: {
875
- parser: pluginFormat.parserPlain
862
+ parser: parserPlain2
876
863
  },
877
864
  name: "antfu:formatter:less",
878
865
  rules: {
@@ -891,7 +878,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
891
878
  configs.push({
892
879
  files: ["**/*.html"],
893
880
  languageOptions: {
894
- parser: pluginFormat.parserPlain
881
+ parser: parserPlain2
895
882
  },
896
883
  name: "antfu:formatter:html",
897
884
  rules: {
@@ -909,7 +896,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
909
896
  configs.push({
910
897
  files: ["**/*.toml"],
911
898
  languageOptions: {
912
- parser: pluginFormat.parserPlain
899
+ parser: parserPlain2
913
900
  },
914
901
  name: "antfu:formatter:toml",
915
902
  rules: {
@@ -926,9 +913,9 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
926
913
  if (options.markdown) {
927
914
  const formater = options.markdown === true ? "prettier" : options.markdown;
928
915
  configs.push({
929
- files: markdownEnabled ? ["**/*.__markdown_content__"] : [GLOB_MARKDOWN],
916
+ files: [GLOB_MARKDOWN],
930
917
  languageOptions: {
931
- parser: pluginFormat.parserPlain
918
+ parser: parserPlain2
932
919
  },
933
920
  name: "antfu:formatter:markdown",
934
921
  rules: {
@@ -950,7 +937,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
950
937
  configs.push({
951
938
  files: ["**/*.graphql"],
952
939
  languageOptions: {
953
- parser: pluginFormat.parserPlain
940
+ parser: parserPlain2
954
941
  },
955
942
  name: "antfu:formatter:graphql",
956
943
  rules: {
@@ -1530,22 +1517,27 @@ async function unocss(options = {}) {
1530
1517
  }
1531
1518
 
1532
1519
  // src/configs/vue.ts
1520
+ var import_eslint_merge_processors2 = require("eslint-merge-processors");
1533
1521
  async function vue(options = {}) {
1534
1522
  const {
1535
1523
  files = [GLOB_VUE],
1536
1524
  overrides = {},
1537
- stylistic: stylistic2 = true
1525
+ stylistic: stylistic2 = true,
1526
+ vueVersion = 3
1538
1527
  } = options;
1528
+ const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1539
1529
  const {
1540
1530
  indent = 2
1541
1531
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1542
1532
  const [
1543
1533
  pluginVue,
1544
- parserVue
1534
+ parserVue,
1535
+ processorVueBlocks
1545
1536
  ] = await Promise.all([
1546
1537
  // @ts-expect-error missing types
1547
1538
  interopDefault(import("eslint-plugin-vue")),
1548
- interopDefault(import("vue-eslint-parser"))
1539
+ interopDefault(import("vue-eslint-parser")),
1540
+ interopDefault(import("eslint-processor-vue-blocks"))
1549
1541
  ]);
1550
1542
  return [
1551
1543
  {
@@ -1568,12 +1560,27 @@ async function vue(options = {}) {
1568
1560
  }
1569
1561
  },
1570
1562
  name: "antfu:vue:rules",
1571
- processor: pluginVue.processors[".vue"],
1563
+ processor: sfcBlocks === false ? pluginVue.processors[".vue"] : (0, import_eslint_merge_processors2.mergeProcessors)([
1564
+ pluginVue.processors[".vue"],
1565
+ processorVueBlocks({
1566
+ ...sfcBlocks,
1567
+ blocks: {
1568
+ ...sfcBlocks.blocks,
1569
+ styles: true
1570
+ }
1571
+ })
1572
+ ]),
1572
1573
  rules: {
1573
1574
  ...pluginVue.configs.base.rules,
1574
- ...pluginVue.configs["vue3-essential"].rules,
1575
- ...pluginVue.configs["vue3-strongly-recommended"].rules,
1576
- ...pluginVue.configs["vue3-recommended"].rules,
1575
+ ...vueVersion === 2 ? {
1576
+ ...pluginVue.configs["vue-essential"].rules,
1577
+ ...pluginVue.configs["vue-strongly-recommended"].rules,
1578
+ ...pluginVue.configs["vue-recommended"].rules
1579
+ } : {
1580
+ ...pluginVue.configs["vue3-essential"].rules,
1581
+ ...pluginVue.configs["vue3-strongly-recommended"].rules,
1582
+ ...pluginVue.configs["vue3-recommended"].rules
1583
+ },
1577
1584
  "node/prefer-global/process": "off",
1578
1585
  "vue/block-order": ["error", {
1579
1586
  order: ["script", "template", "style"]
@@ -1829,16 +1836,14 @@ async function antfu(options = {}, ...userConfigs) {
1829
1836
  {
1830
1837
  componentExts,
1831
1838
  overrides: overrides.markdown
1832
- },
1833
- options.formatters === true || !!(options.formatters || {})?.markdown
1839
+ }
1834
1840
  )
1835
1841
  );
1836
1842
  }
1837
1843
  if (options.formatters) {
1838
1844
  configs.push(formatters(
1839
1845
  options.formatters,
1840
- typeof stylisticOptions === "boolean" ? {} : stylisticOptions,
1841
- options.markdown !== false
1846
+ typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1842
1847
  ));
1843
1848
  }
1844
1849
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
2
2
  import { ParserOptions } from '@typescript-eslint/parser';
3
+ import { Options } from 'eslint-processor-vue-blocks';
3
4
  import { Linter } from 'eslint';
4
5
  import { RuleConfig, MergeIntersection, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ReactHooksRules, ReactRules, ImportRules, EslintRules, JsoncRules, VueRules, EslintCommentsRules, FlatESLintConfigItem } from '@antfu/eslint-define-config';
5
6
  import { RuleOptions as RuleOptions$1 } from '@eslint-types/jsdoc/types';
@@ -130,6 +131,21 @@ interface OptionsFiles {
130
131
  */
131
132
  files?: string[];
132
133
  }
134
+ interface OptionsVue {
135
+ /**
136
+ * Create virtual files for Vue SFC blocks to enable linting.
137
+ *
138
+ * @see https://github.com/antfu/eslint-processor-vue-blocks
139
+ * @default true
140
+ */
141
+ sfcBlocks?: boolean | Options;
142
+ /**
143
+ * Vue version. Apply different rules set from `eslint-plugin-vue`.
144
+ *
145
+ * @default 3
146
+ */
147
+ vueVersion?: 2 | 3;
148
+ }
133
149
  interface OptionsFormatters {
134
150
  /**
135
151
  * Enable formatting support for CSS, Less, Sass, and SCSS.
@@ -354,7 +370,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
354
370
 
355
371
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
356
372
 
357
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
373
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
358
374
 
359
375
  declare function node(): Promise<FlatConfigItem[]>;
360
376
 
@@ -365,7 +381,7 @@ declare function node(): Promise<FlatConfigItem[]>;
365
381
  */
366
382
  declare function perfectionist(): Promise<FlatConfigItem[]>;
367
383
 
368
- declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig, markdownEnabled?: boolean): Promise<FlatConfigItem[]>;
384
+ declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
369
385
 
370
386
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
371
387
 
@@ -393,7 +409,7 @@ declare function unicorn(): Promise<FlatConfigItem[]>;
393
409
 
394
410
  declare function unocss(options?: OptionsUnoCSS): Promise<FlatConfigItem[]>;
395
411
 
396
- declare function vue(options?: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic & OptionsFiles): Promise<FlatConfigItem[]>;
412
+ declare function vue(options?: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic & OptionsFiles & OptionsVue): Promise<FlatConfigItem[]>;
397
413
 
398
414
  declare function yaml(options?: OptionsOverrides & OptionsStylistic & OptionsFiles): Promise<FlatConfigItem[]>;
399
415
 
@@ -434,4 +450,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
434
450
  } ? U : T>;
435
451
  declare function ensurePackages(packages: string[]): Promise<void>;
436
452
 
437
- 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 };
453
+ 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 OptionsVue, 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
@@ -1,5 +1,6 @@
1
1
  import { FlatGitignoreOptions } from 'eslint-config-flat-gitignore';
2
2
  import { ParserOptions } from '@typescript-eslint/parser';
3
+ import { Options } from 'eslint-processor-vue-blocks';
3
4
  import { Linter } from 'eslint';
4
5
  import { RuleConfig, MergeIntersection, RenamePrefix, VitestRules, YmlRules, NRules, Prefix, ReactHooksRules, ReactRules, ImportRules, EslintRules, JsoncRules, VueRules, EslintCommentsRules, FlatESLintConfigItem } from '@antfu/eslint-define-config';
5
6
  import { RuleOptions as RuleOptions$1 } from '@eslint-types/jsdoc/types';
@@ -130,6 +131,21 @@ interface OptionsFiles {
130
131
  */
131
132
  files?: string[];
132
133
  }
134
+ interface OptionsVue {
135
+ /**
136
+ * Create virtual files for Vue SFC blocks to enable linting.
137
+ *
138
+ * @see https://github.com/antfu/eslint-processor-vue-blocks
139
+ * @default true
140
+ */
141
+ sfcBlocks?: boolean | Options;
142
+ /**
143
+ * Vue version. Apply different rules set from `eslint-plugin-vue`.
144
+ *
145
+ * @default 3
146
+ */
147
+ vueVersion?: 2 | 3;
148
+ }
133
149
  interface OptionsFormatters {
134
150
  /**
135
151
  * Enable formatting support for CSS, Less, Sass, and SCSS.
@@ -354,7 +370,7 @@ declare function jsdoc(options?: OptionsStylistic): Promise<FlatConfigItem[]>;
354
370
 
355
371
  declare function jsonc(options?: OptionsFiles & OptionsStylistic & OptionsOverrides): Promise<FlatConfigItem[]>;
356
372
 
357
- declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides, formatMarkdown?: boolean): Promise<FlatConfigItem[]>;
373
+ declare function markdown(options?: OptionsFiles & OptionsComponentExts & OptionsOverrides): Promise<FlatConfigItem[]>;
358
374
 
359
375
  declare function node(): Promise<FlatConfigItem[]>;
360
376
 
@@ -365,7 +381,7 @@ declare function node(): Promise<FlatConfigItem[]>;
365
381
  */
366
382
  declare function perfectionist(): Promise<FlatConfigItem[]>;
367
383
 
368
- declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig, markdownEnabled?: boolean): Promise<FlatConfigItem[]>;
384
+ declare function formatters(options?: OptionsFormatters | true, stylistic?: StylisticConfig): Promise<FlatConfigItem[]>;
369
385
 
370
386
  declare function react(options?: OptionsHasTypeScript & OptionsOverrides & OptionsFiles): Promise<FlatConfigItem[]>;
371
387
 
@@ -393,7 +409,7 @@ declare function unicorn(): Promise<FlatConfigItem[]>;
393
409
 
394
410
  declare function unocss(options?: OptionsUnoCSS): Promise<FlatConfigItem[]>;
395
411
 
396
- declare function vue(options?: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic & OptionsFiles): Promise<FlatConfigItem[]>;
412
+ declare function vue(options?: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic & OptionsFiles & OptionsVue): Promise<FlatConfigItem[]>;
397
413
 
398
414
  declare function yaml(options?: OptionsOverrides & OptionsStylistic & OptionsFiles): Promise<FlatConfigItem[]>;
399
415
 
@@ -434,4 +450,4 @@ declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
434
450
  } ? U : T>;
435
451
  declare function ensurePackages(packages: string[]): Promise<void>;
436
452
 
437
- 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 };
453
+ 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 OptionsVue, 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,44 +509,15 @@ async function jsonc(options = {}) {
509
509
  }
510
510
 
511
511
  // src/configs/markdown.ts
512
- async function markdown(options = {}, formatMarkdown = false) {
512
+ import * as parserPlain from "eslint-parser-plain";
513
+ import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
514
+ async function markdown(options = {}) {
513
515
  const {
514
516
  componentExts = [],
515
517
  files = [GLOB_MARKDOWN],
516
518
  overrides = {}
517
519
  } = options;
518
520
  const markdown2 = await interopDefault(import("eslint-plugin-markdown"));
519
- const baseProcessor = markdown2.processors.markdown;
520
- const processor = !formatMarkdown ? {
521
- meta: {
522
- name: "markdown-processor"
523
- },
524
- supportsAutofix: true,
525
- ...baseProcessor
526
- } : {
527
- meta: {
528
- name: "markdown-processor-with-content"
529
- },
530
- postprocess(messages, filename) {
531
- const markdownContent = messages.pop();
532
- const codeSnippets = baseProcessor.postprocess(messages, filename);
533
- return [
534
- ...markdownContent || [],
535
- ...codeSnippets || []
536
- ];
537
- },
538
- preprocess(text, filename) {
539
- const result = baseProcessor.preprocess(text, filename);
540
- return [
541
- ...result,
542
- {
543
- filename: ".__markdown_content__",
544
- text
545
- }
546
- ];
547
- },
548
- supportsAutofix: true
549
- };
550
521
  return [
551
522
  {
552
523
  name: "antfu:markdown:setup",
@@ -558,7 +529,20 @@ async function markdown(options = {}, formatMarkdown = false) {
558
529
  files,
559
530
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
560
531
  name: "antfu:markdown:processor",
561
- processor
532
+ // `eslint-plugin-markdown` only creates virtual files for code blocks,
533
+ // but not the markdown file itself. We use `eslint-merge-processors` to
534
+ // add a pass-through processor for the markdown file itself.
535
+ processor: mergeProcessors([
536
+ markdown2.processors.markdown,
537
+ processorPassThrough
538
+ ])
539
+ },
540
+ {
541
+ files,
542
+ languageOptions: {
543
+ parser: parserPlain
544
+ },
545
+ name: "antfu:markdown:parser"
562
546
  },
563
547
  {
564
548
  files: [
@@ -656,6 +640,9 @@ async function perfectionist() {
656
640
  ];
657
641
  }
658
642
 
643
+ // src/configs/formatters.ts
644
+ import * as parserPlain2 from "eslint-parser-plain";
645
+
659
646
  // src/configs/stylistic.ts
660
647
  var StylisticConfigDefaults = {
661
648
  indent: 2,
@@ -701,7 +688,7 @@ async function stylistic(options = {}) {
701
688
  }
702
689
 
703
690
  // src/configs/formatters.ts
704
- async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true) {
691
+ async function formatters(options = {}, stylistic2 = {}) {
705
692
  await ensurePackages([
706
693
  "eslint-plugin-format"
707
694
  ]);
@@ -754,7 +741,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
754
741
  {
755
742
  files: [GLOB_CSS, GLOB_POSTCSS],
756
743
  languageOptions: {
757
- parser: pluginFormat.parserPlain
744
+ parser: parserPlain2
758
745
  },
759
746
  name: "antfu:formatter:css",
760
747
  rules: {
@@ -770,7 +757,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
770
757
  {
771
758
  files: [GLOB_SCSS],
772
759
  languageOptions: {
773
- parser: pluginFormat.parserPlain
760
+ parser: parserPlain2
774
761
  },
775
762
  name: "antfu:formatter:scss",
776
763
  rules: {
@@ -786,7 +773,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
786
773
  {
787
774
  files: [GLOB_LESS],
788
775
  languageOptions: {
789
- parser: pluginFormat.parserPlain
776
+ parser: parserPlain2
790
777
  },
791
778
  name: "antfu:formatter:less",
792
779
  rules: {
@@ -805,7 +792,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
805
792
  configs.push({
806
793
  files: ["**/*.html"],
807
794
  languageOptions: {
808
- parser: pluginFormat.parserPlain
795
+ parser: parserPlain2
809
796
  },
810
797
  name: "antfu:formatter:html",
811
798
  rules: {
@@ -823,7 +810,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
823
810
  configs.push({
824
811
  files: ["**/*.toml"],
825
812
  languageOptions: {
826
- parser: pluginFormat.parserPlain
813
+ parser: parserPlain2
827
814
  },
828
815
  name: "antfu:formatter:toml",
829
816
  rules: {
@@ -840,9 +827,9 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
840
827
  if (options.markdown) {
841
828
  const formater = options.markdown === true ? "prettier" : options.markdown;
842
829
  configs.push({
843
- files: markdownEnabled ? ["**/*.__markdown_content__"] : [GLOB_MARKDOWN],
830
+ files: [GLOB_MARKDOWN],
844
831
  languageOptions: {
845
- parser: pluginFormat.parserPlain
832
+ parser: parserPlain2
846
833
  },
847
834
  name: "antfu:formatter:markdown",
848
835
  rules: {
@@ -864,7 +851,7 @@ async function formatters(options = {}, stylistic2 = {}, markdownEnabled = true)
864
851
  configs.push({
865
852
  files: ["**/*.graphql"],
866
853
  languageOptions: {
867
- parser: pluginFormat.parserPlain
854
+ parser: parserPlain2
868
855
  },
869
856
  name: "antfu:formatter:graphql",
870
857
  rules: {
@@ -1444,22 +1431,27 @@ async function unocss(options = {}) {
1444
1431
  }
1445
1432
 
1446
1433
  // src/configs/vue.ts
1434
+ import { mergeProcessors as mergeProcessors2 } from "eslint-merge-processors";
1447
1435
  async function vue(options = {}) {
1448
1436
  const {
1449
1437
  files = [GLOB_VUE],
1450
1438
  overrides = {},
1451
- stylistic: stylistic2 = true
1439
+ stylistic: stylistic2 = true,
1440
+ vueVersion = 3
1452
1441
  } = options;
1442
+ const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1453
1443
  const {
1454
1444
  indent = 2
1455
1445
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1456
1446
  const [
1457
1447
  pluginVue,
1458
- parserVue
1448
+ parserVue,
1449
+ processorVueBlocks
1459
1450
  ] = await Promise.all([
1460
1451
  // @ts-expect-error missing types
1461
1452
  interopDefault(import("eslint-plugin-vue")),
1462
- interopDefault(import("vue-eslint-parser"))
1453
+ interopDefault(import("vue-eslint-parser")),
1454
+ interopDefault(import("eslint-processor-vue-blocks"))
1463
1455
  ]);
1464
1456
  return [
1465
1457
  {
@@ -1482,12 +1474,27 @@ async function vue(options = {}) {
1482
1474
  }
1483
1475
  },
1484
1476
  name: "antfu:vue:rules",
1485
- processor: pluginVue.processors[".vue"],
1477
+ processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors2([
1478
+ pluginVue.processors[".vue"],
1479
+ processorVueBlocks({
1480
+ ...sfcBlocks,
1481
+ blocks: {
1482
+ ...sfcBlocks.blocks,
1483
+ styles: true
1484
+ }
1485
+ })
1486
+ ]),
1486
1487
  rules: {
1487
1488
  ...pluginVue.configs.base.rules,
1488
- ...pluginVue.configs["vue3-essential"].rules,
1489
- ...pluginVue.configs["vue3-strongly-recommended"].rules,
1490
- ...pluginVue.configs["vue3-recommended"].rules,
1489
+ ...vueVersion === 2 ? {
1490
+ ...pluginVue.configs["vue-essential"].rules,
1491
+ ...pluginVue.configs["vue-strongly-recommended"].rules,
1492
+ ...pluginVue.configs["vue-recommended"].rules
1493
+ } : {
1494
+ ...pluginVue.configs["vue3-essential"].rules,
1495
+ ...pluginVue.configs["vue3-strongly-recommended"].rules,
1496
+ ...pluginVue.configs["vue3-recommended"].rules
1497
+ },
1491
1498
  "node/prefer-global/process": "off",
1492
1499
  "vue/block-order": ["error", {
1493
1500
  order: ["script", "template", "style"]
@@ -1743,16 +1750,14 @@ async function antfu(options = {}, ...userConfigs) {
1743
1750
  {
1744
1751
  componentExts,
1745
1752
  overrides: overrides.markdown
1746
- },
1747
- options.formatters === true || !!(options.formatters || {})?.markdown
1753
+ }
1748
1754
  )
1749
1755
  );
1750
1756
  }
1751
1757
  if (options.formatters) {
1752
1758
  configs.push(formatters(
1753
1759
  options.formatters,
1754
- typeof stylisticOptions === "boolean" ? {} : stylisticOptions,
1755
- options.markdown !== false
1760
+ typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1756
1761
  ));
1757
1762
  }
1758
1763
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@antfu/eslint-config",
3
3
  "type": "module",
4
- "version": "2.3.4",
4
+ "version": "2.4.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/)",
@@ -59,6 +59,8 @@
59
59
  "@typescript-eslint/eslint-plugin": "^6.13.2",
60
60
  "@typescript-eslint/parser": "^6.13.2",
61
61
  "eslint-config-flat-gitignore": "^0.1.2",
62
+ "eslint-merge-processors": "^0.1.0",
63
+ "eslint-parser-plain": "^0.1.0",
62
64
  "eslint-plugin-antfu": "^2.0.0",
63
65
  "eslint-plugin-eslint-comments": "^3.2.0",
64
66
  "eslint-plugin-i": "^2.29.0",
@@ -73,6 +75,7 @@
73
75
  "eslint-plugin-vitest": "^0.3.10",
74
76
  "eslint-plugin-vue": "^9.19.2",
75
77
  "eslint-plugin-yml": "^1.10.0",
78
+ "eslint-processor-vue-blocks": "^0.1.1",
76
79
  "globals": "^13.23.0",
77
80
  "jsonc-eslint-parser": "^2.4.0",
78
81
  "local-pkg": "^0.5.0",
@@ -89,7 +92,7 @@
89
92
  "@stylistic/eslint-plugin-migrate": "^1.5.0",
90
93
  "@types/eslint": "^8.44.8",
91
94
  "@types/fs-extra": "^11.0.4",
92
- "@types/node": "^20.10.3",
95
+ "@types/node": "^20.10.4",
93
96
  "@types/prompts": "^2.4.9",
94
97
  "@types/yargs": "^17.0.32",
95
98
  "@unocss/eslint-plugin": "^0.58.0",
@@ -108,9 +111,10 @@
108
111
  "rimraf": "^5.0.5",
109
112
  "simple-git-hooks": "^2.9.0",
110
113
  "tsup": "^8.0.1",
111
- "typescript": "^5.3.2",
112
- "vitest": "^1.0.1",
113
- "@antfu/eslint-config": "2.3.4"
114
+ "typescript": "^5.3.3",
115
+ "vitest": "^1.0.2",
116
+ "vue": "^3.3.10",
117
+ "@antfu/eslint-config": "2.4.0"
114
118
  },
115
119
  "simple-git-hooks": {
116
120
  "pre-commit": "pnpm lint-staged"