@luxass/eslint-config 4.12.1 → 4.13.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
@@ -237,6 +237,7 @@ async function astro(options = {}) {
237
237
  },
238
238
  processor: "astro/client-side-ts",
239
239
  rules: {
240
+ // use recommended rules
240
241
  "astro/missing-client-only-directive-value": "error",
241
242
  "astro/no-conflict-set-directives": "error",
242
243
  "astro/no-deprecated-astro-canonicalurl": "error",
@@ -245,12 +246,11 @@ async function astro(options = {}) {
245
246
  "astro/no-deprecated-getentrybyslug": "error",
246
247
  "astro/no-set-html-directive": "off",
247
248
  "astro/no-unused-define-vars-in-style": "error",
248
- "astro/semi": "error",
249
+ "astro/semi": "off",
249
250
  "astro/valid-compile": "error",
250
251
  ...stylistic2 ? {
251
252
  "style/indent": "off",
252
253
  "style/jsx-closing-tag-location": "off",
253
- "style/jsx-indent": "off",
254
254
  "style/jsx-one-expression-per-line": "off",
255
255
  "style/no-multiple-empty-lines": "off"
256
256
  } : {},
@@ -276,9 +276,8 @@ async function comments() {
276
276
  "eslint-comments/no-duplicate-disable": "error",
277
277
  // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-unlimited-disable.md
278
278
  "eslint-comments/no-unlimited-disable": "error",
279
- // Deprecated in favor of official reportUnusedDisableDirectives
280
- // https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/133
281
- "eslint-comments/no-unused-enable": "off"
279
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments/blob/main/docs/rules/no-unused-enable.md
280
+ "eslint-comments/no-unused-enable": "error"
282
281
  }
283
282
  }
284
283
  ];
@@ -288,17 +287,19 @@ async function comments() {
288
287
  async function disables() {
289
288
  return [
290
289
  {
291
- files: [`scripts/${GLOB_SRC}`],
290
+ files: [`**/scripts/${GLOB_SRC}`],
292
291
  name: "luxass/disables/scripts",
293
292
  rules: {
293
+ "antfu/no-top-level-await": "off",
294
294
  "no-console": "off",
295
295
  "ts/explicit-function-return-type": "off"
296
296
  }
297
297
  },
298
298
  {
299
- files: [`cli/${GLOB_SRC}`, `cli.${GLOB_SRC_EXT}`],
299
+ files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
300
300
  name: "luxass/disables/cli",
301
301
  rules: {
302
+ "antfu/no-top-level-await": "off",
302
303
  "no-console": "off"
303
304
  }
304
305
  },
@@ -320,13 +321,6 @@ async function disables() {
320
321
  "unused-imports/no-unused-vars": "off"
321
322
  }
322
323
  },
323
- {
324
- files: ["**/*.{test,spec}.([tj])s?(x)"],
325
- name: "luxass/disables/test",
326
- rules: {
327
- "no-unused-expressions": "off"
328
- }
329
- },
330
324
  {
331
325
  files: ["**/*.js", "**/*.cjs"],
332
326
  name: "luxass/disables/cjs",
@@ -341,6 +335,15 @@ async function disables() {
341
335
  // GitHub Actions supports empty values to enable features
342
336
  "yaml/no-empty-mapping-value": "off"
343
337
  }
338
+ },
339
+ {
340
+ files: [`**/*.config.${GLOB_SRC_EXT}`, `**/*.config.*.${GLOB_SRC_EXT}`],
341
+ name: "luxass/disables/config-files",
342
+ rules: {
343
+ "antfu/no-top-level-await": "off",
344
+ "no-console": "off",
345
+ "ts/explicit-function-return-type": "off"
346
+ }
344
347
  }
345
348
  ];
346
349
  }
@@ -395,6 +398,16 @@ async function stylistic(options = {}) {
395
398
  }
396
399
 
397
400
  // src/configs/formatters.ts
