@lincy/eslint-config 4.1.1 → 4.2.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/dist/index.js CHANGED
@@ -39,12 +39,14 @@ var GLOB_TS = "**/*.?([cm])ts";
39
39
  var GLOB_TSX = "**/*.?([cm])tsx";
40
40
  var GLOB_STYLE = "**/*.{c,le,sc}ss";
41
41
  var GLOB_CSS = "**/*.css";
42
+ var GLOB_POSTCSS = "**/*.{p,post}css";
42
43
  var GLOB_LESS = "**/*.less";
43
44
  var GLOB_SCSS = "**/*.scss";
44
45
  var GLOB_JSON = "**/*.json";
45
46
  var GLOB_JSON5 = "**/*.json5";
46
47
  var GLOB_JSONC = "**/*.jsonc";
47
48
  var GLOB_MARKDOWN = "**/*.md";
49
+ var GLOB_MARKDOWN_IN_MARKDOWN = "**/*.md/*.md";
48
50
  var GLOB_VUE = "**/*.vue";
49
51
  var GLOB_YAML = "**/*.y?(a)ml";
50
52
  var GLOB_HTML = "**/*.htm?(l)";
@@ -512,24 +514,56 @@ async function jsonc(options = {}) {
512
514
  }
513
515
 
514
516
  // src/configs/markdown.ts
