@dauphaihau/eslint-config 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -551,9 +551,11 @@ async function reactConfig(options = {}) {
551
551
  }
552
552
 
553
553
  // src/configs/tailwind.ts
554
+ import fs2 from "fs";
555
+ var tailwindConfigFile = ["tailwind.config.js", "tailwind.config.ts", "tailwind.config.mjs", "tailwind.config.cjs"].find((f) => fs2.existsSync(f));
554
556
  async function tailwindConfig(options = {}) {
555
557
  const tailwindFiles = strategyManager.getTailwindFiles(options);
556
- if (tailwindFiles.length === 0) {
558
+ if (tailwindFiles.length === 0 || !tailwindConfigFile) {
557
559
  return [];
558
560
  }
559
561
  const { default: tailwind } = await import("eslint-plugin-tailwindcss");
@@ -564,9 +566,8 @@ async function tailwindConfig(options = {}) {
564
566
  plugins: { tailwindcss: tailwind },
565
567
  settings: {
566
568
  tailwindcss: {
567
- // Common utility function callees to analyze for class names
569
+ config: tailwindConfigFile,
568
570
  callees: ["classnames", "clsx", "ctl", "cva", "cx", "cn"],
569
- // Support tagged template literals: tw`bg-blue-500`
570
571
  tags: ["tw"]
571
572
  }
572
573
  },
@@ -598,6 +599,60 @@ async function tailwindConfig(options = {}) {
598
599
  ];
599
600
  }
600
601
 
602
+ // src/configs/vue.ts
603
+ async function vueConfig(options = {}) {
604
+ const vueFiles = strategyManager.getVueFiles(options);
605
+ if (vueFiles.length === 0) {
606
+ return [];
607
+ }
608
+ const { default: pluginVue } = await import("eslint-plugin-vue");
609
+ const recommendedConfigs = pluginVue.configs["flat/recommended"];
610
+ const [pluginSetup, parserSetup, ...ruleConfigs] = recommendedConfigs;
611
+ const mergedRules = ruleConfigs.reduce(
612
+ (acc, c) => ({ ...acc, ...c.rules }),
613
+ {}
614
+ );
615
+ const tsParser = options.typescript ? (await import("typescript-eslint")).parser : void 0;
616
+ const parserConfig = tsParser ? {
617
+ ...parserSetup,
618
+ languageOptions: {
619
+ ...parserSetup.languageOptions,
620
+ parserOptions: {
621
+ ...parserSetup.languageOptions?.parserOptions,
622
+ parser: tsParser
623
+ }
624
+ }
625
+ } : parserSetup;
626
+ return [
627
+ pluginSetup,
628
+ // registers vue plugin globally
629
+ parserConfig,
630
+ // vue-eslint-parser + processor for *.vue files
631
+ {
632
+ name: "dauphaihau/vue",
633
+ files: vueFiles,
634
+ rules: {
635
+ ...mergedRules,
636
+ "vue/comment-directive": "off",
637
+ // meta-rule; disable directives handled by ESLint core
638
+ "vue/component-name-in-template-casing": ["error", "PascalCase"],
639
+ "vue/component-definition-name-casing": ["error", "PascalCase"],
640
+ "vue/multi-word-component-names": "warn",
641
+ "vue/no-v-html": "warn",
642
+ "vue/html-self-closing": ["error", {
643
+ html: { void: "always", normal: "always", component: "always" },
644
+ svg: "always",
645
+ math: "always"
646
+ }],
647
+ "vue/attribute-hyphenation": ["error", "always"],
648
+ "vue/no-unused-vars": "error",
649
+ "vue/no-use-v-if-with-v-for": "error",
650
+ "vue/require-v-for-key": "error"
651
+ }
652
+ }
653
+ ];
654
+ }
655
+
601
656
  // src/configs/naming.ts
602
657
  import ts2 from "typescript-eslint";
603
658
  var identifierQualityRules = {
@@ -680,6 +735,12 @@ var baseNamingSelectors = [
680
735
  format: null
681
736
  // allow anything -> API response, snake_case keys allowed
682
737
  },
738
+ {
739
+ // External type declarations may expose quoted keys such as 'flat/recommended'.
740
+ selector: "typeProperty",
741
+ modifiers: ["requiresQuotes"],
742
+ format: null
743
+ },
683
744
  {
684
745
  // internal domain types
685
746
  selector: "typeProperty",
@@ -803,6 +864,7 @@ var ESLintConfigBuilder = class {
803
864
  this.fileNamesAdded = false;
804
865
  this.typescriptAdded = false;
805
866
  this.reactAdded = false;
867
+ this.vueAdded = false;
806
868
  this.tailwindAdded = false;
807
869
  }
808
870
  /**
@@ -883,6 +945,21 @@ var ESLintConfigBuilder = class {
883
945
  this.reactAdded = true;
884
946
  return this;
885
947
  }
948
+ /**
949
+ * Add Vue-specific rules and plugins.
950
+ * Requires vue option to be set to true.
951
+ */
952
+ withVue(options) {
953
+ const mergedOptions = { ...this.options, ...options };
954
+ if (!mergedOptions.vue) {
955
+ console.warn(
956
+ "ESLintConfigBuilder: Vue config added but vue option is not set. Consider calling setOptions({ vue: true }) first."
957
+ );
958
+ }
959
+ this.pendingConfigs.push(vueConfig(mergedOptions));
960
+ this.vueAdded = true;
961
+ return this;
962
+ }
886
963
  /**
887
964
  * Add Tailwind CSS-specific rules and plugins.
888
965
  * Requires tailwind option to be set to true.
@@ -927,6 +1004,9 @@ var ESLintConfigBuilder = class {
927
1004
  if (mergedOptions.react) {
928
1005
  this.withReact(mergedOptions);
929
1006
  }
1007
+ if (mergedOptions.vue) {
1008
+ this.withVue(mergedOptions);
1009
+ }
930
1010
  if (mergedOptions.tailwind) {
931
1011
  this.withTailwind(mergedOptions);
932
1012
  }
@@ -953,6 +1033,7 @@ var ESLintConfigBuilder = class {
953
1033
  this.fileNamesAdded = false;
954
1034
  this.typescriptAdded = false;
955
1035
  this.reactAdded = false;
1036
+ this.vueAdded = false;
956
1037
  this.tailwindAdded = false;
957
1038
  return this;
958
1039
  }
@@ -983,19 +1064,22 @@ var ESLintConfigBuilder = class {
983
1064
  hasReact() {
984
1065
  return this.reactAdded;
985
1066
  }
1067
+ hasVue() {
1068
+ return this.vueAdded;
1069
+ }
986
1070
  hasTailwind() {
987
1071
  return this.tailwindAdded;
988
1072
  }
989
1073
  };
990
1074
 
991
1075
  // src/index.ts
992
- import fs2 from "fs";
993
- var hasTsConfig = fs2.existsSync("tsconfig.json") || fs2.existsSync("tsconfig.base.json");
1076
+ import fs3 from "fs";
1077
+ var hasTsConfig = fs3.existsSync("tsconfig.json") || fs3.existsSync("tsconfig.base.json");
994
1078
  var hasReact = () => {
995
1079
  try {
996
1080
  const packageJsonPath = "package.json";
997
- if (fs2.existsSync(packageJsonPath)) {
998
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
1081
+ if (fs3.existsSync(packageJsonPath)) {
1082
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
999
1083
  const deps = {
1000
1084
  ...packageJson.dependencies,
1001
1085
  ...packageJson.devDependencies,
@@ -1007,11 +1091,27 @@ var hasReact = () => {
1007
1091
  }
1008
1092
  return false;
1009
1093
  };
1094
+ var hasVue = () => {
1095
+ try {
1096
+ const packageJsonPath = "package.json";
1097
+ if (fs3.existsSync(packageJsonPath)) {
1098
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1099
+ const deps = {
1100
+ ...packageJson.dependencies,
1101
+ ...packageJson.devDependencies,
1102
+ ...packageJson.peerDependencies
1103
+ };
1104
+ return "vue" in deps;
1105
+ }
1106
+ } catch {
1107
+ }
1108
+ return false;
1109
+ };
1010
1110
  var hasTailwind = () => {
1011
1111
  try {
1012
1112
  const packageJsonPath = "package.json";
1013
- if (fs2.existsSync(packageJsonPath)) {
1014
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
1113
+ if (fs3.existsSync(packageJsonPath)) {
1114
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1015
1115
  const deps = {
1016
1116
  ...packageJson.dependencies,
1017
1117
  ...packageJson.devDependencies,
@@ -1021,12 +1121,13 @@ var hasTailwind = () => {
1021
1121
  }
1022
1122
  } catch {
1023
1123
  }
1024
- return fs2.existsSync("tailwind.config.js") || fs2.existsSync("tailwind.config.ts") || fs2.existsSync("tailwind.config.mjs") || fs2.existsSync("tailwind.config.cjs");
1124
+ return fs3.existsSync("tailwind.config.js") || fs3.existsSync("tailwind.config.ts") || fs3.existsSync("tailwind.config.mjs") || fs3.existsSync("tailwind.config.cjs");
1025
1125
  };
1026
1126
  function eslintConfig(options = {}) {
1027
1127
  const finalOptions = {
1028
1128
  typescript: options.typescript ?? hasTsConfig,
1029
1129
  react: options.react ?? hasReact(),
1130
+ vue: options.vue ?? hasVue(),
1030
1131
  tailwind: options.tailwind ?? hasTailwind(),
1031
1132
  ...options
1032
1133
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dauphaihau/eslint-config",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,6 +34,12 @@
34
34
  },
35
35
  "eslint-plugin-tailwindcss": {
36
36
  "optional": true
37
+ },
38
+ "eslint-plugin-vue": {
39
+ "optional": true
40
+ },
41
+ "vue-eslint-parser": {
42
+ "optional": true
37
43
  }
38
44
  },
39
45
  "devDependencies": {
@@ -43,13 +49,15 @@
43
49
  "eslint-plugin-react-hooks": "^7.0.1",
44
50
  "eslint-plugin-react-refresh": "^0.5.2",
45
51
  "eslint-plugin-tailwindcss": "^3.18.2",
52
+ "eslint-plugin-vue": "^10.0.0",
53
+ "vue-eslint-parser": "^10.0.0",
46
54
  "jiti": "^2.0.0",
47
55
  "tsup": "^8.0.0",
48
56
  "typescript": "^5.4.0",
49
57
  "vitest": "^3.2.4"
50
58
  },
51
59
  "scripts": {
52
- "build": "pnpm exec tsup src/index.ts --dts --format esm --external @eslint/js --external @stylistic/eslint-plugin --external typescript-eslint --external eslint-plugin-check-file --external eslint-plugin-react --external eslint-plugin-react-hooks --external eslint-plugin-react-refresh --external eslint-plugin-tailwindcss",
60
+ "build": "pnpm exec tsup src/index.ts --dts --format esm --external @eslint/js --external @stylistic/eslint-plugin --external typescript-eslint --external eslint-plugin-check-file --external eslint-plugin-react --external eslint-plugin-react-hooks --external eslint-plugin-react-refresh --external eslint-plugin-tailwindcss --external eslint-plugin-vue --external vue-eslint-parser",
53
61
  "lint": "eslint .",
54
62
  "lint:fix": "eslint . --fix",
55
63
  "test": "vitest run",