401
+ function mergePrettierOptions(options, overrides = {}) {
402
+ return {
403
+ ...options,
404
+ ...overrides,
405
+ plugins: [
406
+ ...overrides.plugins || [],
407
+ ...options.plugins || []
408
+ ]
409
+ };
410
+ }
398
411
  async function formatters(options = {}, stylistic2 = {}) {
399
412
  if (options === true) {
400
413
  options = {
@@ -457,10 +470,9 @@ async function formatters(options = {}, stylistic2 = {}) {
457
470
  rules: {
458
471
  "format/prettier": [
459
472
  "error",
460
- {
461
- ...prettierOptions,
473
+ mergePrettierOptions(prettierOptions, {
462
474
  parser: "css"
463
- }
475
+ })
464
476
  ]
465
477
  }
466
478
  },
@@ -473,10 +485,9 @@ async function formatters(options = {}, stylistic2 = {}) {
473
485
  rules: {
474
486
  "format/prettier": [
475
487
  "error",
476
- {
477
- ...prettierOptions,
488
+ mergePrettierOptions(prettierOptions, {
478
489
  parser: "scss"
479
- }
490
+ })
480
491
  ]
481
492
  }
482
493
  },
@@ -489,10 +500,9 @@ async function formatters(options = {}, stylistic2 = {}) {
489
500
  rules: {
490
501
  "format/prettier": [
491
502
  "error",
492
- {
493
- ...prettierOptions,
503
+ mergePrettierOptions(prettierOptions, {
494
504
  parser: "less"
495
- }
505
+ })
496
506
  ]
497
507
  }
498
508
  }
@@ -508,10 +518,9 @@ async function formatters(options = {}, stylistic2 = {}) {
508
518
  rules: {
509
519
  "format/prettier": [
510
520
  "error",
511
- {
512
- ...prettierOptions,
521
+ mergePrettierOptions(prettierOptions, {
513
522
  parser: "html"
514
- }
523
+ })
515
524
  ]
516
525
  }
517
526
  });
@@ -527,11 +536,10 @@ async function formatters(options = {}, stylistic2 = {}) {
527
536
  rules: {
528
537
  [`format/${formater}`]: [
529
538
  "error",
530
- formater === "prettier" ? {
531
- ...prettierOptions,
539
+ formater === "prettier" ? mergePrettierOptions(prettierOptions, {
532
540
  embeddedLanguageFormatting: "off",
533
541
  parser: "markdown"
534
- } : {
542
+ }) : {
535
543
  ...dprintOptions,
536
544
  language: "markdown"
537
545
  }
@@ -549,13 +557,12 @@ async function formatters(options = {}, stylistic2 = {}) {
549
557
  rules: {
550
558
  "format/prettier": [
551
559
  "error",
552
- {
553
- ...prettierOptions,
560
+ mergePrettierOptions(prettierOptions, {
554
561
  parser: "astro",
555
562
  plugins: [
556
563
  "prettier-plugin-astro"
557
564
  ]
558
- }
565
+ })
559
566
  ]
560
567
  }
561
568
  });
@@ -570,10 +577,9 @@ async function formatters(options = {}, stylistic2 = {}) {
570
577
  rules: {
571
578
  "format/prettier": [
572
579
  "error",
573
- {
574
- ...prettierOptions,
580
+ mergePrettierOptions(prettierOptions, {
575
581
  parser: "graphql"
576
- }
582
+ })
577
583
  ]
578
584
  }
579
585
  });
@@ -672,6 +678,7 @@ async function javascript(options = {}) {
672
678
  "error",
673
679
  { enforceForClassMembers: true, setWithoutGet: true }
674
680
  ],
681
+ "antfu/no-top-level-await": "error",
675
682
  "array-callback-return": "error",
676
683
  "block-scoped-var": "error",
677
684
  "constructor-super": "error",
@@ -1068,6 +1075,7 @@ async function markdown(options = {}) {
1068
1075
  }
1069
1076
  },
1070
1077
  rules: {
1078
+ "antfu/no-top-level-await": "off",
1071
1079
  "import/newline-after-import": "off",
1072
1080
  "no-alert": "off",
1073
1081
  "no-console": "off",
@@ -1082,6 +1090,7 @@ async function markdown(options = {}) {
1082
1090
  "style/comma-dangle": "off",
1083
1091
  "style/eol-last": "off",
1084
1092
  "ts/consistent-type-imports": "off",
1093
+ "ts/explicit-function-return-type": "off",
1085
1094
  "ts/no-namespace": "off",
1086
1095
  "ts/no-redeclare": "off",
1087
1096
  "ts/no-require-imports": "off",
@@ -1166,34 +1175,41 @@ var RemixPackages = [
1166
1175
  "@remix-run/serve",
1167
1176
  "@remix-run/dev"
1168
1177
  ];
1178
+ var NextJsPackages = [
1179
+ "next"
1180
+ ];
1169
1181
  async function react(options = {}) {
1170
1182
  const {
1171
1183
  files = [GLOB_JS, GLOB_JSX, GLOB_TS, GLOB_TSX],
1172
- overrides = {}
1184
+ overrides = {},
1185
+ filesTypeAware = [GLOB_TS, GLOB_TSX],
1186
+ ignoresTypeAware = [
1187
+ `${GLOB_MARKDOWN}/**`,
1188
+ GLOB_ASTRO_TS
1189
+ ],
1190
+ tsconfigPath
1173
1191
  } = options;
1174
1192
  await ensure([
1175
1193
  "@eslint-react/eslint-plugin",
1176
1194
  "eslint-plugin-react-hooks",
1177
1195
  "eslint-plugin-react-refresh"
1178
1196
  ]);
1179
- const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1180
1197
  const isTypeAware = !!tsconfigPath;
1198
+ const typeAwareRules = {
1199
+ "react/no-leaked-conditional-rendering": "warn"
1200
+ };
1181
1201
  const [
1182
1202
  pluginReact,
1183
1203
  pluginReactHooks,
1184
- pluginReactRefresh,
1185
- parserTs
1204
+ pluginReactRefresh
1186
1205
  ] = await Promise.all([
1187
1206
  interop(import("@eslint-react/eslint-plugin")),
1188
1207
  interop(import("eslint-plugin-react-hooks")),
1189
- interop(import("eslint-plugin-react-refresh")),
1190
- interop(import("@typescript-eslint/parser"))
1208
+ interop(import("eslint-plugin-react-refresh"))
1191
1209
  ]);
1192
- const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
1193
- (i) => isPackageExists2(i)
1194
- );
1210
+ const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((i) => isPackageExists2(i));
1195
1211
  const isUsingRemix = RemixPackages.some((i) => isPackageExists2(i));
1196
- const isUsingNext = isPackageExists2("next");
1212
+ const isUsingNext = NextJsPackages.some((i) => isPackageExists2(i));
1197
1213
  const plugins = pluginReact.configs.all.plugins;
1198
1214
  return [
1199
1215
  {
@@ -1211,12 +1227,10 @@ async function react(options = {}) {
1211
1227
  name: "luxass/react/rules",
1212
1228
  files,
1213
1229
  languageOptions: {
1214
- parser: parserTs,
1215
1230
  parserOptions: {
1216
1231
  ecmaFeatures: {
1217
1232
  jsx: true
1218
- },
1219
- ...isTypeAware ? { project: tsconfigPath } : {}
1233
+ }
1220
1234
  },
1221
1235
  sourceType: "module"
1222
1236
  },
@@ -1243,6 +1257,13 @@ async function react(options = {}) {
1243
1257
  allowConstantExport: isAllowConstantExport,
1244
1258
  allowExportNames: [
1245
1259
  ...isUsingNext ? [
1260
+ "dynamic",
1261
+ "dynamicParams",
1262
+ "revalidate",
1263
+ "fetchCache",
1264
+ "runtime",
1265
+ "preferredRegion",
1266
+ "maxDuration",
1246
1267
  "config",
1247
1268
  "runtime",
1248
1269
  "generateStaticParams",
@@ -1298,13 +1319,18 @@ async function react(options = {}) {
1298
1319
  "react/prefer-destructuring-assignment": "warn",
1299
1320
  "react/prefer-shorthand-boolean": "warn",
1300
1321
  "react/prefer-shorthand-fragment": "warn",
1301
- ...isTypeAware ? {
1302
- "react/no-leaked-conditional-rendering": "warn"
1303
- } : {},
1304
1322
  // overrides
1305
1323
  ...overrides
1306
1324
  }
1307
- }
1325
+ },
1326
+ ...isTypeAware ? [{
1327
+ files: filesTypeAware,
1328
+ ignores: ignoresTypeAware,
1329
+ name: "antfu/react/type-aware-rules",
1330
+ rules: {
1331
+ ...typeAwareRules
1332
+ }
1333
+ }] : []
1308
1334
  ];
1309
1335
  }
1310
1336
 
@@ -1643,7 +1669,6 @@ async function test(options = {}) {
1643
1669
  name: "luxass/test/rules",
1644
1670
  files,
1645
1671
  rules: {
1646
- "node/prefer-global/process": "off",
1647
1672
  "test/consistent-test-it": [
1648
1673
  "error",
1649
1674
  { fn: "it", withinDescribe: "it" }
@@ -1653,7 +1678,13 @@ async function test(options = {}) {
1653
1678
  "test/no-focused-tests": isInEditor ? "off" : ["error", { fixable: true }],
1654
1679
  "test/prefer-hooks-in-order": "error",
1655
1680
  "test/prefer-lowercase-title": "error",
1656
- "ts/explicit-function-return-type": "off",
1681
+ // Disables
1682
+ ...{
1683
+ "antfu/no-top-level-await": "off",
1684
+ "no-unused-expressions": "off",
1685
+ "node/prefer-global/process": "off",
1686
+ "ts/explicit-function-return-type": "off"
1687
+ },
1657
1688
  ...overrides
1658
1689
  }
1659
1690
  }
@@ -1727,6 +1758,7 @@ async function typescript(options = {}) {
1727
1758
  exts = [],
1728
1759
  overrides = {},
1729
1760
  parserOptions = {},
1761
+ overridesTypeAware = {},
1730
1762
  type = "app"
1731
1763
  } = options ?? {};
1732
1764
  const files = options.files ?? [
@@ -1851,8 +1883,13 @@ async function typescript(options = {}) {
1851
1883
  "ts/no-invalid-this": "error",
1852
1884
  "ts/no-invalid-void-type": "off",
1853
1885
  "ts/no-non-null-assertion": "off",
1854
- "ts/no-redeclare": "error",
1886
+ "ts/no-redeclare": ["error", { builtinGlobals: false }],
1855
1887
  "ts/no-require-imports": "error",
1888
+ "ts/no-unused-expressions": ["error", {
1889
+ allowShortCircuit: true,
1890
+ allowTaggedTemplates: true,
1891
+ allowTernary: true
1892
+ }],
1856
1893
  "ts/no-unused-vars": "off",
1857
1894
  "ts/no-use-before-define": [
1858
1895
  "error",
@@ -1876,7 +1913,10 @@ async function typescript(options = {}) {
1876
1913
  files: filesTypeAware,
1877
1914
  ignores: ignoresTypeAware,
1878
1915
  name: "luxass/typescript/rules-type-aware",
1879
- rules: typeAwareRules
1916
+ rules: {
1917
+ ...typeAwareRules,
1918
+ ...overridesTypeAware
1919
+ }
1880
1920
  }] : []
1881
1921
  ];
1882
1922
  }
@@ -2060,7 +2100,9 @@ async function vue(options = {}) {
2060
2100
  ...pluginVue.configs["vue3-essential"].rules,
2061
2101
  ...pluginVue.configs["vue3-strongly-recommended"].rules,
2062
2102
  ...pluginVue.configs["vue3-recommended"].rules,
2103
+ "antfu/no-top-level-await": "off",
2063
2104
  "node/prefer-global/process": "off",
2105
+ "ts/explicit-function-return-type": "off",
2064
2106
  "vue/block-order": [
2065
2107
  "error",
2066
2108
  {
@@ -2221,10 +2263,7 @@ async function yaml(options = {}) {
2221
2263
  "yaml/indent": ["error", indent === "tab" ? 2 : indent],
2222
2264
  "yaml/key-spacing": "error",
2223
2265
  "yaml/no-tab-indent": "error",
2224
- "yaml/quotes": [
2225
- "error",
2226
- { avoidEscape: false, prefer: quotes }
2227
- ],
2266
+ "yaml/quotes": ["error", { avoidEscape: true, prefer: quotes === "backtick" ? "single" : quotes }],
2228
2267
  "yaml/spaced-comment": "error"
2229
2268
  } : {},
2230
2269
  ...overrides
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luxass/eslint-config",
3
- "version": "4.12.1",
3
+ "version": "4.13.0",
4
4
  "description": "ESLint config for @luxass",
5
5
  "type": "module",
6
6
  "author": {
@@ -8,7 +8,7 @@
8
8
  "email": "lucasnrgaard@gmail.com",
9
9
  "url": "https://luxass.dev"
10
10
  },
11
- "packageManager": "pnpm@9.10.0",
11
+ "packageManager": "pnpm@9.14.2",
12
12
  "license": "MIT",
13
13
  "repository": {
14
14
  "type": "git",
@@ -42,7 +42,7 @@
42
42
  "dev": "pnpm eslint-config-inspector --config eslint.config.mjs",
43
43
  "build:inspector": "pnpm build && pnpm eslint-config-inspector build",
44
44
  "test": "vitest --run",
45
- "typegen": "pnpx tsx ./scripts/typegen.ts",
45
+ "typegen": "tsx ./scripts/typegen.ts",
46
46
  "test:watch": "vitest",
47
47
  "lint": "eslint --flag unstable_ts_config .",
48
48
  "typecheck": "tsc --noEmit"
@@ -90,67 +90,67 @@
90
90
  },
91
91
  "dependencies": {
92
92
  "@antfu/install-pkg": "^0.4.1",
93
- "@clack/prompts": "^0.7.0",
94
- "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
95
- "@eslint/markdown": "^6.1.0",
96
- "@stylistic/eslint-plugin": "^2.8.0",
97
- "@typescript-eslint/eslint-plugin": "^8.5.0",
98
- "@typescript-eslint/parser": "^8.5.0",
99
- "@vitest/eslint-plugin": "^1.1.0",
93
+ "@clack/prompts": "^0.8.2",
94
+ "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
95
+ "@eslint/markdown": "^6.2.1",
96
+ "@stylistic/eslint-plugin": "^2.11.0",
97
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
98
+ "@typescript-eslint/parser": "^8.15.0",
99
+ "@vitest/eslint-plugin": "^1.1.10",
100
100
  "eslint-config-flat-gitignore": "^0.3.0",
101
101
  "eslint-flat-config-utils": "^0.4.0",
102
102
  "eslint-merge-processors": "^0.1.0",
103
- "eslint-plugin-antfu": "^2.6.0",
104
- "eslint-plugin-import-x": "^4.2.1",
105
- "eslint-plugin-jsdoc": "^50.2.2",
106
- "eslint-plugin-jsonc": "^2.16.0",
107
- "eslint-plugin-n": "^17.10.2",
108
- "eslint-plugin-perfectionist": "^3.5.0",
109
- "eslint-plugin-regexp": "^2.6.0",
103
+ "eslint-plugin-antfu": "^2.7.0",
104
+ "eslint-plugin-import-x": "^4.4.3",
105
+ "eslint-plugin-jsdoc": "^50.5.0",
106
+ "eslint-plugin-jsonc": "^2.18.2",
107
+ "eslint-plugin-n": "^17.14.0",
108
+ "eslint-plugin-perfectionist": "^4.0.3",
109
+ "eslint-plugin-regexp": "^2.7.0",
110
110
  "eslint-plugin-toml": "^0.11.1",
111
- "eslint-plugin-unicorn": "^55.0.0",
112
- "eslint-plugin-unused-imports": "^4.1.3",
113
- "eslint-plugin-vue": "^9.28.0",
114
- "eslint-plugin-yml": "^1.14.0",
111
+ "eslint-plugin-unicorn": "^56.0.1",
112
+ "eslint-plugin-unused-imports": "^4.1.4",
113
+ "eslint-plugin-vue": "^9.31.0",
114
+ "eslint-plugin-yml": "^1.15.0",
115
115
  "eslint-processor-vue-blocks": "^0.1.2",
116
- "globals": "^15.9.0",
116
+ "globals": "^15.12.0",
117
117
  "jsonc-eslint-parser": "^2.4.0",
118
- "local-pkg": "^0.5.0",
118
+ "local-pkg": "^0.5.1",
119
119
  "parse-gitignore": "^2.0.0",
120
120
  "toml-eslint-parser": "^0.10.0",
121
121
  "vue-eslint-parser": "^9.4.3",
122
122
  "yaml-eslint-parser": "^1.2.3"
123
123
  },
124
124
  "devDependencies": {
125
- "@eslint-react/eslint-plugin": "^1.14.0",
126
- "@eslint/config-inspector": "^0.5.4",
127
- "@stylistic/eslint-plugin-migrate": "^2.8.0",
128
- "@types/eslint": "^9.6.1",
129
- "@types/estree": "^1.0.5",
130
- "@types/node": "^20.14.12",
131
- "@typescript-eslint/rule-tester": "^8.5.0",
132
- "@unocss/eslint-plugin": "^0.62.3",
133
- "astro-eslint-parser": "^1.0.2",
134
- "eslint": "^9.10.0",
135
- "eslint-plugin-astro": "^1.2.3",
125
+ "@eslint-react/eslint-plugin": "^1.17.1",
126
+ "@eslint/config-inspector": "^0.5.6",
127
+ "@stylistic/eslint-plugin-migrate": "^2.11.0",
128
+ "@types/estree": "^1.0.6",
129
+ "@types/node": "^22.9.0",
130
+ "@typescript-eslint/rule-tester": "^8.15.0",
131
+ "@unocss/eslint-plugin": "^0.64.1",
132
+ "astro-eslint-parser": "^1.1.0",
133
+ "eslint": "^9.15.0",
134
+ "eslint-plugin-astro": "^1.3.1",
136
135
  "eslint-plugin-format": "^0.1.2",
137
- "eslint-plugin-react-hooks": "^4.6.2",
138
- "eslint-plugin-react-refresh": "^0.4.11",
139
- "eslint-plugin-tailwindcss": "^3.17.4",
136
+ "eslint-plugin-react-hooks": "^5.0.0",
137
+ "eslint-plugin-react-refresh": "^0.4.14",
138
+ "eslint-plugin-tailwindcss": "^3.17.5",
140
139
  "eslint-typegen": "^0.3.2",
141
- "jiti": "^1.21.6",
140
+ "jiti": "^2.4.0",
142
141
  "prettier-plugin-astro": "^0.14.1",
143
- "tailwindcss": "^3.4.10",
144
- "tsup": "^8.2.4",
145
- "typescript": "^5.6.2",
146
- "unocss": "^0.62.3",
147
- "vitest": "^2.0.5",
148
- "vue": "^3.5.4"
142
+ "tailwindcss": "^3.4.15",
143
+ "tsup": "^8.3.5",
144
+ "tsx": "^4.19.2",
145
+ "typescript": "^5.7.2",
146
+ "unocss": "^0.64.1",
147
+ "vitest": "^2.1.5",
148
+ "vue": "^3.5.13"
149
149
  },
150
150
  "resolutions": {
151
- "@eslint-community/eslint-utils": "^4.4.0",
152
- "@typescript-eslint/utils": "^8.5.0",
153
- "eslint": "^9.10.0",
154
- "tsx": "^4.19.0"
151
+ "@eslint-community/eslint-utils": "^4.4.1",
152
+ "@typescript-eslint/utils": "^8.15.0",
153
+ "eslint": "^9.15.0",
154
+ "tsx": "^4.19.2"
155
155
  }
156
156
  }