@wondermarin/eslint-config 2.4.1 → 2.5.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.
Files changed (2) hide show
  1. package/dist/main.js +124 -186
  2. package/package.json +17 -18
package/dist/main.js CHANGED
@@ -895,10 +895,9 @@ async function typescriptConfig(projectRoot) {
895
895
 
896
896
  // src/configs/stylistic.ts
897
897
  async function stylisticConfig() {
898
- const [prettierConfig, prettierPlugin, stylisticPlugin, perfectionistPlugin] = await Promise.all([
898
+ const [prettierConfig, prettierPlugin, perfectionistPlugin] = await Promise.all([
899
899
  interopDefault(import('eslint-config-prettier')),
900
900
  interopDefault(import('eslint-plugin-prettier')),
901
- interopDefault(import('@stylistic/eslint-plugin')),
902
901
  interopDefault(import('eslint-plugin-perfectionist'))
903
902
  ]);
904
903
  return [
@@ -913,176 +912,6 @@ async function stylisticConfig() {
913
912
  ...prettierConfig.rules
914
913
  }
915
914
  },
916
- {
917
- name: "wondermarin/eslint-config/stylistic",
918
- files: ["**/*.?([cm])js" /* JS */, "**/*.jsx" /* JSX */, "**/*.?([cm])ts" /* TS */, "**/*.tsx" /* TSX */, "**/*.vue" /* VUE */],
919
- plugins: {
920
- "@stylistic": stylisticPlugin
921
- },
922
- rules: {
923
- "@stylistic/array-bracket-newline": "off",
924
- "@stylistic/array-bracket-spacing": "off",
925
- "@stylistic/array-element-newline": "off",
926
- "@stylistic/arrow-parens": "off",
927
- "@stylistic/arrow-spacing": "off",
928
- "@stylistic/block-spacing": "off",
929
- "@stylistic/brace-style": "off",
930
- "@stylistic/comma-dangle": "off",
931
- "@stylistic/comma-spacing": "off",
932
- "@stylistic/comma-style": "off",
933
- "@stylistic/computed-property-spacing": "off",
934
- "@stylistic/dot-location": "off",
935
- "@stylistic/eol-last": "off",
936
- "@stylistic/function-call-argument-newline": "off",
937
- "@stylistic/function-call-spacing": "off",
938
- "@stylistic/function-paren-newline": "off",
939
- "@stylistic/generator-star-spacing": "off",
940
- "@stylistic/implicit-arrow-linebreak": "off",
941
- "@stylistic/indent": "off",
942
- "@stylistic/indent-binary-ops": "off",
943
- "@stylistic/jsx-child-element-spacing": "off",
944
- "@stylistic/jsx-closing-bracket-location": "off",
945
- "@stylistic/jsx-closing-tag-location": "off",
946
- "@stylistic/jsx-curly-brace-presence": "off",
947
- "@stylistic/jsx-curly-newline": "off",
948
- "@stylistic/jsx-curly-spacing": "off",
949
- "@stylistic/jsx-equals-spacing": "off",
950
- "@stylistic/jsx-first-prop-new-line": "off",
951
- "@stylistic/jsx-function-call-newline": "off",
952
- "@stylistic/jsx-indent-props": "off",
953
- "@stylistic/jsx-max-props-per-line": "off",
954
- "@stylistic/jsx-newline": "off",
955
- "@stylistic/jsx-one-expression-per-line": "off",
956
- "@stylistic/jsx-pascal-case": "off",
957
- "@stylistic/jsx-props-no-multi-spaces": "off",
958
- "@stylistic/jsx-quotes": "off",
959
- "@stylistic/jsx-self-closing-comp": "off",
960
- "@stylistic/jsx-sort-props": "off",
961
- "@stylistic/jsx-tag-spacing": "off",
962
- "@stylistic/jsx-wrap-multilines": "off",
963
- "@stylistic/key-spacing": "off",
964
- "@stylistic/keyword-spacing": "off",
965
- "@stylistic/line-comment-position": "off",
966
- "@stylistic/linebreak-style": "off",
967
- "@stylistic/lines-around-comment": "off",
968
- "@stylistic/lines-between-class-members": "off",
969
- "@stylistic/max-len": "off",
970
- "@stylistic/max-statements-per-line": "off",
971
- "@stylistic/member-delimiter-style": "off",
972
- "@stylistic/multiline-comment-style": "off",
973
- "@stylistic/multiline-ternary": "off",
974
- "@stylistic/new-parens": "off",
975
- "@stylistic/newline-per-chained-call": "off",
976
- "@stylistic/no-confusing-arrow": "off",
977
- "@stylistic/no-extra-parens": "off",
978
- "@stylistic/no-extra-semi": "off",
979
- "@stylistic/no-floating-decimal": "off",
980
- "@stylistic/no-mixed-operators": "off",
981
- "@stylistic/no-mixed-spaces-and-tabs": "off",
982
- "@stylistic/no-multi-spaces": "off",
983
- "@stylistic/no-multiple-empty-lines": "off",
984
- "@stylistic/no-tabs": "off",
985
- "@stylistic/no-trailing-spaces": "off",
986
- "@stylistic/no-whitespace-before-property": "off",
987
- "@stylistic/nonblock-statement-body-position": "off",
988
- "@stylistic/object-curly-newline": "off",
989
- "@stylistic/object-curly-spacing": "off",
990
- "@stylistic/object-property-newline": "off",
991
- "@stylistic/one-var-declaration-per-line": "off",
992
- "@stylistic/operator-linebreak": "off",
993
- "@stylistic/padded-blocks": "off",
994
- "@stylistic/padding-line-between-statements": [
995
- "error",
996
- {
997
- blankLine: "always",
998
- next: "*",
999
- prev: [
1000
- "block-like",
1001
- "case",
1002
- "class",
1003
- "debugger",
1004
- "default",
1005
- "directive",
1006
- "do",
1007
- "expression",
1008
- "for",
1009
- "function",
1010
- "if",
1011
- "iife",
1012
- "multiline-expression",
1013
- "multiline-const",
1014
- "multiline-let",
1015
- "switch",
1016
- "throw",
1017
- "try",
1018
- "while",
1019
- "with"
1020
- ]
1021
- },
1022
- {
1023
- blankLine: "always",
1024
- next: [
1025
- "block-like",
1026
- "break",
1027
- "case",
1028
- "class",
1029
- "continue",
1030
- "debugger",
1031
- "default",
1032
- "do",
1033
- "expression",
1034
- "for",
1035
- "function",
1036
- "if",
1037
- "iife",
1038
- "multiline-expression",
1039
- "multiline-const",
1040
- "multiline-let",
1041
- "return",
1042
- "singleline-const",
1043
- "singleline-let",
1044
- "switch",
1045
- "throw",
1046
- "try",
1047
- "while",
1048
- "with"
1049
- ],
1050
- prev: "*"
1051
- },
1052
- {
1053
- blankLine: "any",
1054
- next: "expression",
1055
- prev: "expression"
1056
- },
1057
- {
1058
- blankLine: "any",
1059
- next: ["singleline-const", "singleline-let"],
1060
- prev: ["singleline-const", "singleline-let"]
1061
- }
1062
- ],
1063
- "@stylistic/quote-props": "off",
1064
- "@stylistic/quotes": "off",
1065
- "@stylistic/rest-spread-spacing": "off",
1066
- "@stylistic/semi": "off",
1067
- "@stylistic/semi-spacing": "off",
1068
- "@stylistic/semi-style": "off",
1069
- "@stylistic/space-before-blocks": "off",
1070
- "@stylistic/space-before-function-paren": "off",
1071
- "@stylistic/space-in-parens": "off",
1072
- "@stylistic/space-infix-ops": "off",
1073
- "@stylistic/space-unary-ops": "off",
1074
- "@stylistic/spaced-comment": "off",
1075
- "@stylistic/switch-colon-spacing": "off",
1076
- "@stylistic/template-curly-spacing": "off",
1077
- "@stylistic/template-tag-spacing": "off",
1078
- "@stylistic/type-annotation-spacing": "off",
1079
- "@stylistic/type-generic-spacing": "off",
1080
- "@stylistic/type-named-tuple-spacing": "off",
1081
- "@stylistic/wrap-iife": "off",
1082
- "@stylistic/wrap-regex": "off",
1083
- "@stylistic/yield-star-spacing": "off"
1084
- }
1085
- },
1086
915
  {
1087
916
  name: "wondermarin/eslint-config/perfectionist",
1088
917
  files: ["**/*.?([cm])js" /* JS */, "**/*.jsx" /* JSX */, "**/*.?([cm])ts" /* TS */, "**/*.tsx" /* TSX */, "**/*.vue" /* VUE */],
@@ -1207,6 +1036,21 @@ var fixedUpRuleReplacements = /* @__PURE__ */ new WeakMap();
1207
1036
  var fixedUpRules = /* @__PURE__ */ new WeakSet();
1208
1037
  var fixedUpPluginReplacements = /* @__PURE__ */ new WeakMap();
1209
1038
  var fixedUpPlugins = /* @__PURE__ */ new WeakSet();
1039
+ function nodesOrTokensOverlap(first, second) {
1040
+ return first.range[0] <= second.range[0] && first.range[1] >= second.range[0] || second.range[0] <= first.range[0] && second.range[1] >= first.range[0];
1041
+ }
1042
+ function looksLikeExport(node) {
1043
+ return node.type === "ExportDefaultDeclaration" || node.type === "ExportNamedDeclaration";
1044
+ }
1045
+ function findJSDocComment(node, sourceCode) {
1046
+ const tokenBefore = sourceCode.getTokenBefore(node, {
1047
+ includeComments: true
1048
+ });
1049
+ if (tokenBefore && tokenBefore.type === "Block" && tokenBefore.value.charAt(0) === "*" && node.loc.start.line - tokenBefore.loc.end.line <= 1) {
1050
+ return tokenBefore;
1051
+ }
1052
+ return null;
1053
+ }
1210
1054
  function fixupRule(ruleDefinition) {
1211
1055
  if (fixedUpRuleReplacements.has(ruleDefinition)) {
1212
1056
  return fixedUpRuleReplacements.get(ruleDefinition);
@@ -1217,35 +1061,129 @@ function fixupRule(ruleDefinition) {
1217
1061
  }
1218
1062
  const originalCreate = isLegacyRule ? ruleDefinition : ruleDefinition.create.bind(ruleDefinition);
1219
1063
  function ruleCreate(context) {
1064
+ const sourceCode = context.sourceCode;
1220
1065
  if ("getScope" in context) {
1221
1066
  return originalCreate(context);
1222
1067
  }
1223
- const sourceCode = context.sourceCode;
1224
- let currentNode = sourceCode.ast;
1225
- const newContext = Object.assign(Object.create(context), {
1226
- parserServices: sourceCode.parserServices,
1068
+ let eslintVersion = 9;
1069
+ if (!("getCwd" in context)) {
1070
+ eslintVersion = 10;
1071
+ }
1072
+ let compatSourceCode = sourceCode;
1073
+ if (eslintVersion >= 10) {
1074
+ compatSourceCode = Object.assign(Object.create(sourceCode), {
1075
+ getTokenOrCommentBefore(node, skip) {
1076
+ return sourceCode.getTokenBefore(node, {
1077
+ includeComments: true,
1078
+ skip
1079
+ });
1080
+ },
1081
+ getTokenOrCommentAfter(node, skip) {
1082
+ return sourceCode.getTokenAfter(node, {
1083
+ includeComments: true,
1084
+ skip
1085
+ });
1086
+ },
1087
+ isSpaceBetweenTokens(first, second) {
1088
+ if (nodesOrTokensOverlap(first, second)) {
1089
+ return false;
1090
+ }
1091
+ const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0] ? [first, second] : [second, first];
1092
+ const firstToken = sourceCode.getLastToken(startingNodeOrToken) || startingNodeOrToken;
1093
+ const finalToken = sourceCode.getFirstToken(endingNodeOrToken) || endingNodeOrToken;
1094
+ let currentToken = firstToken;
1095
+ while (currentToken !== finalToken) {
1096
+ const nextToken = sourceCode.getTokenAfter(
1097
+ currentToken,
1098
+ {
1099
+ includeComments: true
1100
+ }
1101
+ );
1102
+ if (currentToken.range[1] !== nextToken.range[0] || nextToken !== finalToken && nextToken.type === "JSXText" && /\s/u.test(nextToken.value)) {
1103
+ return true;
1104
+ }
1105
+ currentToken = nextToken;
1106
+ }
1107
+ return false;
1108
+ },
1109
+ getJSDocComment(node) {
1110
+ let parent = node.parent;
1111
+ switch (node.type) {
1112
+ case "ClassDeclaration":
1113
+ case "FunctionDeclaration":
1114
+ return findJSDocComment(
1115
+ looksLikeExport(parent) ? parent : node,
1116
+ sourceCode
1117
+ );
1118
+ case "ClassExpression":
1119
+ return findJSDocComment(parent.parent, sourceCode);
1120
+ case "ArrowFunctionExpression":
1121
+ case "FunctionExpression":
1122
+ if (parent.type !== "CallExpression" && parent.type !== "NewExpression") {
1123
+ while (!sourceCode.getCommentsBefore(parent).length && !/Function/u.test(parent.type) && parent.type !== "MethodDefinition" && parent.type !== "Property") {
1124
+ parent = parent.parent;
1125
+ if (!parent) {
1126
+ break;
1127
+ }
1128
+ }
1129
+ if (parent && parent.type !== "FunctionDeclaration" && parent.type !== "Program") {
1130
+ return findJSDocComment(parent, sourceCode);
1131
+ }
1132
+ }
1133
+ return findJSDocComment(node, sourceCode);
1134
+ default:
1135
+ return null;
1136
+ }
1137
+ }
1138
+ });
1139
+ Object.freeze(compatSourceCode);
1140
+ }
1141
+ let currentNode = compatSourceCode.ast;
1142
+ const compatContext = Object.assign(Object.create(context), {
1143
+ parserServices: compatSourceCode.parserServices,
1227
1144
  /*
1228
1145
  * The following methods rely on the current node in the traversal,
1229
1146
  * so we need to add them manually.
1230
1147
  */
1231
1148
  getScope() {
1232
- return sourceCode.getScope(currentNode);
1149
+ return compatSourceCode.getScope(currentNode);
1233
1150
  },
1234
1151
  getAncestors() {
1235
- return sourceCode.getAncestors(currentNode);
1152
+ return compatSourceCode.getAncestors(currentNode);
1236
1153
  },
1237
1154
  markVariableAsUsed(variable) {
1238
- sourceCode.markVariableAsUsed(variable, currentNode);
1155
+ compatSourceCode.markVariableAsUsed(variable, currentNode);
1239
1156
  }
1240
1157
  });
1158
+ if (eslintVersion >= 10) {
1159
+ Object.assign(compatContext, {
1160
+ parserOptions: compatContext.languageOptions.parserOptions,
1161
+ getCwd() {
1162
+ return compatContext.cwd;
1163
+ },
1164
+ getFilename() {
1165
+ return compatContext.filename;
1166
+ },
1167
+ getPhysicalFilename() {
1168
+ return compatContext.physicalFilename;
1169
+ },
1170
+ getSourceCode() {
1171
+ return compatSourceCode;
1172
+ }
1173
+ });
1174
+ Object.defineProperty(compatContext, "sourceCode", {
1175
+ enumerable: true,
1176
+ value: compatSourceCode
1177
+ });
1178
+ }
1241
1179
  for (const [
1242
1180
  contextMethodName,
1243
1181
  sourceCodeMethodName
1244
1182
  ] of removedMethodNames) {
1245
- newContext[contextMethodName] = sourceCode[sourceCodeMethodName].bind(sourceCode);
1183
+ compatContext[contextMethodName] = compatSourceCode[sourceCodeMethodName].bind(compatSourceCode);
1246
1184
  }
1247
- Object.freeze(newContext);
1248
- const visitor = originalCreate(newContext);
1185
+ Object.freeze(compatContext);
1186
+ const visitor = originalCreate(compatContext);
1249
1187
  for (const [methodName, method] of Object.entries(visitor)) {
1250
1188
  if (methodName.startsWith("on")) {
1251
1189
  visitor[methodName] = (...args) => {
@@ -1312,13 +1250,14 @@ function convertIgnorePatternToMinimatch(pattern) {
1312
1250
  const matchEverywherePrefix = firstIndexOfSlash < 0 || firstIndexOfSlash === patternToTest.length - 1 ? "**/" : "";
1313
1251
  const patternWithoutLeadingSlash = firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest;
1314
1252
  const escapedPatternWithoutLeadingSlash = patternWithoutLeadingSlash.replaceAll(
1253
+ // eslint-disable-next-line regexp/no-empty-lookarounds-assertion -- False positive
1315
1254
  /(?=((?:\\.|[^{(])*))\1([{(])/guy,
1316
1255
  "$1\\$2"
1317
1256
  );
1318
1257
  const matchInsideSuffix = patternToTest.endsWith("/**") ? "/*" : "";
1319
1258
  return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`;
1320
1259
  }
1321
- function includeIgnoreFile(ignoreFilePath) {
1260
+ function includeIgnoreFile(ignoreFilePath, name) {
1322
1261
  if (!path.isAbsolute(ignoreFilePath)) {
1323
1262
  throw new Error("The ignore file location must be an absolute path.");
1324
1263
  }
@@ -1334,7 +1273,6 @@ function includeIgnoreFile(ignoreFilePath) {
1334
1273
  async function reactConfig() {
1335
1274
  const [reactPlugin, reactHooksPlugin] = await Promise.all([
1336
1275
  interopDefault(import('eslint-plugin-react')),
1337
- // @ts-expect-error missing types
1338
1276
  interopDefault(import('eslint-plugin-react-hooks'))
1339
1277
  ]);
1340
1278
  return [
@@ -1597,8 +1535,8 @@ async function wondermarin(options) {
1597
1535
  });
1598
1536
  const projectRoot = findProjectRoot();
1599
1537
  const configs = await Promise.all([
1600
- baseConfig(projectRoot),
1601
- options.javascript ? javascriptConfig() : [],
1538
+ Promise.resolve(baseConfig(projectRoot)),
1539
+ Promise.resolve(options.javascript ? javascriptConfig() : []),
1602
1540
  options.typescript ? typescriptConfig(projectRoot) : [],
1603
1541
  options.stylistic ? stylisticConfig() : [],
1604
1542
  options.json ? jsonConfig() : [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wondermarin/eslint-config",
3
- "version": "2.4.1",
3
+ "version": "2.5.0",
4
4
  "description": "Personal ESLint config.",
5
5
  "homepage": "https://github.com/Wondermarin/eslint-config#readme",
6
6
  "repository": {
@@ -28,37 +28,36 @@
28
28
  "build": "tsup"
29
29
  },
30
30
  "dependencies": {
31
- "@stylistic/eslint-plugin": "^2.10.1",
32
- "eslint-config-prettier": "^9.1.0",
31
+ "eslint-config-prettier": "^9.1.2",
33
32
  "eslint-plugin-package-json": "^0.15.6",
34
33
  "eslint-plugin-perfectionist": "^3.9.1",
35
- "eslint-plugin-prettier": "^5.2.1",
36
- "globals": "^15.12.0",
37
- "jsonc-eslint-parser": "^2.4.0"
34
+ "eslint-plugin-prettier": "^5.5.4",
35
+ "globals": "^15.15.0",
36
+ "jsonc-eslint-parser": "^2.4.2"
38
37
  },
39
38
  "devDependencies": {
40
- "@eslint/compat": "^1.2.3",
39
+ "@eslint/compat": "^2.0.0",
41
40
  "@types/eslint": "^9.6.1",
42
41
  "@types/eslint-config-prettier": "^6.11.3",
43
- "@types/node": "^22.9.0",
44
- "@typescript-eslint/eslint-plugin": "^8.14.0",
45
- "@typescript-eslint/parser": "^8.14.0",
42
+ "@types/node": "^25.0.3",
43
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
44
+ "@typescript-eslint/parser": "^8.51.0",
46
45
  "@wondermarin/prettier-config": "^1.0.0",
47
46
  "defu": "^6.1.4",
48
- "eslint": "^9.14.0",
49
- "eslint-plugin-react": "^7.37.2",
50
- "eslint-plugin-react-hooks": "^5.0.0",
51
- "jiti": "^2.4.0",
52
- "prettier": "^3.3.3",
53
- "tsup": "^8.3.5",
54
- "typescript": "^5.6.3"
47
+ "eslint": "^9.39.2",
48
+ "eslint-plugin-react": "^7.37.5",
49
+ "eslint-plugin-react-hooks": "^7.0.1",
50
+ "jiti": "^2.6.1",
51
+ "prettier": "^3.7.4",
52
+ "tsup": "^8.5.1",
53
+ "typescript": "^5.9.3"
55
54
  },
56
55
  "peerDependencies": {
57
56
  "@typescript-eslint/eslint-plugin": "^8.14",
58
57
  "@typescript-eslint/parser": "^8.14",
59
58
  "eslint": "^9.14",
60
59
  "eslint-plugin-react": "^7.37",
61
- "eslint-plugin-react-hooks": "^5"
60
+ "eslint-plugin-react-hooks": "^5 || ^6.1 || ^7"
62
61
  },
63
62
  "peerDependenciesMeta": {
64
63
  "@typescript-eslint/eslint-plugin": {