515
- async function markdown(options = {}) {
517
+ async function markdown(options = {}, formatMarkdown = false) {
516
518
  const {
517
519
  componentExts = [],
518
520
  files = [GLOB_MARKDOWN],
519
521
  overrides = {}
520
522
  } = options;
523
+ const markdown2 = await interopDefault(import("eslint-plugin-markdown"));
524
+ const baseProcessor = markdown2.processors.markdown;
525
+ const processor = !formatMarkdown ? {
526
+ meta: {
527
+ name: "markdown-processor"
528
+ },
529
+ supportsAutofix: true,
530
+ ...baseProcessor
531
+ } : {
532
+ meta: {
533
+ name: "markdown-processor-with-content"
534
+ },
535
+ postprocess(messages, filename) {
536
+ const markdownContent = messages.pop();
537
+ const codeSnippets = baseProcessor.postprocess(messages, filename);
538
+ return [
539
+ ...markdownContent || [],
540
+ ...codeSnippets || []
541
+ ];
542
+ },
543
+ preprocess(text, filename) {
544
+ const result = baseProcessor.preprocess(text, filename);
545
+ return [
546
+ ...result,
547
+ {
548
+ filename: ".__markdown_content__",
549
+ text
550
+ }
551
+ ];
552
+ },
553
+ supportsAutofix: true
554
+ };
521
555
  return [
522
556
  {
523
557
  name: "eslint:markdown:setup",
524
558
  plugins: {
525
- // @ts-expect-error missing types
526
- markdown: await interopDefault(import("eslint-plugin-markdown"))
559
+ markdown: markdown2
527
560
  }
528
561
  },
529
562
  {
530
563
  files,
564
+ ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
531
565
  name: "eslint:markdown:processor",
532
- processor: "markdown/markdown"
566
+ processor
533
567
  },
534
568
  {
535
569
  files: [
@@ -543,9 +577,8 @@ async function markdown(options = {}) {
543
577
  }
544
578
  }
545
579
  },
546
- name: "eslint:markdown:rules",
580
+ name: "eslint:markdown:disables",
547
581
  rules: {
548
- "antfu/no-ts-export-equal": "off",
549
582
  "import/newline-after-import": "off",
550
583
  "no-alert": "off",
551
584
  "no-console": "off",
@@ -594,256 +627,45 @@ async function markdown(options = {}) {
594
627
  ];
595
628
  }
596
629
 
597
- // src/configs/node.ts
598
- async function node() {
630
+ // src/configs/perfectionist.ts
631
+ async function perfectionist() {
599
632
  return [
600
633
  {
601
- name: "eslint:node",
634
+ name: "eslint:perfectionist",
602
635
  plugins: {
603
- node: default4
604
- },
605
- rules: {
606
- "node/handle-callback-err": ["error", "^(err|error)$"],
607
- "node/no-deprecated-api": "error",
608
- "node/no-exports-assign": "error",
609
- "node/no-new-require": "error",
610
- "node/no-path-concat": "error",
611
- "node/prefer-global/buffer": ["error", "never"],
612
- "node/prefer-global/process": ["error", "never"],
613
- "node/process-exit-as-throw": "error"
614
- }
615
- }
616
- ];
617
- }
618
-
619
- // src/configs/sort.ts
620
- async function sortPackageJson() {
621
- return [
622
- {
623
- files: ["**/package.json"],
624
- name: "eslint:sort-package-json",
625
- rules: {
626
- "jsonc/sort-array-values": [
627
- "error",
628
- {
629
- order: { type: "asc" },
630
- pathPattern: "^files$"
631
- }
632
- ],
633
- "jsonc/sort-keys": [
634
- "error",
635
- {
636
- order: [
637
- "publisher",
638
- "name",
639
- "displayName",
640
- "type",
641
- "version",
642
- "private",
643
- "packageManager",
644
- "description",
645
- "author",
646
- "license",
647
- "funding",
648
- "homepage",
649
- "repository",
650
- "bugs",
651
- "keywords",
652
- "categories",
653
- "sideEffects",
654
- "exports",
655
- "main",
656
- "module",
657
- "unpkg",
658
- "jsdelivr",
659
- "types",
660
- "typesVersions",
661
- "bin",
662
- "icon",
663
- "files",
664
- "engines",
665
- "activationEvents",
666
- "contributes",
667
- "scripts",
668
- "peerDependencies",
669
- "peerDependenciesMeta",
670
- "dependencies",
671
- "optionalDependencies",
672
- "devDependencies",
673
- "pnpm",
674
- "overrides",
675
- "resolutions",
676
- "husky",
677
- "simple-git-hooks",
678
- "lint-staged",
679
- "eslintConfig"
680
- ],
681
- pathPattern: "^$"
682
- },
683
- {
684
- order: { type: "asc" },
685
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies$"
686
- },
687
- {
688
- order: { type: "asc" },
689
- pathPattern: "^resolutions$"
690
- },
691
- {
692
- order: { type: "asc" },
693
- pathPattern: "^pnpm.overrides$"
694
- },
695
- {
696
- order: [
697
- "types",
698
- "import",
699
- "require",
700
- "default"
701
- ],
702
- pathPattern: "^exports.*$"
703
- }
704
- ]
705
- }
706
- }
707
- ];
708
- }
709
- function sortTsconfig() {
710
- return [
711
- {
712
- files: ["**/tsconfig.json", "**/tsconfig.*.json"],
713
- name: "eslint:sort-tsconfig",
714
- rules: {
715
- "jsonc/sort-keys": [
716
- "error",
717
- {
718
- order: [
719
- "extends",
720
- "compilerOptions",
721
- "references",
722
- "files",
723
- "include",
724
- "exclude"
725
- ],
726
- pathPattern: "^$"
727
- },
728
- {
729
- order: [
730
- /* Projects */
731
- "incremental",
732
- "composite",
733
- "tsBuildInfoFile",
734
- "disableSourceOfProjectReferenceRedirect",
735
- "disableSolutionSearching",
736
- "disableReferencedProjectLoad",
737
- /* Language and Environment */
738
- "target",
739
- "jsx",
740
- "jsxFactory",
741
- "jsxFragmentFactory",
742
- "jsxImportSource",
743
- "lib",
744
- "moduleDetection",
745
- "noLib",
746
- "reactNamespace",
747
- "useDefineForClassFields",
748
- "emitDecoratorMetadata",
749
- "experimentalDecorators",
750
- /* Modules */
751
- "baseUrl",
752
- "rootDir",
753
- "rootDirs",
754
- "customConditions",
755
- "module",
756
- "moduleResolution",
757
- "moduleSuffixes",
758
- "noResolve",
759
- "paths",
760
- "resolveJsonModule",
761
- "resolvePackageJsonExports",
762
- "resolvePackageJsonImports",
763
- "typeRoots",
764
- "types",
765
- "allowArbitraryExtensions",
766
- "allowImportingTsExtensions",
767
- "allowUmdGlobalAccess",
768
- /* JavaScript Support */
769
- "allowJs",
770
- "checkJs",
771
- "maxNodeModuleJsDepth",
772
- /* Type Checking */
773
- "strict",
774
- "strictBindCallApply",
775
- "strictFunctionTypes",
776
- "strictNullChecks",
777
- "strictPropertyInitialization",
778
- "allowUnreachableCode",
779
- "allowUnusedLabels",
780
- "alwaysStrict",
781
- "exactOptionalPropertyTypes",
782
- "noFallthroughCasesInSwitch",
783
- "noImplicitAny",
784
- "noImplicitOverride",
785
- "noImplicitReturns",
786
- "noImplicitThis",
787
- "noPropertyAccessFromIndexSignature",
788
- "noUncheckedIndexedAccess",
789
- "noUnusedLocals",
790
- "noUnusedParameters",
791
- "useUnknownInCatchVariables",
792
- /* Emit */
793
- "declaration",
794
- "declarationDir",
795
- "declarationMap",
796
- "downlevelIteration",
797
- "emitBOM",
798
- "emitDeclarationOnly",
799
- "importHelpers",
800
- "importsNotUsedAsValues",
801
- "inlineSourceMap",
802
- "inlineSources",
803
- "mapRoot",
804
- "newLine",
805
- "noEmit",
806
- "noEmitHelpers",
807
- "noEmitOnError",
808
- "outDir",
809
- "outFile",
810
- "preserveConstEnums",
811
- "preserveValueImports",
812
- "removeComments",
813
- "sourceMap",
814
- "sourceRoot",
815
- "stripInternal",
816
- /* Interop Constraints */
817
- "allowSyntheticDefaultImports",
818
- "esModuleInterop",
819
- "forceConsistentCasingInFileNames",
820
- "isolatedModules",
821
- "preserveSymlinks",
822
- "verbatimModuleSyntax",
823
- /* Completeness */
824
- "skipDefaultLibCheck",
825
- "skipLibCheck"
826
- ],
827
- pathPattern: "^compilerOptions$"
828
- }
829
- ]
636
+ perfectionist: default7
830
637
  }
831
638
  }
832
639
  ];
833
640
  }
834
641
 
835
642
  // src/configs/stylistic.ts
643
+ var StylisticConfigDefaults = {
644
+ indent: 4,
645
+ jsx: true,
646
+ quotes: "single",
647
+ semi: false
648
+ };
836
649
  async function stylistic(options = {}) {
837
650
  const {
838
651
  overrides = {},
839
- stylistic: stylistic2 = {}
652
+ stylistic: stylistic2 = StylisticConfigDefaults
840
653
  } = options;
841
654
  const {
842
- indent = 4,
843
- jsx = true,
844
- quotes = "single"
845
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
655
+ indent,
656
+ jsx,
657
+ quotes,
658
+ semi
659
+ } = typeof stylistic2 === "boolean" ? StylisticConfigDefaults : stylistic2;
846
660
  const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
661
+ const config = pluginStylistic.configs.customize({
662
+ flat: true,
663
+ indent,
664
+ jsx,
665
+ pluginName: "style",
666
+ quotes,
667
+ semi
668
+ });
847
669
  return [
848
670
  {
849
671
  name: "eslint:stylistic",
@@ -852,530 +674,602 @@ async function stylistic(options = {}) {
852
674
  style: pluginStylistic
853
675
  },
854
676
  rules: {
677
+ ...config.rules,
855
678
  "antfu/consistent-list-newline": "off",
856
679
  "antfu/if-newline": "error",
857
- "antfu/indent-binary-ops": ["error", { indent }],
858
680
  "antfu/top-level-function": "error",
859
681
  "curly": ["error", "multi-or-nest", "consistent"],
860
- "style/array-bracket-spacing": ["error", "never"],
861
- "style/arrow-spacing": ["error", { after: true, before: true }],
862
- "style/block-spacing": ["error", "always"],
863
- "style/brace-style": ["error", "stroustrup", { allowSingleLine: true }],
864
- "style/comma-dangle": ["error", "always-multiline"],
865
- "style/comma-spacing": ["error", { after: true, before: false }],
866
- "style/comma-style": ["error", "last"],
867
- "style/computed-property-spacing": ["error", "never", { enforceForClassMembers: true }],
868
- "style/dot-location": ["error", "property"],
869
- "style/eol-last": "error",
870
- "style/indent": ["error", indent, {
871
- ArrayExpression: 1,
872
- CallExpression: { arguments: 1 },
873
- flatTernaryExpressions: false,
874
- FunctionDeclaration: { body: 1, parameters: 1 },
875
- FunctionExpression: { body: 1, parameters: 1 },
876
- ignoreComments: false,
877
- ignoredNodes: [
878
- "TemplateLiteral *",
879
- "JSXElement",
880
- "JSXElement > *",
881
- "JSXAttribute",
882
- "JSXIdentifier",
883
- "JSXNamespacedName",
884
- "JSXMemberExpression",
885
- "JSXSpreadAttribute",
886
- "JSXExpressionContainer",
887
- "JSXOpeningElement",
888
- "JSXClosingElement",
889
- "JSXFragment",
890
- "JSXOpeningFragment",
891
- "JSXClosingFragment",
892
- "JSXText",
893
- "JSXEmptyExpression",
894
- "JSXSpreadChild",
895
- "TSUnionType",
896
- "TSIntersectionType",
897
- "TSTypeParameterInstantiation",
898
- "FunctionExpression > .params[decorators.length > 0]",
899
- "FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
900
- "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
901
- ],
902
- ImportDeclaration: 1,
903
- MemberExpression: 1,
904
- ObjectExpression: 1,
905
- offsetTernaryExpressions: true,
906
- outerIIFEBody: 1,
907
- SwitchCase: 1,
908
- VariableDeclarator: 1
909
- }],
910
- "style/key-spacing": ["error", { afterColon: true, beforeColon: false }],
911
- "style/keyword-spacing": ["error", { after: true, before: true }],
912
- "style/lines-between-class-members": ["error", "always", { exceptAfterSingleLine: true }],
913
- "style/max-statements-per-line": ["error", { max: 1 }],
914
- "style/member-delimiter-style": ["error", { multiline: { delimiter: "none" } }],
915
682
  "style/multiline-ternary": ["error", "never"],
916
- "style/new-parens": "error",
917
- "style/no-extra-parens": ["error", "functions"],
918
- "style/no-floating-decimal": "error",
919
- "style/no-mixed-operators": ["error", {
920
- allowSamePrecedence: true,
921
- groups: [
922
- ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
923
- ["&&", "||"],
924
- ["in", "instanceof"]
925
- ]
926
- }],
927
- "style/no-mixed-spaces-and-tabs": "error",
928
- "style/no-multi-spaces": "error",
929
- "style/no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
930
- "style/no-tabs": indent === "tab" ? "off" : "error",
931
- "style/no-trailing-spaces": "error",
932
- "style/no-whitespace-before-property": "error",
933
- "style/object-curly-newline": ["error", { consistent: true, multiline: true }],
934
- "style/object-curly-spacing": ["error", "always"],
935
- "style/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
936
- "style/operator-linebreak": ["error", "before"],
937
- "style/padded-blocks": ["error", { blocks: "never", classes: "never", switches: "never" }],
938
- "style/quote-props": ["error", "consistent-as-needed"],
939
- "style/quotes": ["error", quotes, { allowTemplateLiterals: true, avoidEscape: false }],
940
- "style/rest-spread-spacing": ["error", "never"],
941
- "style/semi": ["error", "never"],
942
- "style/semi-spacing": ["error", { after: true, before: false }],
943
- "style/space-before-blocks": ["error", "always"],
944
- "style/space-before-function-paren": ["error", { anonymous: "always", asyncArrow: "always", named: "never" }],
945
- "style/space-in-parens": ["error", "never"],
946
- "style/space-infix-ops": "error",
947
- "style/space-unary-ops": ["error", { nonwords: false, words: true }],
948
- "style/spaced-comment": ["error", "always", {
949
- block: {
950
- balanced: true,
951
- exceptions: ["*"],
952
- markers: ["!"]
953
- },
954
- line: {
955
- exceptions: ["/", "#"],
956
- markers: ["/"]
957
- }
958
- }],
959
- "style/template-curly-spacing": "error",
960
- "style/template-tag-spacing": ["error", "never"],
961
- "style/type-annotation-spacing": ["error", {}],
962
- "style/wrap-iife": ["error", "any", { functionPrototypeMethods: true }],
963
- "style/yield-star-spacing": ["error", "both"],
964
- ...jsx ? {
965
- "style/jsx-closing-bracket-location": "error",
966
- "style/jsx-closing-tag-location": "error",
967
- "style/jsx-curly-brace-presence": ["error", { propElementValues: "always" }],
968
- "style/jsx-curly-newline": "error",
969
- "style/jsx-curly-spacing": ["error", "never"],
970
- "style/jsx-equals-spacing": "error",
971
- "style/jsx-first-prop-new-line": "error",
972
- "style/jsx-indent": ["error", indent, { checkAttributes: true, indentLogicalExpressions: true }],
973
- "style/jsx-indent-props": ["error", indent],
974
- "style/jsx-max-props-per-line": ["error", { maximum: 4 }],
975
- // 在 JSX 中的单行上强制执行最多 props 数量
976
- "style/jsx-newline": "off",
977
- // 在 jsx 元素和表达式之后换行
978
- "style/jsx-one-expression-per-line": ["error", { allow: "single-child" }],
979
- "style/jsx-quotes": ["error", "prefer-double"],
980
- // 强制在 JSX 属性中一致使用双引号或单引号
981
- "style/jsx-tag-spacing": ["error", {
982
- afterOpening: "never",
983
- beforeClosing: "never",
984
- beforeSelfClosing: "always",
985
- closingSlash: "never"
986
- }],
987
- "style/jsx-wrap-multilines": ["error", {
988
- arrow: "parens-new-line",
989
- assignment: "parens-new-line",
990
- condition: "parens-new-line",
991
- declaration: "parens-new-line",
992
- logical: "parens-new-line",
993
- prop: "parens-new-line",
994
- return: "parens-new-line"
995
- }]
996
- } : {},
997
683
  ...overrides
998
684
  }
999
685
  }
1000
686
  ];
1001
687
  }
1002
688
 
1003
- // src/configs/typescript.ts
1004
- import process2 from "process";
1005
- async function typescript(options = {}) {
1006
- const {
1007
- componentExts = [],
1008
- overrides = {},
1009
- parserOptions = {}
1010
- } = options;
1011
- const files = options.files ?? [
1012
- GLOB_SRC,
1013
- ...componentExts.map((ext) => `**/*.${ext}`)
1014
- ];
1015
- const typeAwareRules = {
1016
- "dot-notation": "off",
1017
- "no-implied-eval": "off",
1018
- "no-throw-literal": "off",
1019
- "ts/await-thenable": "error",
1020
- "ts/dot-notation": ["error", { allowKeywords: true }],
1021
- "ts/no-floating-promises": "error",
1022
- "ts/no-for-in-array": "error",
1023
- "ts/no-implied-eval": "error",
1024
- "ts/no-misused-promises": "error",
1025
- "ts/no-throw-literal": "error",
1026
- "ts/no-unnecessary-type-assertion": "error",
1027
- "ts/no-unsafe-argument": "error",
1028
- "ts/no-unsafe-assignment": "error",
1029
- "ts/no-unsafe-call": "error",
1030
- "ts/no-unsafe-member-access": "error",
1031
- "ts/no-unsafe-return": "error",
1032
- "ts/restrict-plus-operands": "error",
1033
- "ts/restrict-template-expressions": "error",
1034
- "ts/unbound-method": "error"
1035
- };
1036
- const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1037
- const [
1038
- pluginTs,
1039
- parserTs
1040
- ] = await Promise.all([
1041
- interopDefault(import("@typescript-eslint/eslint-plugin")),
1042
- interopDefault(import("@typescript-eslint/parser"))
689
+ // src/configs/formatters.ts
690
+ async function formatters(options = {}, stylistic2 = {}) {
691
+ await ensurePackages([
692
+ "eslint-plugin-format"
1043
693
  ]);
1044
- return [
694
+ if (options === true) {
695
+ options = {
696
+ css: true,
697
+ graphql: false,
698
+ html: true,
699
+ markdown: true,
700
+ toml: true
701
+ };
702
+ }
703
+ const {
704
+ indent,
705
+ quotes,
706
+ semi
707
+ } = {
708
+ ...StylisticConfigDefaults,
709
+ ...stylistic2
710
+ };
711
+ const prettierOptions = Object.assign(
1045
712
  {
1046
- // Install the plugins without globs, so they can be configured separately.
1047
- name: "eslint:typescript:setup",
1048
- plugins: {
1049
- antfu: default2,
1050
- ts: pluginTs
1051
- }
713
+ semi,
714
+ singleQuote: quotes === "single",
715
+ tabWidth: typeof indent === "number" ? indent : 2,
716
+ trailingComma: "all",
717
+ useTabs: indent === "tab"
1052
718
  },
719
+ options.prettierOptions || {}
720
+ );
721
+ const dprintOptions = Object.assign(
1053
722
  {
1054
- files,
1055
- languageOptions: {
1056
- parser: parserTs,
1057
- parserOptions: {
1058
- extraFileExtensions: componentExts.map((ext) => `.${ext}`),
1059
- sourceType: "module",
1060
- ...tsconfigPath ? {
1061
- project: tsconfigPath,
1062
- tsconfigRootDir: process2.cwd()
1063
- } : {},
1064
- ...parserOptions
723
+ indentWidth: typeof indent === "number" ? indent : 2,
724
+ quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
725
+ useTabs: indent === "tab"
726
+ },
727
+ options.dprintOptions || {}
728
+ );
729
+ const pluginFormat = await interopDefault(import("eslint-plugin-format"));
730
+ const configs = [
731
+ {
732
+ name: "eslint:formatters:setup",
733
+ plugins: {
734
+ format: pluginFormat
735
+ }
736
+ }
737
+ ];
738
+ if (options.css) {
739
+ configs.push(
740
+ {
741
+ files: [GLOB_CSS, GLOB_POSTCSS],
742
+ languageOptions: {
743
+ parser: pluginFormat.parserPlain
744
+ },
745
+ name: "eslint:formatter:css",
746
+ rules: {
747
+ "format/prettier": [
748
+ "error",
749
+ {
750
+ ...prettierOptions,
751
+ parser: "css"
752
+ }
753
+ ]
1065
754
  }
1066
755
  },
1067
- name: "eslint:typescript:rules",
756
+ {
757
+ files: [GLOB_SCSS],
758
+ languageOptions: {
759
+ parser: pluginFormat.parserPlain
760
+ },
761
+ name: "eslint:formatter:scss",
762
+ rules: {
763
+ "format/prettier": [
764
+ "error",
765
+ {
766
+ ...prettierOptions,
767
+ parser: "scss"
768
+ }
769
+ ]
770
+ }
771
+ },
772
+ {
773
+ files: [GLOB_LESS],
774
+ languageOptions: {
775
+ parser: pluginFormat.parserPlain
776
+ },
777
+ name: "eslint:formatter:less",
778
+ rules: {
779
+ "format/prettier": [
780
+ "error",
781
+ {
782
+ ...prettierOptions,
783
+ parser: "less"
784
+ }
785
+ ]
786
+ }
787
+ }
788
+ );
789
+ }
790
+ if (options.html) {
791
+ configs.push({
792
+ files: ["**/*.html"],
793
+ languageOptions: {
794
+ parser: pluginFormat.parserPlain
795
+ },
796
+ name: "eslint:formatter:html",
1068
797
  rules: {
1069
- ...renameRules(
1070
- pluginTs.configs["eslint-recommended"].overrides[0].rules,
1071
- "@typescript-eslint/",
1072
- "ts/"
1073
- ),
1074
- ...renameRules(
1075
- pluginTs.configs.strict.rules,
1076
- "@typescript-eslint/",
1077
- "ts/"
1078
- ),
1079
- "antfu/generic-spacing": "error",
1080
- "antfu/named-tuple-spacing": "error",
1081
- "no-dupe-class-members": "off",
1082
- "no-invalid-this": "off",
1083
- "no-loss-of-precision": "off",
1084
- "no-redeclare": "off",
1085
- "no-use-before-define": "off",
1086
- "no-useless-constructor": "off",
1087
- "ts/ban-ts-comment": ["error", { "ts-ignore": "allow-with-description" }],
1088
- "ts/ban-types": ["error", { types: { Function: false } }],
1089
- "ts/consistent-type-definitions": ["error", "interface"],
1090
- "ts/consistent-type-imports": ["error", { disallowTypeAnnotations: false, prefer: "type-imports" }],
1091
- "ts/no-dupe-class-members": "error",
1092
- "ts/no-dynamic-delete": "off",
1093
- "ts/no-explicit-any": "off",
1094
- "ts/no-extraneous-class": "off",
1095
- "ts/no-import-type-side-effects": "error",
1096
- "ts/no-invalid-this": "error",
1097
- "ts/no-invalid-void-type": "off",
1098
- "ts/no-loss-of-precision": "error",
1099
- "ts/no-non-null-assertion": "off",
1100
- "ts/no-redeclare": "error",
1101
- "ts/no-require-imports": "error",
1102
- "ts/no-unused-vars": "off",
1103
- "ts/no-use-before-define": ["error", { classes: false, functions: false, variables: true }],
1104
- "ts/no-useless-constructor": "off",
1105
- "ts/prefer-ts-expect-error": "error",
1106
- "ts/triple-slash-reference": "off",
1107
- "ts/unified-signatures": "off",
1108
- ...tsconfigPath ? typeAwareRules : {},
1109
- ...overrides
798
+ "format/prettier": [
799
+ "error",
800
+ {
801
+ ...prettierOptions,
802
+ parser: "html"
803
+ }
804
+ ]
1110
805
  }
1111
- },
1112
- {
1113
- files: ["**/*.d.ts"],
1114
- name: "eslint:typescript:dts-overrides",
806
+ });
807
+ }
808
+ if (options.toml) {
809
+ configs.push({
810
+ files: ["**/*.toml"],
811
+ languageOptions: {
812
+ parser: pluginFormat.parserPlain
813
+ },
814
+ name: "eslint:formatter:toml",
1115
815
  rules: {
1116
- "eslint-comments/no-unlimited-disable": "off",
1117
- "import/no-duplicates": "off",
1118
- "no-restricted-syntax": "off",
1119
- "unused-imports/no-unused-vars": "off"
816
+ "format/dprint": [
817
+ "error",
818
+ {
819
+ ...dprintOptions,
820
+ language: "toml"
821
+ }
822
+ ]
1120
823
  }
1121
- },
1122
- {
1123
- files: ["**/*.{test,spec}.ts?(x)"],
1124
- name: "eslint:typescript:tests-overrides",
824
+ });
825
+ }
826
+ if (options.markdown) {
827
+ const formater = options.markdown === true ? "prettier" : options.markdown;
828
+ configs.push({
829
+ files: ["**/*.__markdown_content__"],
830
+ languageOptions: {
831
+ parser: pluginFormat.parserPlain
832
+ },
833
+ name: "eslint:formatter:markdown",
1125
834
  rules: {
1126
- "no-unused-expressions": "off"
835
+ [`format/${formater}`]: [
836
+ "error",
837
+ formater === "prettier" ? {
838
+ ...prettierOptions,
839
+ embeddedLanguageFormatting: "off",
840
+ parser: "markdown"
841
+ } : {
842
+ ...dprintOptions,
843
+ language: "markdown"
844
+ }
845
+ ]
1127
846
  }
1128
- },
1129
- {
1130
- files: ["**/*.js", "**/*.cjs"],
1131
- name: "eslint:typescript:javascript-overrides",
847
+ });
848
+ }
849
+ if (options.graphql) {
850
+ configs.push({
851
+ files: ["**/*.graphql"],
852
+ languageOptions: {
853
+ parser: pluginFormat.parserPlain
854
+ },
855
+ name: "eslint:formatter:graphql",
1132
856
  rules: {
1133
- "ts/no-require-imports": "off",
1134
- "ts/no-var-requires": "off"
857
+ "format/prettier": [
858
+ "error",
859
+ {
860
+ ...prettierOptions,
861
+ parser: "graphql"
862
+ }
863
+ ]
1135
864
  }
1136
- }
1137
- ];
865
+ });
866
+ }
867
+ return configs;
1138
868
  }
1139
869
 
1140
- // src/configs/unicorn.ts
1141
- async function unicorn() {
870
+ // src/configs/node.ts
871
+ async function node() {
1142
872
  return [
1143
873
  {
1144
- name: "eslint:unicorn",
874
+ name: "eslint:node",
1145
875
  plugins: {
1146
- unicorn: default5
876
+ node: default4
1147
877
  },
1148
878
  rules: {
1149
- // Pass error message when throwing errors
1150
- "unicorn/error-message": "error",
1151
- // Uppercase regex escapes
1152
- "unicorn/escape-case": "error",
1153
- // Array.isArray instead of instanceof
1154
- "unicorn/no-instanceof-array": "error",
1155
- // Ban `new Array` as `Array` constructor's params are ambiguous
1156
- "unicorn/no-new-array": "error",
1157
- // Prevent deprecated `new Buffer()`
1158
- "unicorn/no-new-buffer": "error",
1159
- // Keep regex literals safe!
1160
- "unicorn/no-unsafe-regex": "error",
1161
- // Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
1162
- "unicorn/number-literal-case": "error",
1163
- // textContent instead of innerText
1164
- "unicorn/prefer-dom-node-text-content": "error",
1165
- // includes over indexOf when checking for existence
1166
- "unicorn/prefer-includes": "error",
1167
- // Prefer using the node: protocol
1168
- "unicorn/prefer-node-protocol": "error",
1169
- // Prefer using number properties like `Number.isNaN` rather than `isNaN`
1170
- "unicorn/prefer-number-properties": "error",
1171
- // String methods startsWith/endsWith instead of more complicated stuff
1172
- "unicorn/prefer-string-starts-ends-with": "error",
1173
- // Enforce throwing type error when throwing error while checking typeof
1174
- "unicorn/prefer-type-error": "error",
1175
- // Use new when throwing error
1176
- "unicorn/throw-new-error": "error"
879
+ "node/handle-callback-err": ["error", "^(err|error)$"],
880
+ "node/no-deprecated-api": "error",
881
+ "node/no-exports-assign": "error",
882
+ "node/no-new-require": "error",
883
+ "node/no-path-concat": "error",
884
+ "node/prefer-global/buffer": ["error", "never"],
885
+ "node/prefer-global/process": ["error", "never"],
886
+ "node/process-exit-as-throw": "error"
1177
887
  }
1178
888
  }
1179
889
  ];
1180
890
  }
1181
891
 
1182
- // src/configs/vue.ts
1183
- import { getPackageInfoSync } from "local-pkg";
1184
- var pkg = getPackageInfoSync("vue");
1185
- var vueVersion = pkg && pkg.version;
1186
- vueVersion = vueVersion && vueVersion[0];
1187
- vueVersion = Number.isNaN(vueVersion) ? "3" : vueVersion;
1188
- async function vue(options = {}) {
892
+ // src/configs/react.ts
893
+ import { isPackageExists as isPackageExists2 } from "local-pkg";
894
+ var ReactRefreshAllowConstantExportPackages = [
895
+ "vite"
896
+ ];
897
+ async function react(options = {}) {
1189
898
  const {
1190
- files = [GLOB_VUE],
899
+ files = [GLOB_JSX, GLOB_TSX],
900
+ jsx = true,
1191
901
  overrides = {},
1192
- stylistic: stylistic2 = true
902
+ typescript: typescript2 = true,
903
+ version = "detect"
1193
904
  } = options;
1194
- const {
1195
- indent = 4
1196
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
905
+ await ensurePackages([
906
+ "eslint-plugin-react",
907
+ "eslint-plugin-react-hooks",
908
+ "eslint-plugin-react-refresh"
909
+ ]);
1197
910
  const [
1198
- pluginVue,
1199
- parserVue
911
+ pluginReact,
912
+ pluginReactHooks,
913
+ pluginReactRefresh
1200
914
  ] = await Promise.all([
1201
915
  // @ts-expect-error missing types
1202
- interopDefault(import("eslint-plugin-vue")),
1203
- interopDefault(import("vue-eslint-parser"))
916
+ interopDefault(import("eslint-plugin-react")),
917
+ // @ts-expect-error missing types
918
+ interopDefault(import("eslint-plugin-react-hooks")),
919
+ // @ts-expect-error missing types
920
+ interopDefault(import("eslint-plugin-react-refresh"))
1204
921
  ]);
922
+ const _isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
923
+ (i) => isPackageExists2(i)
924
+ );
1205
925
  return [
1206
926
  {
1207
- name: "eslint:vue:setup",
927
+ name: "eslint:react:setup",
1208
928
  plugins: {
1209
- vue: pluginVue
929
+ "react": pluginReact,
930
+ "react-hooks": pluginReactHooks,
931
+ "react-refresh": pluginReactRefresh
1210
932
  }
1211
933
  },
1212
934
  {
1213
935
  files,
1214
936
  languageOptions: {
1215
- parser: parserVue,
1216
937
  parserOptions: {
1217
938
  ecmaFeatures: {
1218
- jsx: true
1219
- },
1220
- extraFileExtensions: [".vue"],
1221
- parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null,
1222
- sourceType: "module"
939
+ jsx
940
+ }
1223
941
  }
1224
942
  },
1225
- name: "eslint:vue:rules",
1226
- processor: pluginVue.processors[".vue"],
943
+ name: "eslint:react:rules",
1227
944
  rules: {
1228
- ...pluginVue.configs.base.rules,
1229
- ...vueVersion === "3" ? {
1230
- ...pluginVue.configs["vue3-essential"].rules,
1231
- ...pluginVue.configs["vue3-strongly-recommended"].rules,
1232
- ...pluginVue.configs["vue3-recommended"].rules
1233
- } : {
1234
- ...pluginVue.configs.essential.rules,
1235
- ...pluginVue.configs["strongly-recommended"].rules,
1236
- ...pluginVue.configs.recommended.rules
1237
- },
1238
- "node/prefer-global/process": "off",
1239
- "vue/block-order": ["error", {
1240
- order: ["template", "script", "style"]
1241
- }],
1242
- "vue/component-name-in-template-casing": ["error", "PascalCase"],
1243
- "vue/component-options-name-casing": ["error", "PascalCase"],
1244
- "vue/custom-event-name-casing": vueVersion === "3" ? ["error", "camelCase"] : ["error", "kebab-case"],
1245
- ...vueVersion === "2" ? {
1246
- "vue/require-explicit-emits": "off"
1247
- } : null,
1248
- "vue/define-macros-order": ["error", {
1249
- order: ["defineOptions", "defineProps", "defineEmits", "defineSlots"]
1250
- }],
1251
- "vue/dot-location": ["error", "property"],
1252
- "vue/dot-notation": ["error", { allowKeywords: true }],
1253
- "vue/eqeqeq": ["error", "smart"],
1254
- "vue/html-indent": ["error", indent, {
1255
- alignAttributesVertically: true,
1256
- attribute: 1,
1257
- baseIndent: 1,
1258
- closeBracket: 0,
1259
- ignores: []
1260
- }],
1261
- "vue/html-self-closing": ["error", {
1262
- html: {
1263
- component: "any",
1264
- normal: "any",
1265
- void: "never"
1266
- },
1267
- math: "always",
1268
- svg: "always"
1269
- }],
1270
- "vue/max-attributes-per-line": "off",
1271
- "vue/multi-word-component-names": "off",
1272
- "vue/no-constant-condition": "warn",
1273
- "vue/no-dupe-keys": "off",
1274
- "vue/no-empty-pattern": "error",
1275
- "vue/no-extra-parens": ["error", "functions"],
1276
- "vue/no-irregular-whitespace": "error",
1277
- "vue/no-loss-of-precision": "error",
1278
- "vue/no-restricted-syntax": [
1279
- "error",
1280
- "DebuggerStatement",
1281
- "LabeledStatement",
1282
- "WithStatement"
1283
- ],
1284
- "vue/no-restricted-v-bind": ["error", "/^v-/"],
1285
- "vue/no-setup-props-reactivity-loss": "off",
1286
- "vue/no-sparse-arrays": "error",
1287
- "vue/no-unused-refs": "error",
1288
- "vue/no-useless-v-bind": "error",
1289
- "vue/no-v-html": "off",
1290
- "vue/no-v-text-v-html-on-component": "off",
1291
- "vue/object-shorthand": ["error", "always", {
1292
- avoidQuotes: true,
1293
- ignoreConstructors: false
1294
- }],
1295
- "vue/prefer-separate-static-class": "error",
1296
- "vue/prefer-template": "error",
1297
- "vue/require-default-prop": "off",
1298
- "vue/require-prop-types": "off",
1299
- "vue/singleline-html-element-content-newline": "off",
1300
- "vue/space-infix-ops": "error",
1301
- "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1302
- ...stylistic2 ? {
1303
- "vue/array-bracket-spacing": ["error", "never"],
1304
- "vue/arrow-spacing": ["error", { after: true, before: true }],
1305
- "vue/block-spacing": ["error", "always"],
1306
- "vue/block-tag-newline": ["error", { multiline: "always", singleline: "always" }],
1307
- "vue/brace-style": ["error", "stroustrup", { allowSingleLine: true }],
1308
- "vue/comma-dangle": ["error", "always-multiline"],
1309
- "vue/comma-spacing": ["error", { after: true, before: false }],
1310
- "vue/comma-style": ["error", "last"],
1311
- "vue/html-comment-content-spacing": ["error", "always", { exceptions: ["-"] }],
1312
- "vue/key-spacing": ["error", { afterColon: true, beforeColon: false }],
1313
- "vue/keyword-spacing": ["error", { after: true, before: true }],
1314
- "vue/object-curly-newline": "off",
1315
- "vue/object-curly-spacing": ["error", "always"],
1316
- "vue/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
1317
- "vue/operator-linebreak": ["error", "before"],
1318
- "vue/padding-line-between-blocks": ["error", "always"],
1319
- "vue/quote-props": ["error", "consistent-as-needed"],
1320
- "vue/space-in-parens": ["error", "never"],
1321
- "vue/template-curly-spacing": "error"
945
+ // react-hooks
946
+ "react-hooks/exhaustive-deps": "warn",
947
+ "react-hooks/rules-of-hooks": "error",
948
+ // react-refresh
949
+ // 'react-refresh/only-export-components': [
950
+ // 'warn',
951
+ // { allowConstantExport: _isAllowConstantExport },
952
+ // ],
953
+ "react-refresh/only-export-components": "off",
954
+ // react
955
+ "react/boolean-prop-naming": "error",
956
+ "react/button-has-type": "error",
957
+ "react/default-props-match-prop-types": "error",
958
+ "react/destructuring-assignment": "error",
959
+ "react/display-name": "error",
960
+ "react/forbid-component-props": "off",
961
+ // 禁止组件上使用某些 props
962
+ "react/forbid-dom-props": "error",
963
+ "react/forbid-elements": "error",
964
+ "react/forbid-foreign-prop-types": "error",
965
+ "react/forbid-prop-types": "error",
966
+ "react/function-component-definition": "error",
967
+ "react/hook-use-state": "off",
968
+ // useState 钩子值和 setter 变量的解构和对称命名
969
+ "react/iframe-missing-sandbox": "error",
970
+ "react/jsx-boolean-value": "error",
971
+ "react/jsx-filename-extension": "off",
972
+ // 禁止可能包含 JSX 文件扩展名
973
+ "react/jsx-fragments": "error",
974
+ "react/jsx-handler-names": "error",
975
+ "react/jsx-key": "error",
976
+ "react/jsx-max-depth": "off",
977
+ // 强制 JSX 最大深度
978
+ "react/jsx-no-bind": "off",
979
+ // .bind()JSX 属性中禁止使用箭头函数
980
+ "react/jsx-no-comment-textnodes": "error",
981
+ "react/jsx-no-constructed-context-values": "error",
982
+ "react/jsx-no-duplicate-props": "error",
983
+ "react/jsx-no-leaked-render": "error",
984
+ "react/jsx-no-literals": "off",
985
+ // 禁止在 JSX 中使用字符串文字
986
+ "react/jsx-no-script-url": "error",
987
+ "react/jsx-no-target-blank": "error",
988
+ "react/jsx-no-undef": "error",
989
+ "react/jsx-no-useless-fragment": "error",
990
+ "react/jsx-pascal-case": "error",
991
+ "react/jsx-props-no-spreading": "off",
992
+ // 强制任何 JSX 属性都不会传播
993
+ "react/jsx-uses-react": "error",
994
+ "react/jsx-uses-vars": "error",
995
+ "react/no-access-state-in-setstate": "error",
996
+ "react/no-adjacent-inline-elements": "error",
997
+ "react/no-array-index-key": "error",
998
+ "react/no-arrow-function-lifecycle": "error",
999
+ "react/no-children-prop": "error",
1000
+ "react/no-danger": "off",
1001
+ // 禁止使用 dangerouslySetInnerHTML
1002
+ "react/no-danger-with-children": "error",
1003
+ "react/no-deprecated": "error",
1004
+ "react/no-did-mount-set-state": "error",
1005
+ "react/no-did-update-set-state": "error",
1006
+ "react/no-direct-mutation-state": "error",
1007
+ "react/no-find-dom-node": "error",
1008
+ "react/no-invalid-html-attribute": "error",
1009
+ "react/no-is-mounted": "error",
1010
+ "react/no-multi-comp": "error",
1011
+ "react/no-namespace": "error",
1012
+ "react/no-object-type-as-default-prop": "error",
1013
+ "react/no-redundant-should-component-update": "error",
1014
+ "react/no-render-return-value": "error",
1015
+ "react/no-set-state": "error",
1016
+ "react/no-string-refs": "error",
1017
+ "react/no-this-in-sfc": "error",
1018
+ "react/no-typos": "error",
1019
+ "react/no-unescaped-entities": "error",
1020
+ "react/no-unknown-property": "error",
1021
+ "react/no-unsafe": "off",
1022
+ // 禁止使用不安全的生命周期方法
1023
+ "react/no-unstable-nested-components": "error",
1024
+ "react/no-unused-class-component-methods": "error",
1025
+ "react/no-unused-prop-types": "error",
1026
+ "react/no-unused-state": "error",
1027
+ "react/no-will-update-set-state": "error",
1028
+ "react/prefer-es6-class": "error",
1029
+ "react/prefer-exact-props": "error",
1030
+ "react/prefer-read-only-props": "error",
1031
+ "react/prefer-stateless-function": "error",
1032
+ "react/prop-types": "error",
1033
+ "react/react-in-jsx-scope": "off",
1034
+ // 使用 JSX 时需要引入 React
1035
+ "react/require-default-props": "off",
1036
+ // 为每个非必需 prop 强制执行 defaultProps 定义
1037
+ "react/require-optimization": "error",
1038
+ "react/require-render-return": "error",
1039
+ "react/self-closing-comp": "error",
1040
+ "react/sort-comp": "error",
1041
+ "react/sort-default-props": "error",
1042
+ "react/sort-prop-types": "error",
1043
+ "react/state-in-constructor": "error",
1044
+ "react/static-property-placement": "error",
1045
+ "react/style-prop-object": "error",
1046
+ "react/void-dom-elements-no-children": "error",
1047
+ ...typescript2 ? {
1048
+ "react/jsx-no-undef": "off",
1049
+ "react/prop-type": "off"
1322
1050
  } : {},
1323
1051
  ...overrides
1052
+ },
1053
+ settings: {
1054
+ react: {
1055
+ version
1056
+ }
1324
1057
  }
1325
1058
  }
1326
1059
  ];
1327
1060
  }
1328
1061
 
1329
- // src/configs/yaml.ts
1330
- async function yaml(options = {}) {
1331
- const {
1332
- files = [GLOB_YAML],
1333
- overrides = {},
1334
- stylistic: stylistic2 = true
1335
- } = options;
1336
- const [
1337
- pluginYaml,
1338
- parserYaml
1339
- ] = await Promise.all([
1340
- interopDefault(import("eslint-plugin-yml")),
1341
- interopDefault(import("yaml-eslint-parser"))
1342
- ]);
1062
+ // src/configs/sort.ts
1063
+ async function sortPackageJson() {
1343
1064
  return [
1344
1065
  {
1345
- name: "eslint:yaml:setup",
1346
- plugins: {
1347
- yaml: pluginYaml
1066
+ files: ["**/package.json"],
1067
+ name: "eslint:sort-package-json",
1068
+ rules: {
1069
+ "jsonc/sort-array-values": [
1070
+ "error",
1071
+ {
1072
+ order: { type: "asc" },
1073
+ pathPattern: "^files$"
1074
+ }
1075
+ ],
1076
+ "jsonc/sort-keys": [
1077
+ "error",
1078
+ {
1079
+ order: [
1080
+ "publisher",
1081
+ "name",
1082
+ "displayName",
1083
+ "type",
1084
+ "version",
1085
+ "private",
1086
+ "packageManager",
1087
+ "description",
1088
+ "author",
1089
+ "license",
1090
+ "funding",
1091
+ "homepage",
1092
+ "repository",
1093
+ "bugs",
1094
+ "keywords",
1095
+ "categories",
1096
+ "sideEffects",
1097
+ "exports",
1098
+ "main",
1099
+ "module",
1100
+ "unpkg",
1101
+ "jsdelivr",
1102
+ "types",
1103
+ "typesVersions",
1104
+ "bin",
1105
+ "icon",
1106
+ "files",
1107
+ "engines",
1108
+ "activationEvents",
1109
+ "contributes",
1110
+ "scripts",
1111
+ "peerDependencies",
1112
+ "peerDependenciesMeta",
1113
+ "dependencies",
1114
+ "optionalDependencies",
1115
+ "devDependencies",
1116
+ "pnpm",
1117
+ "overrides",
1118
+ "resolutions",
1119
+ "husky",
1120
+ "simple-git-hooks",
1121
+ "lint-staged",
1122
+ "eslintConfig"
1123
+ ],
1124
+ pathPattern: "^$"
1125
+ },
1126
+ {
1127
+ order: { type: "asc" },
1128
+ pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies$"
1129
+ },
1130
+ {
1131
+ order: { type: "asc" },
1132
+ pathPattern: "^resolutions$"
1133
+ },
1134
+ {
1135
+ order: { type: "asc" },
1136
+ pathPattern: "^pnpm.overrides$"
1137
+ },
1138
+ {
1139
+ order: [
1140
+ "types",
1141
+ "import",
1142
+ "require",
1143
+ "default"
1144
+ ],
1145
+ pathPattern: "^exports.*$"
1146
+ }
1147
+ ]
1348
1148
  }
1349
- },
1149
+ }
1150
+ ];
1151
+ }
1152
+ function sortTsconfig() {
1153
+ return [
1350
1154
  {
1351
- files,
1352
- languageOptions: {
1353
- parser: parserYaml
1354
- },
1355
- name: "eslint:yaml:rules",
1155
+ files: ["**/tsconfig.json", "**/tsconfig.*.json"],
1156
+ name: "eslint:sort-tsconfig",
1356
1157
  rules: {
1357
- "style/spaced-comment": "off",
1358
- "yaml/block-mapping": "error",
1359
- "yaml/block-sequence": "error",
1360
- "yaml/no-empty-key": "error",
1361
- "yaml/no-empty-sequence-entry": "error",
1362
- "yaml/no-irregular-whitespace": "error",
1363
- "yaml/plain-scalar": "error",
1364
- "yaml/vue-custom-block/no-parsing-error": "error",
1365
- ...stylistic2 ? {
1366
- "yaml/block-mapping-question-indicator-newline": "error",
1367
- "yaml/block-sequence-hyphen-indicator-newline": "error",
1368
- "yaml/flow-mapping-curly-newline": "error",
1369
- "yaml/flow-mapping-curly-spacing": "error",
1370
- "yaml/flow-sequence-bracket-newline": "error",
1371
- "yaml/flow-sequence-bracket-spacing": "error",
1372
- "yaml/indent": ["error", 2],
1373
- "yaml/key-spacing": "error",
1374
- "yaml/no-tab-indent": "error",
1375
- "yaml/quotes": ["error", { avoidEscape: false, prefer: "single" }],
1376
- "yaml/spaced-comment": "error"
1377
- } : {},
1378
- ...overrides
1158
+ "jsonc/sort-keys": [
1159
+ "error",
1160
+ {
1161
+ order: [
1162
+ "extends",
1163
+ "compilerOptions",
1164
+ "references",
1165
+ "files",
1166
+ "include",
1167
+ "exclude"
1168
+ ],
1169
+ pathPattern: "^$"
1170
+ },
1171
+ {
1172
+ order: [
1173
+ /* Projects */
1174
+ "incremental",
1175
+ "composite",
1176
+ "tsBuildInfoFile",
1177
+ "disableSourceOfProjectReferenceRedirect",
1178
+ "disableSolutionSearching",
1179
+ "disableReferencedProjectLoad",
1180
+ /* Language and Environment */
1181
+ "target",
1182
+ "jsx",
1183
+ "jsxFactory",
1184
+ "jsxFragmentFactory",
1185
+ "jsxImportSource",
1186
+ "lib",
1187
+ "moduleDetection",
1188
+ "noLib",
1189
+ "reactNamespace",
1190
+ "useDefineForClassFields",
1191
+ "emitDecoratorMetadata",
1192
+ "experimentalDecorators",
1193
+ /* Modules */
1194
+ "baseUrl",
1195
+ "rootDir",
1196
+ "rootDirs",
1197
+ "customConditions",
1198
+ "module",
1199
+ "moduleResolution",
1200
+ "moduleSuffixes",
1201
+ "noResolve",
1202
+ "paths",
1203
+ "resolveJsonModule",
1204
+ "resolvePackageJsonExports",
1205
+ "resolvePackageJsonImports",
1206
+ "typeRoots",
1207
+ "types",
1208
+ "allowArbitraryExtensions",
1209
+ "allowImportingTsExtensions",
1210
+ "allowUmdGlobalAccess",
1211
+ /* JavaScript Support */
1212
+ "allowJs",
1213
+ "checkJs",
1214
+ "maxNodeModuleJsDepth",
1215
+ /* Type Checking */
1216
+ "strict",
1217
+ "strictBindCallApply",
1218
+ "strictFunctionTypes",
1219
+ "strictNullChecks",
1220
+ "strictPropertyInitialization",
1221
+ "allowUnreachableCode",
1222
+ "allowUnusedLabels",
1223
+ "alwaysStrict",
1224
+ "exactOptionalPropertyTypes",
1225
+ "noFallthroughCasesInSwitch",
1226
+ "noImplicitAny",
1227
+ "noImplicitOverride",
1228
+ "noImplicitReturns",
1229
+ "noImplicitThis",
1230
+ "noPropertyAccessFromIndexSignature",
1231
+ "noUncheckedIndexedAccess",
1232
+ "noUnusedLocals",
1233
+ "noUnusedParameters",
1234
+ "useUnknownInCatchVariables",
1235
+ /* Emit */
1236
+ "declaration",
1237
+ "declarationDir",
1238
+ "declarationMap",
1239
+ "downlevelIteration",
1240
+ "emitBOM",
1241
+ "emitDeclarationOnly",
1242
+ "importHelpers",
1243
+ "importsNotUsedAsValues",
1244
+ "inlineSourceMap",
1245
+ "inlineSources",
1246
+ "mapRoot",
1247
+ "newLine",
1248
+ "noEmit",
1249
+ "noEmitHelpers",
1250
+ "noEmitOnError",
1251
+ "outDir",
1252
+ "outFile",
1253
+ "preserveConstEnums",
1254
+ "preserveValueImports",
1255
+ "removeComments",
1256
+ "sourceMap",
1257
+ "sourceRoot",
1258
+ "stripInternal",
1259
+ /* Interop Constraints */
1260
+ "allowSyntheticDefaultImports",
1261
+ "esModuleInterop",
1262
+ "forceConsistentCasingInFileNames",
1263
+ "isolatedModules",
1264
+ "preserveSymlinks",
1265
+ "verbatimModuleSyntax",
1266
+ /* Completeness */
1267
+ "skipDefaultLibCheck",
1268
+ "skipLibCheck"
1269
+ ],
1270
+ pathPattern: "^compilerOptions$"
1271
+ }
1272
+ ]
1379
1273
  }
1380
1274
  }
1381
1275
  ];
@@ -1411,198 +1305,191 @@ async function test(options = {}) {
1411
1305
  }
1412
1306
  },
1413
1307
  {
1414
- files,
1415
- name: "eslint:test:rules",
1416
- rules: {
1417
- "node/prefer-global/process": "off",
1418
- "test/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
1419
- "test/no-identical-title": "error",
1420
- "test/no-only-tests": isInEditor ? "off" : "error",
1421
- "test/prefer-hooks-in-order": "error",
1422
- "test/prefer-lowercase-title": "error",
1423
- ...overrides
1424
- }
1425
- }
1426
- ];
1427
- }
1428
-
1429
- // src/configs/perfectionist.ts
1430
- async function perfectionist() {
1431
- return [
1432
- {
1433
- name: "eslint:perfectionist",
1434
- plugins: {
1435
- perfectionist: default7
1308
+ files,
1309
+ name: "eslint:test:rules",
1310
+ rules: {
1311
+ "node/prefer-global/process": "off",
1312
+ "test/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
1313
+ "test/no-identical-title": "error",
1314
+ "test/no-only-tests": isInEditor ? "off" : "error",
1315
+ "test/prefer-hooks-in-order": "error",
1316
+ "test/prefer-lowercase-title": "error",
1317
+ ...overrides
1436
1318
  }
1437
1319
  }
1438
1320
  ];
1439
1321
  }
1440
1322
 
1441
- // src/configs/react.ts
1442
- import { isPackageExists as isPackageExists2 } from "local-pkg";
1443
- var ReactRefreshAllowConstantExportPackages = [
1444
- "vite"
1445
- ];
1446
- async function react(options = {}) {
1323
+ // src/configs/typescript.ts
1324
+ import process2 from "process";
1325
+ async function typescript(options = {}) {
1447
1326
  const {
1448
- files = [GLOB_JSX, GLOB_TSX],
1449
- jsx = true,
1327
+ componentExts = [],
1450
1328
  overrides = {},
1451
- typescript: typescript2 = true,
1452
- version = "17.0"
1329
+ parserOptions = {}
1453
1330
  } = options;
1454
- await ensurePackages([
1455
- "eslint-plugin-react",
1456
- "eslint-plugin-react-hooks",
1457
- "eslint-plugin-react-refresh"
1458
- ]);
1331
+ const files = options.files ?? [
1332
+ GLOB_SRC,
1333
+ ...componentExts.map((ext) => `**/*.${ext}`)
1334
+ ];
1335
+ const typeAwareRules = {
1336
+ "dot-notation": "off",
1337
+ "no-implied-eval": "off",
1338
+ "no-throw-literal": "off",
1339
+ "ts/await-thenable": "error",
1340
+ "ts/dot-notation": ["error", { allowKeywords: true }],
1341
+ "ts/no-floating-promises": "error",
1342
+ "ts/no-for-in-array": "error",
1343
+ "ts/no-implied-eval": "error",
1344
+ "ts/no-misused-promises": "error",
1345
+ "ts/no-throw-literal": "error",
1346
+ "ts/no-unnecessary-type-assertion": "error",
1347
+ "ts/no-unsafe-argument": "error",
1348
+ "ts/no-unsafe-assignment": "error",
1349
+ "ts/no-unsafe-call": "error",
1350
+ "ts/no-unsafe-member-access": "error",
1351
+ "ts/no-unsafe-return": "error",
1352
+ "ts/restrict-plus-operands": "error",
1353
+ "ts/restrict-template-expressions": "error",
1354
+ "ts/unbound-method": "error"
1355
+ };
1356
+ const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1459
1357
  const [
1460
- pluginReact,
1461
- pluginReactHooks,
1462
- pluginReactRefresh
1358
+ pluginTs,
1359
+ parserTs
1463
1360
  ] = await Promise.all([
1464
- // @ts-expect-error missing types
1465
- interopDefault(import("eslint-plugin-react")),
1466
- // @ts-expect-error missing types
1467
- interopDefault(import("eslint-plugin-react-hooks")),
1468
- // @ts-expect-error missing types
1469
- interopDefault(import("eslint-plugin-react-refresh"))
1361
+ interopDefault(import("@typescript-eslint/eslint-plugin")),
1362
+ interopDefault(import("@typescript-eslint/parser"))
1470
1363
  ]);
1471
- const _isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
1472
- (i) => isPackageExists2(i)
1473
- );
1474
1364
  return [
1475
1365
  {
1476
- name: "eslint:react:setup",
1366
+ // Install the plugins without globs, so they can be configured separately.
1367
+ name: "eslint:typescript:setup",
1477
1368
  plugins: {
1478
- "react": pluginReact,
1479
- "react-hooks": pluginReactHooks,
1480
- "react-refresh": pluginReactRefresh
1369
+ antfu: default2,
1370
+ ts: pluginTs
1481
1371
  }
1482
1372
  },
1483
1373
  {
1484
1374
  files,
1485
1375
  languageOptions: {
1376
+ parser: parserTs,
1486
1377
  parserOptions: {
1487
- ecmaFeatures: {
1488
- jsx
1489
- }
1378
+ extraFileExtensions: componentExts.map((ext) => `.${ext}`),
1379
+ sourceType: "module",
1380
+ ...tsconfigPath ? {
1381
+ project: tsconfigPath,
1382
+ tsconfigRootDir: process2.cwd()
1383
+ } : {},
1384
+ ...parserOptions
1490
1385
  }
1491
1386
  },
1492
- name: "eslint:react:rules",
1387
+ name: "eslint:typescript:rules",
1493
1388
  rules: {
1494
- // react-hooks
1495
- "react-hooks/exhaustive-deps": "warn",
1496
- "react-hooks/rules-of-hooks": "error",
1497
- // react-refresh
1498
- // 'react-refresh/only-export-components': [
1499
- // 'warn',
1500
- // { allowConstantExport: _isAllowConstantExport },
1501
- // ],
1502
- "react-refresh/only-export-components": "off",
1503
- // react
1504
- "react/boolean-prop-naming": "error",
1505
- "react/button-has-type": "error",
1506
- "react/default-props-match-prop-types": "error",
1507
- "react/destructuring-assignment": "error",
1508
- "react/display-name": "error",
1509
- "react/forbid-component-props": "off",
1510
- // 禁止组件上使用某些 props
1511
- "react/forbid-dom-props": "error",
1512
- "react/forbid-elements": "error",
1513
- "react/forbid-foreign-prop-types": "error",
1514
- "react/forbid-prop-types": "error",
1515
- "react/function-component-definition": "error",
1516
- "react/hook-use-state": "off",
1517
- // useState 钩子值和 setter 变量的解构和对称命名
1518
- "react/iframe-missing-sandbox": "error",
1519
- "react/jsx-boolean-value": "error",
1520
- "react/jsx-filename-extension": "off",
1521
- // 禁止可能包含 JSX 文件扩展名
1522
- "react/jsx-fragments": "error",
1523
- "react/jsx-handler-names": "error",
1524
- "react/jsx-key": "error",
1525
- "react/jsx-max-depth": "off",
1526
- // 强制 JSX 最大深度
1527
- "react/jsx-no-bind": "off",
1528
- // .bind()JSX 属性中禁止使用箭头函数
1529
- "react/jsx-no-comment-textnodes": "error",
1530
- "react/jsx-no-constructed-context-values": "error",
1531
- "react/jsx-no-duplicate-props": "error",
1532
- "react/jsx-no-leaked-render": "error",
1533
- "react/jsx-no-literals": "off",
1534
- // 禁止在 JSX 中使用字符串文字
1535
- "react/jsx-no-script-url": "error",
1536
- "react/jsx-no-target-blank": "error",
1537
- "react/jsx-no-undef": "error",
1538
- "react/jsx-no-useless-fragment": "error",
1539
- "react/jsx-pascal-case": "error",
1540
- "react/jsx-props-no-spreading": "off",
1541
- // 强制任何 JSX 属性都不会传播
1542
- "react/jsx-uses-react": "error",
1543
- "react/jsx-uses-vars": "error",
1544
- "react/no-access-state-in-setstate": "error",
1545
- "react/no-adjacent-inline-elements": "error",
1546
- "react/no-array-index-key": "error",
1547
- "react/no-arrow-function-lifecycle": "error",
1548
- "react/no-children-prop": "error",
1549
- "react/no-danger": "off",
1550
- // 禁止使用 dangerouslySetInnerHTML
1551
- "react/no-danger-with-children": "error",
1552
- "react/no-deprecated": "error",
1553
- "react/no-did-mount-set-state": "error",
1554
- "react/no-did-update-set-state": "error",
1555
- "react/no-direct-mutation-state": "error",
1556
- "react/no-find-dom-node": "error",
1557
- "react/no-invalid-html-attribute": "error",
1558
- "react/no-is-mounted": "error",
1559
- "react/no-multi-comp": "error",
1560
- "react/no-namespace": "error",
1561
- "react/no-object-type-as-default-prop": "error",
1562
- "react/no-redundant-should-component-update": "error",
1563
- "react/no-render-return-value": "error",
1564
- "react/no-set-state": "error",
1565
- "react/no-string-refs": "error",
1566
- "react/no-this-in-sfc": "error",
1567
- "react/no-typos": "error",
1568
- "react/no-unescaped-entities": "error",
1569
- "react/no-unknown-property": "error",
1570
- "react/no-unsafe": "off",
1571
- // 禁止使用不安全的生命周期方法
1572
- "react/no-unstable-nested-components": "error",
1573
- "react/no-unused-class-component-methods": "error",
1574
- "react/no-unused-prop-types": "error",
1575
- "react/no-unused-state": "error",
1576
- "react/no-will-update-set-state": "error",
1577
- "react/prefer-es6-class": "error",
1578
- "react/prefer-exact-props": "error",
1579
- "react/prefer-read-only-props": "error",
1580
- "react/prefer-stateless-function": "error",
1581
- "react/prop-types": "error",
1582
- "react/react-in-jsx-scope": "off",
1583
- // 使用 JSX 时需要引入 React
1584
- "react/require-default-props": "off",
1585
- // 为每个非必需 prop 强制执行 defaultProps 定义
1586
- "react/require-optimization": "error",
1587
- "react/require-render-return": "error",
1588
- "react/self-closing-comp": "error",
1589
- "react/sort-comp": "error",
1590
- "react/sort-default-props": "error",
1591
- "react/sort-prop-types": "error",
1592
- "react/state-in-constructor": "error",
1593
- "react/static-property-placement": "error",
1594
- "react/style-prop-object": "error",
1595
- "react/void-dom-elements-no-children": "error",
1596
- ...typescript2 ? {
1597
- "react/jsx-no-undef": "off",
1598
- "react/prop-type": "off"
1599
- } : {},
1389
+ ...renameRules(
1390
+ pluginTs.configs["eslint-recommended"].overrides[0].rules,
1391
+ "@typescript-eslint/",
1392
+ "ts/"
1393
+ ),
1394
+ ...renameRules(
1395
+ pluginTs.configs.strict.rules,
1396
+ "@typescript-eslint/",
1397
+ "ts/"
1398
+ ),
1399
+ "no-dupe-class-members": "off",
1400
+ "no-loss-of-precision": "off",
1401
+ "no-redeclare": "off",
1402
+ "no-use-before-define": "off",
1403
+ "no-useless-constructor": "off",
1404
+ "ts/ban-ts-comment": ["error", { "ts-ignore": "allow-with-description" }],
1405
+ "ts/ban-types": ["error", { types: { Function: false } }],
1406
+ "ts/consistent-type-definitions": ["error", "interface"],
1407
+ "ts/consistent-type-imports": ["error", { disallowTypeAnnotations: false, prefer: "type-imports" }],
1408
+ "ts/no-dupe-class-members": "error",
1409
+ "ts/no-dynamic-delete": "off",
1410
+ "ts/no-explicit-any": "off",
1411
+ "ts/no-extraneous-class": "off",
1412
+ "ts/no-import-type-side-effects": "error",
1413
+ "ts/no-invalid-void-type": "off",
1414
+ "ts/no-loss-of-precision": "error",
1415
+ "ts/no-non-null-assertion": "off",
1416
+ "ts/no-redeclare": "error",
1417
+ "ts/no-require-imports": "error",
1418
+ "ts/no-unused-vars": "off",
1419
+ "ts/no-use-before-define": ["error", { classes: false, functions: false, variables: true }],
1420
+ "ts/no-useless-constructor": "off",
1421
+ "ts/prefer-ts-expect-error": "error",
1422
+ "ts/triple-slash-reference": "off",
1423
+ "ts/unified-signatures": "off",
1424
+ ...tsconfigPath ? typeAwareRules : {},
1600
1425
  ...overrides
1426
+ }
1427
+ },
1428
+ {
1429
+ files: ["**/*.d.ts"],
1430
+ name: "eslint:typescript:dts-overrides",
1431
+ rules: {
1432
+ "eslint-comments/no-unlimited-disable": "off",
1433
+ "import/no-duplicates": "off",
1434
+ "no-restricted-syntax": "off",
1435
+ "unused-imports/no-unused-vars": "off"
1436
+ }
1437
+ },
1438
+ {
1439
+ files: ["**/*.{test,spec}.ts?(x)"],
1440
+ name: "eslint:typescript:tests-overrides",
1441
+ rules: {
1442
+ "no-unused-expressions": "off"
1443
+ }
1444
+ },
1445
+ {
1446
+ files: ["**/*.js", "**/*.cjs"],
1447
+ name: "eslint:typescript:javascript-overrides",
1448
+ rules: {
1449
+ "ts/no-require-imports": "off",
1450
+ "ts/no-var-requires": "off"
1451
+ }
1452
+ }
1453
+ ];
1454
+ }
1455
+
1456
+ // src/configs/unicorn.ts
1457
+ async function unicorn() {
1458
+ return [
1459
+ {
1460
+ name: "eslint:unicorn",
1461
+ plugins: {
1462
+ unicorn: default5
1601
1463
  },
1602
- settings: {
1603
- react: {
1604
- version
1605
- }
1464
+ rules: {
1465
+ // Pass error message when throwing errors
1466
+ "unicorn/error-message": "error",
1467
+ // Uppercase regex escapes
1468
+ "unicorn/escape-case": "error",
1469
+ // Array.isArray instead of instanceof
1470
+ "unicorn/no-instanceof-array": "error",
1471
+ // Ban `new Array` as `Array` constructor's params are ambiguous
1472
+ "unicorn/no-new-array": "error",
1473
+ // Prevent deprecated `new Buffer()`
1474
+ "unicorn/no-new-buffer": "error",
1475
+ // Keep regex literals safe!
1476
+ "unicorn/no-unsafe-regex": "error",
1477
+ // Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
1478
+ "unicorn/number-literal-case": "error",
1479
+ // textContent instead of innerText
1480
+ "unicorn/prefer-dom-node-text-content": "error",
1481
+ // includes over indexOf when checking for existence
1482
+ "unicorn/prefer-includes": "error",
1483
+ // Prefer using the node: protocol
1484
+ "unicorn/prefer-node-protocol": "error",
1485
+ // Prefer using number properties like `Number.isNaN` rather than `isNaN`
1486
+ "unicorn/prefer-number-properties": "error",
1487
+ // String methods startsWith/endsWith instead of more complicated stuff
1488
+ "unicorn/prefer-string-starts-ends-with": "error",
1489
+ // Enforce throwing type error when throwing error while checking typeof
1490
+ "unicorn/prefer-type-error": "error",
1491
+ // Use new when throwing error
1492
+ "unicorn/throw-new-error": "error"
1606
1493
  }
1607
1494
  }
1608
1495
  ];
@@ -1641,6 +1528,208 @@ async function unocss(options = {}) {
1641
1528
  ];
1642
1529
  }
1643
1530
 
1531
+ // src/configs/vue.ts
1532
+ import { getPackageInfoSync } from "local-pkg";
1533
+ var pkg = getPackageInfoSync("vue");
1534
+ var vueVersion = pkg && pkg.version;
1535
+ vueVersion = vueVersion && vueVersion[0];
1536
+ vueVersion = Number.isNaN(vueVersion) ? "3" : vueVersion;
1537
+ async function vue(options = {}) {
1538
+ const {
1539
+ files = [GLOB_VUE],
1540
+ overrides = {},
1541
+ stylistic: stylistic2 = true
1542
+ } = options;
1543
+ const {
1544
+ indent = 4
1545
+ } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1546
+ const [
1547
+ pluginVue,
1548
+ parserVue
1549
+ ] = await Promise.all([
1550
+ // @ts-expect-error missing types
1551
+ interopDefault(import("eslint-plugin-vue")),
1552
+ interopDefault(import("vue-eslint-parser"))
1553
+ ]);
1554
+ return [
1555
+ {
1556
+ name: "eslint:vue:setup",
1557
+ plugins: {
1558
+ vue: pluginVue
1559
+ }
1560
+ },
1561
+ {
1562
+ files,
1563
+ languageOptions: {
1564
+ parser: parserVue,
1565
+ parserOptions: {
1566
+ ecmaFeatures: {
1567
+ jsx: true
1568
+ },
1569
+ extraFileExtensions: [".vue"],
1570
+ parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null,
1571
+ sourceType: "module"
1572
+ }
1573
+ },
1574
+ name: "eslint:vue:rules",
1575
+ processor: pluginVue.processors[".vue"],
1576
+ rules: {
1577
+ ...pluginVue.configs.base.rules,
1578
+ ...vueVersion === "3" ? {
1579
+ ...pluginVue.configs["vue3-essential"].rules,
1580
+ ...pluginVue.configs["vue3-strongly-recommended"].rules,
1581
+ ...pluginVue.configs["vue3-recommended"].rules
1582
+ } : {
1583
+ ...pluginVue.configs.essential.rules,
1584
+ ...pluginVue.configs["strongly-recommended"].rules,
1585
+ ...pluginVue.configs.recommended.rules
1586
+ },
1587
+ "node/prefer-global/process": "off",
1588
+ "vue/block-order": ["error", {
1589
+ order: ["template", "script", "style"]
1590
+ }],
1591
+ "vue/component-name-in-template-casing": ["error", "PascalCase"],
1592
+ "vue/component-options-name-casing": ["error", "PascalCase"],
1593
+ "vue/custom-event-name-casing": vueVersion === "3" ? ["error", "camelCase"] : ["error", "kebab-case"],
1594
+ ...vueVersion === "2" ? {
1595
+ "vue/require-explicit-emits": "off"
1596
+ } : null,
1597
+ "vue/define-macros-order": ["error", {
1598
+ order: ["defineOptions", "defineProps", "defineEmits", "defineSlots"]
1599
+ }],
1600
+ "vue/dot-location": ["error", "property"],
1601
+ "vue/dot-notation": ["error", { allowKeywords: true }],
1602
+ "vue/eqeqeq": ["error", "smart"],
1603
+ "vue/html-indent": ["error", indent, {
1604
+ alignAttributesVertically: true,
1605
+ attribute: 1,
1606
+ baseIndent: 1,
1607
+ closeBracket: 0,
1608
+ ignores: []
1609
+ }],
1610
+ "vue/html-self-closing": ["error", {
1611
+ html: {
1612
+ component: "any",
1613
+ normal: "any",
1614
+ void: "never"
1615
+ },
1616
+ math: "always",
1617
+ svg: "always"
1618
+ }],
1619
+ "vue/max-attributes-per-line": "off",
1620
+ "vue/multi-word-component-names": "off",
1621
+ "vue/no-constant-condition": "warn",
1622
+ "vue/no-dupe-keys": "off",
1623
+ "vue/no-empty-pattern": "error",
1624
+ "vue/no-extra-parens": ["error", "functions"],
1625
+ "vue/no-irregular-whitespace": "error",
1626
+ "vue/no-loss-of-precision": "error",
1627
+ "vue/no-restricted-syntax": [
1628
+ "error",
1629
+ "DebuggerStatement",
1630
+ "LabeledStatement",
1631
+ "WithStatement"
1632
+ ],
1633
+ "vue/no-restricted-v-bind": ["error", "/^v-/"],
1634
+ "vue/no-setup-props-reactivity-loss": "off",
1635
+ "vue/no-sparse-arrays": "error",
1636
+ "vue/no-unused-refs": "error",
1637
+ "vue/no-useless-v-bind": "error",
1638
+ "vue/no-v-html": "off",
1639
+ "vue/no-v-text-v-html-on-component": "off",
1640
+ "vue/object-shorthand": ["error", "always", {
1641
+ avoidQuotes: true,
1642
+ ignoreConstructors: false
1643
+ }],
1644
+ "vue/prefer-separate-static-class": "error",
1645
+ "vue/prefer-template": "error",
1646
+ "vue/require-default-prop": "off",
1647
+ "vue/require-prop-types": "off",
1648
+ "vue/singleline-html-element-content-newline": "off",
1649
+ "vue/space-infix-ops": "error",
1650
+ "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1651
+ ...stylistic2 ? {
1652
+ "vue/array-bracket-spacing": ["error", "never"],
1653
+ "vue/arrow-spacing": ["error", { after: true, before: true }],
1654
+ "vue/block-spacing": ["error", "always"],
1655
+ "vue/block-tag-newline": ["error", { multiline: "always", singleline: "always" }],
1656
+ "vue/brace-style": ["error", "stroustrup", { allowSingleLine: true }],
1657
+ "vue/comma-dangle": ["error", "always-multiline"],
1658
+ "vue/comma-spacing": ["error", { after: true, before: false }],
1659
+ "vue/comma-style": ["error", "last"],
1660
+ "vue/html-comment-content-spacing": ["error", "always", { exceptions: ["-"] }],
1661
+ "vue/key-spacing": ["error", { afterColon: true, beforeColon: false }],
1662
+ "vue/keyword-spacing": ["error", { after: true, before: true }],
1663
+ "vue/object-curly-newline": "off",
1664
+ "vue/object-curly-spacing": ["error", "always"],
1665
+ "vue/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
1666
+ "vue/operator-linebreak": ["error", "before"],
1667
+ "vue/padding-line-between-blocks": ["error", "always"],
1668
+ "vue/quote-props": ["error", "consistent-as-needed"],
1669
+ "vue/space-in-parens": ["error", "never"],
1670
+ "vue/template-curly-spacing": "error"
1671
+ } : {},
1672
+ ...overrides
1673
+ }
1674
+ }
1675
+ ];
1676
+ }
1677
+
1678
+ // src/configs/yaml.ts
1679
+ async function yaml(options = {}) {
1680
+ const {
1681
+ files = [GLOB_YAML],
1682
+ overrides = {},
1683
+ stylistic: stylistic2 = true
1684
+ } = options;
1685
+ const [
1686
+ pluginYaml,
1687
+ parserYaml
1688
+ ] = await Promise.all([
1689
+ interopDefault(import("eslint-plugin-yml")),
1690
+ interopDefault(import("yaml-eslint-parser"))
1691
+ ]);
1692
+ return [
1693
+ {
1694
+ name: "eslint:yaml:setup",
1695
+ plugins: {
1696
+ yaml: pluginYaml
1697
+ }
1698
+ },
1699
+ {
1700
+ files,
1701
+ languageOptions: {
1702
+ parser: parserYaml
1703
+ },
1704
+ name: "eslint:yaml:rules",
1705
+ rules: {
1706
+ "style/spaced-comment": "off",
1707
+ "yaml/block-mapping": "error",
1708
+ "yaml/block-sequence": "error",
1709
+ "yaml/no-empty-key": "error",
1710
+ "yaml/no-empty-sequence-entry": "error",
1711
+ "yaml/no-irregular-whitespace": "error",
1712
+ "yaml/plain-scalar": "error",
1713
+ "yaml/vue-custom-block/no-parsing-error": "error",
1714
+ ...stylistic2 ? {
1715
+ "yaml/block-mapping-question-indicator-newline": "error",
1716
+ "yaml/block-sequence-hyphen-indicator-newline": "error",
1717
+ "yaml/flow-mapping-curly-newline": "error",
1718
+ "yaml/flow-mapping-curly-spacing": "error",
1719
+ "yaml/flow-sequence-bracket-newline": "error",
1720
+ "yaml/flow-sequence-bracket-spacing": "error",
1721
+ "yaml/indent": ["error", 2],
1722
+ "yaml/key-spacing": "error",
1723
+ "yaml/no-tab-indent": "error",
1724
+ "yaml/quotes": ["error", { avoidEscape: false, prefer: "single" }],
1725
+ "yaml/spaced-comment": "error"
1726
+ } : {},
1727
+ ...overrides
1728
+ }
1729
+ }
1730
+ ];
1731
+ }
1732
+
1644
1733
  // src/factory.ts
1645
1734
  var flatConfigProps = [
1646
1735
  "files",
@@ -1768,11 +1857,20 @@ async function lincy(options = {}, ...userConfigs) {
1768
1857
  }));
1769
1858
  }
1770
1859
  if (options.markdown ?? true) {
1771
- configs.push(markdown({
1772
- ...typeof options.markdown !== "boolean" ? options.markdown : {},
1773
- componentExts,
1774
- overrides: overrides.markdown
1775
- }));
1860
+ configs.push(markdown(
1861
+ {
1862
+ ...typeof options.markdown !== "boolean" ? options.markdown : {},
1863
+ componentExts,
1864
+ overrides: overrides.markdown
1865
+ },
1866
+ options.formatters === true || !!(options.formatters || {})?.markdown
1867
+ ));
1868
+ }
1869
+ if (options.formatters) {
1870
+ configs.push(formatters(
1871
+ options.formatters,
1872
+ typeof stylisticOptions === "boolean" ? {} : stylisticOptions
1873
+ ));
1776
1874
  }
1777
1875
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
1778
1876
  if (key in options)
@@ -1803,6 +1901,8 @@ export {
1803
1901
  GLOB_LESS,
1804
1902
  GLOB_MARKDOWN,
1805
1903
  GLOB_MARKDOWN_CODE,
1904
+ GLOB_MARKDOWN_IN_MARKDOWN,
1905
+ GLOB_POSTCSS,
1806
1906
  GLOB_SCSS,
1807
1907
  GLOB_SRC,
1808
1908
  GLOB_SRC_EXT,
@@ -1812,10 +1912,12 @@ export {
1812
1912
  GLOB_TSX,
1813
1913
  GLOB_VUE,
1814
1914
  GLOB_YAML,
1915
+ StylisticConfigDefaults,
1815
1916
  combine,
1816
1917
  comments,
1817
1918
  src_default as default,
1818
1919
  ensurePackages,
1920
+ formatters,
1819
1921
  ignores,
1820
1922
  imports,
1821
1923
  interopDefault,