@luxass/eslint-config 6.0.3 → 7.0.0-beta.1

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.mjs CHANGED
@@ -1,7 +1,10 @@
1
1
  import { FlatConfigComposer } from "eslint-flat-config-utils";
2
- import { isPackageExists } from "local-pkg";
3
2
  import process from "node:process";
3
+ import fs from "node:fs/promises";
4
4
  import { fileURLToPath } from "node:url";
5
+ import fs$1 from "node:fs";
6
+ import path from "node:path";
7
+ import { isPackageExists } from "local-pkg";
5
8
  import createCommand from "eslint-plugin-command/config";
6
9
  import eslintCommentsPlugin from "@eslint-community/eslint-plugin-eslint-comments";
7
10
  import pluginAntfu from "eslint-plugin-antfu";
@@ -14,6 +17,40 @@ import pluginPerfectionist from "eslint-plugin-perfectionist";
14
17
  import { configs } from "eslint-plugin-regexp";
15
18
  import pluginUnicorn from "eslint-plugin-unicorn";
16
19
 
20
+ //#region node_modules/.pnpm/find-up-simple@1.0.1/node_modules/find-up-simple/index.js
21
+ const toPath = (urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
22
+ async function findUp(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
23
+ let directory = path.resolve(toPath(cwd) ?? "");
24
+ const { root } = path.parse(directory);
25
+ stopAt = path.resolve(directory, toPath(stopAt ?? root));
26
+ const isAbsoluteName = path.isAbsolute(name);
27
+ while (directory) {
28
+ const filePath = isAbsoluteName ? name : path.join(directory, name);
29
+ try {
30
+ const stats = await fs.stat(filePath);
31
+ if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) return filePath;
32
+ } catch {}
33
+ if (directory === stopAt || directory === root) break;
34
+ directory = path.dirname(directory);
35
+ }
36
+ }
37
+ function findUpSync(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
38
+ let directory = path.resolve(toPath(cwd) ?? "");
39
+ const { root } = path.parse(directory);
40
+ stopAt = path.resolve(directory, toPath(stopAt) ?? root);
41
+ const isAbsoluteName = path.isAbsolute(name);
42
+ while (directory) {
43
+ const filePath = isAbsoluteName ? name : path.join(directory, name);
44
+ try {
45
+ const stats = fs$1.statSync(filePath, { throwIfNoEntry: false });
46
+ if (type === "file" && stats?.isFile() || type === "directory" && stats?.isDirectory()) return filePath;
47
+ } catch {}
48
+ if (directory === stopAt || directory === root) break;
49
+ directory = path.dirname(directory);
50
+ }
51
+ }
52
+
53
+ //#endregion
17
54
  //#region src/globs.ts
18
55
  const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
19
56
  const GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
@@ -1066,10 +1103,10 @@ async function perfectionist() {
1066
1103
  groups: [
1067
1104
  "type",
1068
1105
  [
1069
- "parent-type",
1070
- "sibling-type",
1071
- "index-type",
1072
- "internal-type"
1106
+ "type-parent",
1107
+ "type-sibling",
1108
+ "type-index",
1109
+ "type-internal"
1073
1110
  ],
1074
1111
  "builtin",
1075
1112
  "external",
@@ -1080,7 +1117,6 @@ async function perfectionist() {
1080
1117
  "index"
1081
1118
  ],
1082
1119
  "side-effect",
1083
- "object",
1084
1120
  "unknown"
1085
1121
  ],
1086
1122
  newlinesBetween: "ignore",
@@ -1101,32 +1137,130 @@ async function perfectionist() {
1101
1137
 
1102
1138
  //#endregion
1103
1139
  //#region src/configs/pnpm.ts
1104
- async function pnpm() {
1105
- const [pluginPnpm, yamlParser, jsoncParser] = await Promise.all([
1140
+ async function detectCatalogUsage() {
1141
+ const workspaceFile = await findUp("pnpm-workspace.yaml");
1142
+ if (!workspaceFile) return false;
1143
+ const yaml$1 = await fs.readFile(workspaceFile, "utf-8");
1144
+ return yaml$1.includes("catalog:") || yaml$1.includes("catalogs:");
1145
+ }
1146
+ async function pnpm(options) {
1147
+ const [pluginPnpm, pluginYaml, yamlParser, jsoncParser] = await Promise.all([
1106
1148
  interop(import("eslint-plugin-pnpm")),
1149
+ interop(import("eslint-plugin-yml")),
1107
1150
  interop(import("yaml-eslint-parser")),
1108
1151
  interop(import("jsonc-eslint-parser"))
1109
1152
  ]);
1110
- return [{
1153
+ const { catalogs = await detectCatalogUsage(), isInEditor = false, json = true, sort = true, yaml: yaml$1 = true } = options;
1154
+ const configs$1 = [];
1155
+ if (json) configs$1.push({
1111
1156
  files: ["package.json", "**/package.json"],
1112
1157
  languageOptions: { parser: jsoncParser },
1113
1158
  name: "luxass/pnpm/package-json",
1114
1159
  plugins: { pnpm: pluginPnpm },
1115
1160
  rules: {
1116
- "pnpm/json-enforce-catalog": "error",
1117
- "pnpm/json-prefer-workspace-settings": "error",
1118
- "pnpm/json-valid-catalog": "error"
1119
- }
1120
- }, {
1121
- files: ["pnpm-workspace.yaml"],
1122
- languageOptions: { parser: yamlParser },
1123
- name: "luxass/pnpm/pnpm-workspace-yaml",
1124
- plugins: { pnpm: pluginPnpm },
1125
- rules: {
1126
- "pnpm/yaml-no-duplicate-catalog-item": "error",
1127
- "pnpm/yaml-no-unused-catalog-item": "error"
1161
+ ...catalogs ? { "pnpm/json-enforce-catalog": ["error", {
1162
+ autofix: !isInEditor,
1163
+ ignores: ["@types/vscode"]
1164
+ }] } : {},
1165
+ "pnpm/json-prefer-workspace-settings": ["error", { autofix: !isInEditor }],
1166
+ "pnpm/json-valid-catalog": ["error", { autofix: !isInEditor }]
1128
1167
  }
1129
- }];
1168
+ });
1169
+ if (yaml$1) {
1170
+ configs$1.push({
1171
+ files: ["pnpm-workspace.yaml"],
1172
+ languageOptions: { parser: yamlParser },
1173
+ name: "luxass/pnpm/pnpm-workspace-yaml",
1174
+ plugins: { pnpm: pluginPnpm },
1175
+ rules: {
1176
+ "pnpm/yaml-enforce-settings": ["error", { settings: {
1177
+ shellEmulator: true,
1178
+ trustPolicy: "no-downgrade"
1179
+ } }],
1180
+ "pnpm/yaml-no-duplicate-catalog-item": "error",
1181
+ "pnpm/yaml-no-unused-catalog-item": "error"
1182
+ }
1183
+ });
1184
+ if (sort) configs$1.push({
1185
+ files: ["pnpm-workspace.yaml"],
1186
+ languageOptions: { parser: yamlParser },
1187
+ name: "luxass/pnpm/pnpm-workspace-yaml-sort",
1188
+ plugins: { yaml: pluginYaml },
1189
+ rules: { "yaml/sort-keys": [
1190
+ "error",
1191
+ {
1192
+ order: [
1193
+ ...[
1194
+ "cacheDir",
1195
+ "catalogMode",
1196
+ "cleanupUnusedCatalogs",
1197
+ "dedupeDirectDeps",
1198
+ "deployAllFiles",
1199
+ "enablePrePostScripts",
1200
+ "engineStrict",
1201
+ "extendNodePath",
1202
+ "hoist",
1203
+ "hoistPattern",
1204
+ "hoistWorkspacePackages",
1205
+ "ignoreCompatibilityDb",
1206
+ "ignoreDepScripts",
1207
+ "ignoreScripts",
1208
+ "ignoreWorkspaceRootCheck",
1209
+ "managePackageManagerVersions",
1210
+ "minimumReleaseAge",
1211
+ "minimumReleaseAgeExclude",
1212
+ "modulesDir",
1213
+ "nodeLinker",
1214
+ "nodeVersion",
1215
+ "optimisticRepeatInstall",
1216
+ "packageManagerStrict",
1217
+ "packageManagerStrictVersion",
1218
+ "preferSymlinkedExecutables",
1219
+ "preferWorkspacePackages",
1220
+ "publicHoistPattern",
1221
+ "registrySupportsTimeField",
1222
+ "requiredScripts",
1223
+ "resolutionMode",
1224
+ "savePrefix",
1225
+ "scriptShell",
1226
+ "shamefullyHoist",
1227
+ "shellEmulator",
1228
+ "stateDir",
1229
+ "supportedArchitectures",
1230
+ "symlink",
1231
+ "tag",
1232
+ "trustPolicy",
1233
+ "trustPolicyExclude",
1234
+ "updateNotifier"
1235
+ ],
1236
+ "packages",
1237
+ "overrides",
1238
+ "patchedDependencies",
1239
+ "catalog",
1240
+ "catalogs",
1241
+ ...[
1242
+ "allowedDeprecatedVersions",
1243
+ "allowNonAppliedPatches",
1244
+ "configDependencies",
1245
+ "ignoredBuiltDependencies",
1246
+ "ignoredOptionalDependencies",
1247
+ "neverBuiltDependencies",
1248
+ "onlyBuiltDependencies",
1249
+ "onlyBuiltDependenciesFile",
1250
+ "packageExtensions",
1251
+ "peerDependencyRules"
1252
+ ]
1253
+ ],
1254
+ pathPattern: "^$"
1255
+ },
1256
+ {
1257
+ order: { type: "asc" },
1258
+ pathPattern: ".*"
1259
+ }
1260
+ ] }
1261
+ });
1262
+ }
1263
+ return configs$1;
1130
1264
  }
1131
1265
 
1132
1266
  //#endregion
@@ -1145,13 +1279,14 @@ const ReactRouterPackages = [
1145
1279
  "@react-router/dev"
1146
1280
  ];
1147
1281
  const NextJsPackages = ["next"];
1282
+ const ReactCompilerPackages = ["babel-plugin-react-compiler"];
1148
1283
  async function react(options = {}) {
1149
1284
  const { files = [
1150
1285
  GLOB_JS,
1151
1286
  GLOB_JSX,
1152
1287
  GLOB_TS,
1153
1288
  GLOB_TSX
1154
- ], filesTypeAware = [GLOB_TS, GLOB_TSX], ignoresTypeAware = [`${GLOB_MARKDOWN}/**`, GLOB_ASTRO_TS], overrides = {}, tsconfigPath } = options;
1289
+ ], filesTypeAware = [GLOB_TS, GLOB_TSX], ignoresTypeAware = [`${GLOB_MARKDOWN}/**`, GLOB_ASTRO_TS], overrides = {}, reactCompiler = ReactCompilerPackages.some((i) => isPackageExists(i)), tsconfigPath } = options;
1155
1290
  await ensure([
1156
1291
  "@eslint-react/eslint-plugin",
1157
1292
  "eslint-plugin-react-hooks",
@@ -1195,52 +1330,19 @@ async function react(options = {}) {
1195
1330
  "react-dom/no-find-dom-node": "error",
1196
1331
  "react-dom/no-flush-sync": "error",
1197
1332
  "react-dom/no-hydrate": "error",
1198
- "react-dom/no-missing-button-type": "warn",
1199
- "react-dom/no-missing-iframe-sandbox": "warn",
1200
1333
  "react-dom/no-namespace": "error",
1201
1334
  "react-dom/no-render": "error",
1202
1335
  "react-dom/no-render-return-value": "error",
1203
1336
  "react-dom/no-script-url": "warn",
1204
1337
  "react-dom/no-unsafe-iframe-sandbox": "warn",
1205
- "react-dom/no-unsafe-target-blank": "warn",
1206
1338
  "react-dom/no-use-form-state": "error",
1207
1339
  "react-dom/no-void-elements-with-children": "error",
1208
- "react-hooks-extra/no-direct-set-state-in-use-effect": "warn",
1209
- ...pluginReactHooks.configs.recommended.rules,
1210
- "react-refresh/only-export-components": ["warn", {
1211
- allowConstantExport: isAllowConstantExport,
1212
- allowExportNames: [...isUsingNext ? [
1213
- "dynamic",
1214
- "dynamicParams",
1215
- "revalidate",
1216
- "fetchCache",
1217
- "runtime",
1218
- "preferredRegion",
1219
- "maxDuration",
1220
- "config",
1221
- "generateStaticParams",
1222
- "metadata",
1223
- "generateMetadata",
1224
- "viewport",
1225
- "generateViewport"
1226
- ] : [], ...isUsingRemix || isUsingReactRouter ? [
1227
- "meta",
1228
- "links",
1229
- "headers",
1230
- "loader",
1231
- "action",
1232
- "clientLoader",
1233
- "clientAction",
1234
- "handle",
1235
- "shouldRevalidate"
1236
- ] : []]
1237
- }],
1238
- "react-web-api/no-leaked-event-listener": "warn",
1239
- "react-web-api/no-leaked-interval": "warn",
1240
- "react-web-api/no-leaked-resize-observer": "warn",
1241
- "react-web-api/no-leaked-timeout": "warn",
1340
+ "react-hooks/exhaustive-deps": "warn",
1341
+ "react-hooks/rules-of-hooks": "error",
1342
+ "react/jsx-key-before-spread": "warn",
1242
1343
  "react/jsx-no-comment-textnodes": "warn",
1243
1344
  "react/jsx-no-duplicate-props": "warn",
1345
+ "react/jsx-uses-react": "warn",
1244
1346
  "react/jsx-uses-vars": "warn",
1245
1347
  "react/no-access-state-in-setstate": "error",
1246
1348
  "react/no-array-index-key": "warn",
@@ -1257,11 +1359,12 @@ async function react(options = {}) {
1257
1359
  "react/no-create-ref": "error",
1258
1360
  "react/no-default-props": "error",
1259
1361
  "react/no-direct-mutation-state": "error",
1260
- "react/no-duplicate-key": "warn",
1362
+ "react/no-duplicate-key": "error",
1261
1363
  "react/no-forward-ref": "warn",
1262
1364
  "react/no-implicit-key": "warn",
1263
1365
  "react/no-missing-key": "error",
1264
1366
  "react/no-nested-component-definitions": "error",
1367
+ "react/no-nested-lazy-component-declarations": "error",
1265
1368
  "react/no-prop-types": "error",
1266
1369
  "react/no-redundant-should-component-update": "error",
1267
1370
  "react/no-set-state-in-component-did-mount": "warn",
@@ -1272,13 +1375,60 @@ async function react(options = {}) {
1272
1375
  "react/no-unsafe-component-will-mount": "warn",
1273
1376
  "react/no-unsafe-component-will-receive-props": "warn",
1274
1377
  "react/no-unsafe-component-will-update": "warn",
1275
- "react/no-unstable-context-value": "warn",
1276
- "react/no-unstable-default-props": "warn",
1277
- "react/no-unused-class-component-members": "warn",
1278
- "react/no-unused-state": "warn",
1279
1378
  "react/no-use-context": "warn",
1280
1379
  "react/no-useless-forward-ref": "warn",
1380
+ "react/prefer-namespace-import": "error",
1281
1381
  "react/prefer-use-state-lazy-initialization": "warn",
1382
+ ...reactCompiler ? {
1383
+ "react-hooks/component-hook-factories": "error",
1384
+ "react-hooks/config": "error",
1385
+ "react-hooks/error-boundaries": "error",
1386
+ "react-hooks/gating": "error",
1387
+ "react-hooks/globals": "error",
1388
+ "react-hooks/immutability": "error",
1389
+ "react-hooks/incompatible-library": "warn",
1390
+ "react-hooks/preserve-manual-memoization": "error",
1391
+ "react-hooks/purity": "error",
1392
+ "react-hooks/refs": "error",
1393
+ "react-hooks/set-state-in-effect": "error",
1394
+ "react-hooks/set-state-in-render": "error",
1395
+ "react-hooks/static-components": "error",
1396
+ "react-hooks/unsupported-syntax": "warn",
1397
+ "react-hooks/use-memo": "error"
1398
+ } : {},
1399
+ "react-hooks-extra/no-direct-set-state-in-use-effect": "warn",
1400
+ "react-refresh/only-export-components": ["warn", {
1401
+ allowConstantExport: isAllowConstantExport,
1402
+ allowExportNames: [...isUsingNext ? [
1403
+ "dynamic",
1404
+ "dynamicParams",
1405
+ "revalidate",
1406
+ "fetchCache",
1407
+ "runtime",
1408
+ "preferredRegion",
1409
+ "maxDuration",
1410
+ "config",
1411
+ "generateStaticParams",
1412
+ "metadata",
1413
+ "generateMetadata",
1414
+ "viewport",
1415
+ "generateViewport"
1416
+ ] : [], ...isUsingRemix || isUsingReactRouter ? [
1417
+ "meta",
1418
+ "links",
1419
+ "headers",
1420
+ "loader",
1421
+ "action",
1422
+ "clientLoader",
1423
+ "clientAction",
1424
+ "handle",
1425
+ "shouldRevalidate"
1426
+ ] : []]
1427
+ }],
1428
+ "react-web-api/no-leaked-event-listener": "warn",
1429
+ "react-web-api/no-leaked-interval": "warn",
1430
+ "react-web-api/no-leaked-resize-observer": "warn",
1431
+ "react-web-api/no-leaked-timeout": "warn",
1282
1432
  ...overrides
1283
1433
  }
1284
1434
  },
@@ -1783,7 +1933,7 @@ async function typescript(options = {}) {
1783
1933
  }] : [],
1784
1934
  ...erasableOnly ? [{
1785
1935
  name: "luxas/typescript/erasable-syntax-only",
1786
- plugins: { "erasable-syntax-only": await interop(import("./lib-2_zHyZqD.mjs")) },
1936
+ plugins: { "erasable-syntax-only": await interop(import("./lib-BXbP6VXm.mjs")) },
1787
1937
  rules: {
1788
1938
  "erasable-syntax-only/enums": "error",
1789
1939
  "erasable-syntax-only/import-aliases": "error",
@@ -2128,7 +2278,7 @@ const defaultPluginRenaming = {
2128
2278
  * The merged ESLint configurations.
2129
2279
  */
2130
2280
  function luxass(options = {}, ...userConfigs) {
2131
- const { astro: enableAstro = false, autoRenamePlugins = true, exts = [], gitignore: enableGitignore = true, imports: enableImports = true, jsx: enableJsx = true, pnpm: enableCatalogs = false, react: enableReact = false, regexp: enableRegexp = true, tailwindcss: enableTailwindCSS = false, type: projectType = "app", typescript: enableTypeScript = isPackageExists("typescript"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => isPackageExists(i)) } = options;
2281
+ const { astro: enableAstro = false, autoRenamePlugins = true, exts = [], gitignore: enableGitignore = true, ignores: userIgnores = [], imports: enableImports = true, jsdoc: enableJsdoc = true, jsx: enableJsx = true, node: enableNode = true, pnpm: enableCatalogs = !!findUpSync("pnpm-workspace.yaml"), react: enableReact = false, regexp: enableRegexp = true, tailwindcss: enableTailwindCSS = false, type: projectType = "app", typescript: enableTypeScript = isPackageExists("typescript"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => isPackageExists(i)) } = options;
2132
2282
  let isInEditor = options.isInEditor;
2133
2283
  if (isInEditor == null) {
2134
2284
  isInEditor = isInEditorEnv();
@@ -2147,14 +2297,15 @@ function luxass(options = {}, ...userConfigs) {
2147
2297
  })]));
2148
2298
  const typescriptOptions = resolveSubOptions(options, "typescript");
2149
2299
  const tsconfigPath = "tsconfigPath" in typescriptOptions ? typescriptOptions.tsconfigPath : void 0;
2150
- configs$1.push(ignores(), javascript({
2300
+ configs$1.push(ignores(userIgnores), javascript({
2151
2301
  isInEditor,
2152
2302
  overrides: getOverrides(options, "javascript")
2153
- }), comments());
2154
- configs$1.push(node(), jsdoc({ stylistic: stylisticOptions }), imports({ stylistic: stylisticOptions }), command(), perfectionist());
2155
- if (enableImports) configs$1.push(imports(enableImports === true ? { stylistic: stylisticOptions } : {
2303
+ }), comments(), command(), perfectionist());
2304
+ if (enableNode) configs$1.push(node());
2305
+ if (enableJsdoc) configs$1.push(jsdoc({ stylistic: stylisticOptions }));
2306
+ if (enableImports) configs$1.push(imports({
2156
2307
  stylistic: stylisticOptions,
2157
- ...enableImports
2308
+ ...resolveSubOptions(options, "imports")
2158
2309
  }));
2159
2310
  if (enableUnicorn) configs$1.push(unicorn(enableUnicorn === true ? {} : enableUnicorn));
2160
2311
  if (enableVue) exts.push("vue");
@@ -2178,6 +2329,7 @@ function luxass(options = {}, ...userConfigs) {
2178
2329
  overrides: getOverrides(options, "test")
2179
2330
  }));
2180
2331
  if (enableReact) configs$1.push(react({
2332
+ ...typescriptOptions,
2181
2333
  ...resolveSubOptions(options, "react"),
2182
2334
  overrides: getOverrides(options, "react"),
2183
2335
  tsconfigPath
@@ -2204,7 +2356,12 @@ function luxass(options = {}, ...userConfigs) {
2204
2356
  overrides: getOverrides(options, "jsonc"),
2205
2357
  stylistic: stylisticOptions
2206
2358
  }), sortPackageJson(), sortTsconfig());
2207
- if (enableCatalogs) configs$1.push(pnpm());
2359
+ if (enableCatalogs) configs$1.push(pnpm({
2360
+ isInEditor,
2361
+ json: options.jsonc !== false,
2362
+ yaml: options.yaml !== false,
2363
+ ...resolveSubOptions(options, "pnpm")
2364
+ }));
2208
2365
  if (options.yaml ?? true) configs$1.push(yaml({
2209
2366
  overrides: getOverrides(options, "yaml"),
2210
2367
  stylistic: stylisticOptions