@shayanthenerd/eslint-config 0.23.0 → 0.24.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @shayanthenerd/eslint-config   [![license-badge]][license] [![npm-version-badge]][npmx]
2
2
 
3
- ESLint configuration for enforcing best practices and maintaining a consistent coding style. [Explore configurations][online-preview]!
3
+ ESLint configuration for enforcing best practices and maintaining a consistent coding style. [Inspect configurations][online-preview]!
4
4
 
5
5
  - **Flexible**: [Highly-customizable options](#customization) and configurations with sensible defaults.
6
6
  - **Smart**: Context-aware linting with [automatic dependency detection](#automatic-dependency-detection) and _.gitignore_ recognition.
@@ -58,7 +58,7 @@ Legend:
58
58
  | [promises][plugin-promise] | ✅  | ◻️  |
59
59
  | [Imports][plugin-import-x] | ✅  | ◻️  |
60
60
  | [Zod][plugin-zod] | ✅  | 🔎  |
61
- | [Node][plugin-node] | ⌛️  | N/A |
61
+ | [Node][plugin-n] |   | ◻️  |
62
62
  | [Unicorn][plugin-unicorn] | ⌛️  | N/A |
63
63
 
64
64
  ## Installation and Configuration
@@ -180,7 +180,7 @@ To opt out of this behavior, either [globally disable automatic dependency detec
180
180
 
181
181
  ## Framework and Tool Integrations
182
182
  ### Tailwind
183
- The Tailwind integration isn't automatically enabled because ESLint needs to know where to locate your Tailwind configuration.
183
+ To enable the Tailwind integration, provide the location of your Tailwind configuration or CSS entry point.
184
184
  ```js title="eslint.config.js"
185
185
  import { defineConfig } from '@shayanthenerd/eslint-config';
186
186
 
@@ -195,7 +195,7 @@ export default defineConfig({
195
195
  });
196
196
  ```
197
197
 
198
- For editor integration, to avoid inconsistent diagnostics and auto-fixes from the [Tailwind CSS IntelliSense VS Code extension][extension-tailwind], add the following settings to _.vscode/settings.json_:
198
+ For editor integration, to avoid inconsistent diagnostics from the [Tailwind CSS IntelliSense VS Code extension][extension-tailwind], add the following settings to _.vscode/settings.json_:
199
199
  ```json title=".vscode/settings.json"
200
200
  {
201
201
  "tailwindCSS.lint.cssConflict": "ignore",
@@ -225,6 +225,9 @@ By default, the plugin uses GitHub Flavored Markdown (GFM). You can [switch to C
225
225
  > [!NOTE]
226
226
  > Fenced code blocks inside Markdown files are not linted by @eslint/markdown.
227
227
 
228
+ ### Node.js
229
+ Some rules depend on the specified Node.js version. Visit the documentation for [version-resolution options and project-specific configurations](https://github.com/eslint-community/eslint-plugin-n#configured-nodejs-version-range).
230
+
228
231
  ## IDE Support
229
232
  Install the VS Code extensions for [ESLint][extension-eslint] and [Prettier][extension-prettier]. Then add the following in _.vscode/settings.json_:
230
233
  ```jsonc title=".vscode/settings.json"
@@ -346,32 +349,30 @@ _.vscode/settings.json_:
346
349
  ```
347
350
 
348
351
  ### Using Prettier Alone
349
- If you prefer to use Prettier as the only formatter, [disable the stylistic configuration](#customization) and let Prettier handle all formatting. Note that **this approach provides less granular control over the formatting options**.
352
+ If you prefer to use Prettier as the only formatter, [disable the stylistic configuration](#customization) and let Prettier handle all formatting. Just make sure to avoid running `lint` and `format` scripts on the same files simultaneously.
350
353
 
351
354
  _package.json_:
352
355
  ```json title="package.json"
353
356
  {
354
357
  "scripts": {
355
- "format": "prettier --write . --cache"
358
+ "format": "prettier --write . --cache",
359
+ "lint": "eslint --fix --cache --cache-location='node_modules/.cache/.eslintcache'"
356
360
  }
357
361
  }
358
362
  ```
359
363
  _.vscode/settings.json_:
360
364
  ```json title=".vscode/settings.json"
361
365
  {
362
- "eslint.format.enable": false,
363
366
  "editor.formatOnSave": true,
364
367
  "editor.defaultFormatter": "esbenp.prettier-vscode",
368
+
369
+ /* On file save, code actions are run before format, so the following doesn't cause conflicts. */
365
370
  "editor.codeActionsOnSave": {
366
- "source.fixAll.eslint": "never"
371
+ "source.fixAll.eslint": "explicit"
367
372
  }
368
373
  }
369
374
  ```
370
375
 
371
- When using this approach:
372
- - Avoid running `lint` and `format` scripts on the same files simultaneously.
373
- - Use either ESLint fixes or Prettier formatting when saving files, but not both.
374
-
375
376
  ## API Reference
376
377
  <details>
377
378
  <summary>
@@ -496,6 +497,9 @@ When using this approach:
496
497
  language?: 'gfm' | 'commonmark',
497
498
  overrides?: Overrides,
498
499
  },
500
+ node?: boolean | {
501
+ overrides?: Overrides,
502
+ },
499
503
  nuxt?: boolean | {
500
504
  icon?: boolean | {
501
505
  component?: string,
@@ -567,6 +571,9 @@ When using this approach:
567
571
  typeDefinitionStyle?: 'type' | 'interface',
568
572
  overrides?: Overrides,
569
573
  },
574
+ unicorn?: boolean | {
575
+ overrides?: Overrides,
576
+ },
570
577
  vue?: boolean | {
571
578
  accessibility?: boolean | {
572
579
  accessibleChildComponents?: string[],
@@ -639,7 +646,7 @@ Under this policy, minor updates may introduce new linting errors, which could b
639
646
  You can find a list of all available versions and their changelogs on the [releases page][releases].
640
647
 
641
648
  ## Roadmap to v1.0.0
642
- - [ ] Add integration for ESLint plugins such as [eslint-plugin-n][plugin-node], [eslint-plugin-unicorn][plugin-unicorn], and more.
649
+ - [x] Add integration for ESLint plugins such as [eslint-plugin-n][plugin-n], [eslint-plugin-unicorn][plugin-unicorn], and more.
643
650
  - [ ] Add support for other React, Next, Astro, and Markdown.
644
651
  - [ ] Develop an interactive starter wizard to quickly scaffold the configurations for ESLint, Prettier, etc.
645
652
 
@@ -671,8 +678,8 @@ This project was inspired by the work of [Anthony Fu][antfu], whose generous con
671
678
  [plugin-import-x]: https://github.com/un-ts/eslint-plugin-import-x
672
679
  [plugin-jsx-a11y]: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y
673
680
  [plugin-md]: https://github.com/eslint/markdown
681
+ [plugin-n]: https://github.com/eslint-community/eslint-plugin-n
674
682
  [plugin-next]: https://nextjs.org/docs/app/api-reference/config/eslint#eslint-plugin
675
- [plugin-node]: https://github.com/eslint-community/eslint-plugin-n
676
683
  [plugin-package-json]: https://github.com/JoshuaKGoldberg/eslint-plugin-package-json
677
684
  [plugin-perfectionist]: https://perfectionist.dev
678
685
  [plugin-playwright]: https://github.com/mskelton/eslint-plugin-playwright
@@ -3,15 +3,19 @@ import { isEnabled } from "../utils/isEnabled.mjs";
3
3
  import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getHTMLRules } from "../rules/html.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
+ import eslintPluginUnicorn from "eslint-plugin-unicorn";
6
7
  import eslintPluginHTML from "@html-eslint/eslint-plugin";
7
8
  //#region src/configs/html.ts
8
9
  function getHTMLConfig(options) {
9
- const { html } = options.configs;
10
+ const { html, unicorn } = options.configs;
10
11
  const { overrides } = isEnabled(html) ? html : defaultOptions.configs.html;
11
12
  return mergeConfigs({
12
13
  name: "shayanthenerd/html",
13
14
  files: [globs.html],
14
- plugins: { "@html-eslint": eslintPluginHTML },
15
+ plugins: {
16
+ "@html-eslint": eslintPluginHTML,
17
+ ...isEnabled(unicorn) && { unicorn: eslintPluginUnicorn }
18
+ },
15
19
  languageOptions: { parser: eslintPluginHTML.configs["flat/recommended"].languageOptions.parser },
16
20
  rules: getHTMLRules(options)
17
21
  }, overrides);
@@ -0,0 +1,27 @@
1
+ import { isTruthy } from "../utils/isTruthy.mjs";
2
+ import { globs } from "../helpers/globs.mjs";
3
+ import { isEnabled } from "../utils/isEnabled.mjs";
4
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
5
+ import { getNodeRules } from "../rules/node.mjs";
6
+ import { mergeConfigs } from "eslint-flat-config-utils";
7
+ import eslintPluginNode from "eslint-plugin-n";
8
+ import path from "node:path";
9
+ //#region src/configs/node.ts
10
+ function getNodeConfig(options) {
11
+ const { tsConfig, configs: { vue, node, astro } } = options;
12
+ const { overrides } = isEnabled(node) ? node : defaultOptions.configs.node;
13
+ const tsconfig = tsConfig ? path.resolve(tsConfig.rootDir, tsConfig.filename) : void 0;
14
+ return mergeConfigs({
15
+ name: "shayanthenerd/node",
16
+ files: [
17
+ globs.src,
18
+ isEnabled(vue) ? globs.vue : "",
19
+ isEnabled(astro) ? globs.astro : ""
20
+ ].filter(isTruthy),
21
+ plugins: { n: eslintPluginNode },
22
+ settings: { n: { tsconfigPath: tsconfig } },
23
+ rules: getNodeRules(options)
24
+ }, overrides);
25
+ }
26
+ //#endregion
27
+ export { getNodeConfig };
@@ -1,9 +1,9 @@
1
1
  import { globs } from "../helpers/globs.mjs";
2
- //#region src/configs/restrictedExports.ts
3
- function getRestrictedExports() {
2
+ //#region src/configs/restrictedDefaultExports.ts
3
+ function getRestrictedDefaultExports() {
4
4
  return {
5
- name: "shayanthenerd/restricted-exports",
6
- files: [globs.restrictedExports],
5
+ name: "shayanthenerd/restrict-default-exports",
6
+ files: [globs.restrictedDefaultExports],
7
7
  rules: { "no-restricted-exports": ["error", { restrictDefaultExports: {
8
8
  named: true,
9
9
  direct: true,
@@ -13,4 +13,4 @@ function getRestrictedExports() {
13
13
  };
14
14
  }
15
15
  //#endregion
16
- export { getRestrictedExports };
16
+ export { getRestrictedDefaultExports };
@@ -0,0 +1,24 @@
1
+ import { isTruthy } from "../utils/isTruthy.mjs";
2
+ import { globs } from "../helpers/globs.mjs";
3
+ import { isEnabled } from "../utils/isEnabled.mjs";
4
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
5
+ import { getUnicornRules } from "../rules/unicorn.mjs";
6
+ import { mergeConfigs } from "eslint-flat-config-utils";
7
+ import eslintPluginUnicorn from "eslint-plugin-unicorn";
8
+ //#region src/configs/unicorn.ts
9
+ function getUnicornConfig(options) {
10
+ const { vue, astro, unicorn } = options.configs;
11
+ const { overrides } = isEnabled(unicorn) ? unicorn : defaultOptions.configs.unicorn;
12
+ return mergeConfigs({
13
+ name: "shayanthenerd/unicorn",
14
+ files: [
15
+ globs.src,
16
+ isEnabled(vue) ? globs.vue : "",
17
+ isEnabled(astro) ? globs.astro : ""
18
+ ].filter(isTruthy),
19
+ plugins: { unicorn: eslintPluginUnicorn },
20
+ rules: getUnicornRules()
21
+ }, overrides);
22
+ }
23
+ //#endregion
24
+ export { getUnicornConfig };
@@ -11,14 +11,14 @@ import eslintPluginVueAccessibility from "eslint-plugin-vuejs-accessibility";
11
11
  const baseVueConfig = eslintPluginVue.configs["flat/base"].find((config) => config.languageOptions?.parser);
12
12
  function getVueConfig(options) {
13
13
  const { vue } = options.configs;
14
- const accessibility = isEnabled(vue) && isEnabled(vue.accessibility);
14
+ const isVueAccessibilityEnabled = isEnabled(vue) && isEnabled(vue.accessibility);
15
15
  const { overrides } = isEnabled(vue) ? vue : defaultOptions.configs.vue;
16
16
  return mergeConfigs({
17
17
  name: "shayanthenerd/vue",
18
18
  files: [globs.vue],
19
19
  plugins: {
20
20
  vue: eslintPluginVue,
21
- ...accessibility && { "vuejs-accessibility": eslintPluginVueAccessibility }
21
+ ...isVueAccessibilityEnabled && { "vuejs-accessibility": eslintPluginVueAccessibility }
22
22
  },
23
23
  processor: "vue/vue",
24
24
  languageOptions: {
@@ -32,7 +32,7 @@ function getVueConfig(options) {
32
32
  },
33
33
  rules: {
34
34
  ...getVueRules(options),
35
- ...accessibility && getVueAccessibilityRules(options)
35
+ ...isVueAccessibilityEnabled && getVueAccessibilityRules(options)
36
36
  }
37
37
  }, overrides);
38
38
  }
@@ -3,7 +3,7 @@ const srcExtensions = "?([mc])[jt]s?(x)";
3
3
  const vueExtensions = `{vue,${srcExtensions}}`;
4
4
  const globs = {
5
5
  src: `**/*.${srcExtensions}`,
6
- restrictedExports: `**/{${[
6
+ restrictedDefaultExports: `**/{${[
7
7
  "shared",
8
8
  "dto?(s)",
9
9
  "model?(s)",
@@ -59,6 +59,7 @@ const defaultOptions = {
59
59
  language: "gfm",
60
60
  overrides: {}
61
61
  },
62
+ node: { overrides: {} },
62
63
  nuxt: {
63
64
  icon: { component: "Icon" },
64
65
  image: false,
@@ -107,6 +108,7 @@ const defaultOptions = {
107
108
  typeDefinitionStyle: "interface",
108
109
  overrides: {}
109
110
  },
111
+ unicorn: { overrides: {} },
110
112
  vue: {
111
113
  accessibility: {
112
114
  accessibleChildComponents: [
@@ -3,6 +3,7 @@ import { isPackageDetected, logDetectedPackages } from "../isPackageDetected.mjs
3
3
  function enableDetectedConfigs(options) {
4
4
  options.configs ??= {};
5
5
  options.configs.test ??= {};
6
+ options.configs.node ??= true;
6
7
  options.configs.packageJson ??= true;
7
8
  options.configs.markdown ??= true;
8
9
  options.configs.html ??= false;
package/dist/index.mjs CHANGED
@@ -5,11 +5,13 @@ import { getVueConfig } from "./configs/vue.mjs";
5
5
  import { getZodConfig } from "./configs/zod.mjs";
6
6
  import { getBaseConfig } from "./configs/base.mjs";
7
7
  import { getHTMLConfig } from "./configs/html.mjs";
8
+ import { getNodeConfig } from "./configs/node.mjs";
8
9
  import { getAstroConfig } from "./configs/astro.mjs";
9
10
  import { getVitestConfig } from "./configs/vitest.mjs";
10
11
  import { getCypressConfig } from "./configs/cypress.mjs";
11
12
  import { getImportXConfig } from "./configs/importX.mjs";
12
13
  import { getPromiseConfig } from "./configs/promise.mjs";
14
+ import { getUnicornConfig } from "./configs/unicorn.mjs";
13
15
  import { getMarkdownConfig } from "./configs/markdown.mjs";
14
16
  import { getTailwindConfig } from "./configs/tailwind.mjs";
15
17
  import { getStorybookConfig } from "./configs/storybook.mjs";
@@ -18,11 +20,11 @@ import { getPlaywrightConfig } from "./configs/playwright.mjs";
18
20
  import { getTypeScriptConfig } from "./configs/typescript.mjs";
19
21
  import { getPackageJsonConfig } from "./configs/packageJson.mjs";
20
22
  import { getPerfectionistConfig } from "./configs/perfectionist.mjs";
21
- import { getRestrictedExports } from "./configs/restrictedExports.mjs";
22
23
  import { getIgnorePatterns } from "./helpers/ignores/getIgnorePatterns.mjs";
23
24
  import { mergeWithDefaults } from "./helpers/options/mergeWithDefaults.mjs";
24
25
  import { getVueComponentNamesConfig } from "./configs/vueComponentNames.mjs";
25
26
  import { getVueServerComponentsConfig } from "./configs/vueServerComponents.mjs";
27
+ import { getRestrictedDefaultExports } from "./configs/restrictedDefaultExports.mjs";
26
28
  import { defineConfig as defineConfig$1, globalIgnores } from "eslint/config";
27
29
  //#region src/index.ts
28
30
  /**
@@ -69,7 +71,7 @@ function defineConfig(...args) {
69
71
  configs = secondArgument ?? [];
70
72
  }
71
73
  const mergedOptions = mergeWithDefaults(options);
72
- const { gitignore, project: { rules, ignores, settings, linterOptions }, configs: { css, vue, zod, html, nuxt, astro, importX, promise, markdown, tailwind, stylistic, typescript, packageJson, perfectionist, base: { preferNamedExports }, test: { vitest, cypress, storybook, playwright } } } = mergedOptions;
74
+ const { gitignore, project: { rules, ignores, settings, linterOptions }, configs: { css, vue, zod, html, node, nuxt, astro, unicorn, importX, promise, markdown, tailwind, stylistic, typescript, packageJson, perfectionist, base: { preferNamedExports }, test: { vitest, cypress, storybook, playwright } } } = mergedOptions;
73
75
  const ignorePatterns = getIgnorePatterns({
74
76
  gitignore,
75
77
  patterns: ignores
@@ -84,11 +86,13 @@ function defineConfig(...args) {
84
86
  globalIgnores(ignorePatterns, "shayanthenerd/ignores"),
85
87
  getBaseConfig(mergedOptions),
86
88
  isEnabled(typescript) && getTypeScriptConfig(mergedOptions),
89
+ isEnabled(unicorn) && getUnicornConfig(mergedOptions),
87
90
  isEnabled(promise) && getPromiseConfig(mergedOptions),
88
91
  isEnabled(importX) && getImportXConfig(mergedOptions),
89
- preferNamedExports && getRestrictedExports(),
92
+ preferNamedExports && getRestrictedDefaultExports(),
90
93
  isEnabled(stylistic) && getStylisticConfig(mergedOptions),
91
94
  isEnabled(perfectionist) && getPerfectionistConfig(mergedOptions),
95
+ isEnabled(node) && getNodeConfig(mergedOptions),
92
96
  isEnabled(packageJson) && getPackageJsonConfig(mergedOptions),
93
97
  isEnabled(markdown) && getMarkdownConfig(mergedOptions),
94
98
  isEnabled(html) && getHTMLConfig(mergedOptions),
@@ -14,36 +14,36 @@ const allowedPhysicalUnits = [
14
14
  "vw"
15
15
  ];
16
16
  const allowedPhysicalProperties = [
17
+ "top",
17
18
  "bottom",
18
- "border-bottom",
19
- "border-bottom-color",
20
- "border-bottom-style",
21
- "border-bottom-width",
19
+ "padding-top",
20
+ "padding-bottom",
21
+ "margin-top",
22
+ "margin-bottom",
22
23
  "border-top",
23
24
  "border-top-color",
24
25
  "border-top-style",
25
26
  "border-top-width",
26
- "contain-intrinsic-height",
27
- "contain-intrinsic-width",
28
- "height",
29
- "margin-bottom",
30
- "margin-top",
31
- "max-height",
27
+ "border-bottom",
28
+ "border-bottom-color",
29
+ "border-bottom-style",
30
+ "border-bottom-width",
31
+ "width",
32
+ "min-width",
32
33
  "max-width",
34
+ "height",
33
35
  "min-height",
34
- "min-width",
36
+ "max-height",
35
37
  "overflow-x",
36
38
  "overflow-y",
37
39
  "overscroll-behavior-x",
38
40
  "overscroll-behavior-y",
39
- "padding-bottom",
40
- "padding-top",
41
- "scroll-margin-bottom",
42
- "scroll-margin-top",
43
- "scroll-padding-bottom",
44
41
  "scroll-padding-top",
45
- "top",
46
- "width"
42
+ "scroll-padding-bottom",
43
+ "scroll-margin-top",
44
+ "scroll-margin-bottom",
45
+ "contain-intrinsic-width",
46
+ "contain-intrinsic-height"
47
47
  ];
48
48
  function getCSSRules(options) {
49
49
  const { css } = options.configs;
@@ -2,7 +2,7 @@ import { isEnabled } from "../utils/isEnabled.mjs";
2
2
  import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
3
3
  //#region src/rules/html.ts
4
4
  function getHTMLRules(options) {
5
- const { html, tailwind, stylistic } = options.configs;
5
+ const { html, unicorn, tailwind, stylistic } = options.configs;
6
6
  const { useBaseline, idNamingConvention } = isEnabled(html) ? html : defaultOptions.configs.html;
7
7
  const { indent, maxLineLength, maxAttributesPerLine, maxConsecutiveEmptyLines, selfCloseVoidHTMLElements } = isEnabled(stylistic) ? stylistic : defaultOptions.configs.stylistic;
8
8
  const htmlRules = {
@@ -77,6 +77,7 @@ function getHTMLRules(options) {
77
77
  ]
78
78
  };
79
79
  if (isEnabled(tailwind)) htmlRules["better-tailwindcss/no-duplicate-classes"] = "off";
80
+ if (isEnabled(unicorn)) htmlRules["unicorn/no-invalid-file-input-accept"] = "error";
80
81
  return htmlRules;
81
82
  }
82
83
  //#endregion
@@ -1,28 +1,31 @@
1
+ import { isEnabled } from "../utils/isEnabled.mjs";
1
2
  //#region src/rules/javascript.ts
2
3
  function getJavaScriptRules(options) {
3
- const { typescript, base: { maxDepth, functionStyle, maxNestedCallbacks, preferNamedExports } } = options.configs;
4
+ const { unicorn, typescript, base: { maxDepth, functionStyle, maxNestedCallbacks } } = options.configs;
5
+ const isUnicornEnabled = isEnabled(unicorn);
6
+ const isTypeScriptEnabled = isEnabled(typescript);
4
7
  return {
5
8
  "array-callback-return": "error",
6
- "constructor-super": typescript ? "off" : "error",
9
+ "constructor-super": isTypeScriptEnabled ? "off" : "error",
7
10
  "for-direction": "error",
8
- "getter-return": typescript ? "off" : "error",
11
+ "getter-return": isTypeScriptEnabled ? "off" : ["error", { allowImplicit: true }],
9
12
  "no-async-promise-executor": "error",
10
13
  "no-await-in-loop": "error",
11
14
  "no-case-declarations": "error",
12
- "no-class-assign": typescript ? "off" : "error",
15
+ "no-class-assign": isTypeScriptEnabled ? "off" : "error",
13
16
  "no-compare-neg-zero": "error",
14
17
  "no-cond-assign": "error",
15
- "no-const-assign": typescript ? "off" : "error",
18
+ "no-const-assign": isTypeScriptEnabled ? "off" : "error",
16
19
  "no-constant-binary-expression": "error",
17
20
  "no-constant-condition": "error",
18
21
  "no-constructor-return": "error",
19
22
  "no-control-regex": "error",
20
23
  "no-debugger": "error",
21
24
  "no-delete-var": "error",
22
- "no-dupe-args": typescript ? "off" : "error",
23
- "no-dupe-class-members": typescript ? "off" : "error",
25
+ "no-dupe-args": isTypeScriptEnabled ? "off" : "error",
26
+ "no-dupe-class-members": isTypeScriptEnabled ? "off" : "error",
24
27
  "no-dupe-else-if": "error",
25
- "no-dupe-keys": typescript ? "off" : "error",
28
+ "no-dupe-keys": isTypeScriptEnabled ? "off" : "error",
26
29
  "no-duplicate-case": "error",
27
30
  "no-duplicate-imports": ["error", {
28
31
  includeExports: true,
@@ -33,9 +36,9 @@ function getJavaScriptRules(options) {
33
36
  "no-empty-static-block": "error",
34
37
  "no-ex-assign": "error",
35
38
  "no-fallthrough": "error",
36
- "no-func-assign": typescript ? "off" : "error",
39
+ "no-func-assign": isTypeScriptEnabled ? "off" : "error",
37
40
  "no-global-assign": "error",
38
- "no-import-assign": typescript ? "off" : "error",
41
+ "no-import-assign": isTypeScriptEnabled ? "off" : "error",
39
42
  "no-inner-declarations": "warn",
40
43
  "no-invalid-regexp": "error",
41
44
  "no-irregular-whitespace": "warn",
@@ -47,9 +50,9 @@ function getJavaScriptRules(options) {
47
50
  "no-unassigned-vars": "error",
48
51
  "no-unmodified-loop-condition": "error",
49
52
  "no-unreachable-loop": "warn",
50
- "no-unsafe-negation": typescript ? "off" : ["error", { enforceForOrderingRelations: true }],
53
+ "no-unsafe-negation": isTypeScriptEnabled ? "off" : ["error", { enforceForOrderingRelations: true }],
51
54
  "no-unsafe-optional-chaining": ["error", { disallowArithmeticOperators: true }],
52
- "no-unused-vars": [typescript ? "off" : "error", {
55
+ "no-unused-vars": [isTypeScriptEnabled ? "off" : "error", {
53
56
  args: "all",
54
57
  argsIgnorePattern: "^_",
55
58
  varsIgnorePattern: "^_",
@@ -76,13 +79,13 @@ function getJavaScriptRules(options) {
76
79
  ignoreClassesWithImplements: "public-fields"
77
80
  }],
78
81
  "complexity": "warn",
79
- "consistent-return": typescript ? "off" : "error",
82
+ "consistent-return": isTypeScriptEnabled ? "off" : "error",
80
83
  "consistent-this": "error",
81
84
  "curly": "warn",
82
85
  "default-case": "warn",
83
86
  "default-case-last": "warn",
84
- "default-param-last": typescript ? "off" : "warn",
85
- "dot-notation": typescript ? "off" : "warn",
87
+ "default-param-last": isTypeScriptEnabled ? "off" : "warn",
88
+ "dot-notation": isTypeScriptEnabled ? "off" : "warn",
86
89
  "eqeqeq": "error",
87
90
  "func-name-matching": "warn",
88
91
  "func-names": ["warn", "as-needed"],
@@ -130,22 +133,23 @@ function getJavaScriptRules(options) {
130
133
  "no-extra-label": "error",
131
134
  "no-implicit-coercion": "error",
132
135
  "no-implicit-globals": "error",
133
- "no-implied-eval": typescript ? "off" : "error",
134
- "no-invalid-this": typescript ? "off" : "error",
136
+ "no-implied-eval": isTypeScriptEnabled ? "off" : "error",
137
+ "no-invalid-this": isTypeScriptEnabled ? "off" : "error",
135
138
  "no-iterator": "warn",
136
139
  "no-label-var": "error",
137
140
  "no-lone-blocks": "error",
138
- "no-lonely-if": "error",
141
+ "no-lonely-if": isUnicornEnabled ? "off" : "warn",
139
142
  "no-loop-func": "warn",
140
143
  "no-multi-assign": ["error", { ignoreNonDeclaration: true }],
141
144
  "no-multi-str": "error",
142
- "no-nested-ternary": "warn",
145
+ "no-negated-condition": "warn",
146
+ "no-nested-ternary": isUnicornEnabled ? "off" : "warn",
143
147
  "no-new": "error",
144
148
  "no-new-func": "error",
145
- "no-new-native-nonconstructor": typescript ? "off" : "error",
149
+ "no-new-native-nonconstructor": isTypeScriptEnabled || isUnicornEnabled ? "off" : "error",
146
150
  "no-new-wrappers": "error",
147
151
  "no-nonoctal-decimal-escape": "error",
148
- "no-obj-calls": typescript ? "off" : "error",
152
+ "no-obj-calls": isTypeScriptEnabled ? "off" : "error",
149
153
  "no-object-constructor": "error",
150
154
  "no-octal": "error",
151
155
  "no-octal-escape": "error",
@@ -154,17 +158,11 @@ function getJavaScriptRules(options) {
154
158
  "no-proto": "warn",
155
159
  "no-prototype-builtins": "error",
156
160
  "no-regex-spaces": "error",
157
- "no-restricted-exports": [preferNamedExports ? "error" : "off", { restrictDefaultExports: {
158
- named: true,
159
- namedFrom: true,
160
- defaultFrom: true,
161
- namespaceFrom: true
162
- } }],
163
161
  "no-return-assign": ["error", "always"],
164
162
  "no-script-url": "error",
165
163
  "no-self-assign": "error",
166
164
  "no-sequences": ["error", { allowInParentheses: false }],
167
- "no-setter-return": typescript ? "off" : "error",
165
+ "no-setter-return": isTypeScriptEnabled ? "off" : "error",
168
166
  "no-shadow": ["error", {
169
167
  hoist: "all",
170
168
  allow: ["name"],
@@ -174,13 +172,13 @@ function getJavaScriptRules(options) {
174
172
  }],
175
173
  "no-shadow-restricted-names": "warn",
176
174
  "no-sparse-arrays": "error",
177
- "no-this-before-super": typescript ? "off" : "error",
175
+ "no-this-before-super": isTypeScriptEnabled ? "off" : "error",
178
176
  "no-throw-literal": "error",
179
- "no-undef": typescript ? "off" : "error",
177
+ "no-undef": isTypeScriptEnabled ? "off" : "error",
180
178
  "no-undef-init": "error",
181
179
  "no-unexpected-multiline": "error",
182
180
  "no-unneeded-ternary": "error",
183
- "no-unreachable": typescript ? "off" : "error",
181
+ "no-unreachable": isTypeScriptEnabled ? "off" : "error",
184
182
  "no-unsafe-finally": "error",
185
183
  "no-unused-expressions": ["error", {
186
184
  allowTernary: true,
@@ -189,7 +187,7 @@ function getJavaScriptRules(options) {
189
187
  allowTaggedTemplates: true
190
188
  }],
191
189
  "no-unused-labels": "error",
192
- "no-unused-private-class-members": typescript ? "off" : "error",
190
+ "no-unused-private-class-members": isTypeScriptEnabled ? "off" : "error",
193
191
  "no-useless-backreference": "error",
194
192
  "no-useless-call": "error",
195
193
  "no-useless-catch": "error",
@@ -206,20 +204,23 @@ function getJavaScriptRules(options) {
206
204
  "operator-assignment": "error",
207
205
  "prefer-arrow-callback": ["warn", { allowUnboundThis: true }],
208
206
  "prefer-const": "error",
209
- "prefer-destructuring": [typescript ? "off" : "warn", { array: false }],
207
+ "prefer-destructuring": [isTypeScriptEnabled ? "off" : "warn", {
208
+ object: true,
209
+ array: false
210
+ }],
210
211
  "prefer-exponentiation-operator": "warn",
211
212
  "prefer-named-capture-group": "warn",
212
213
  "prefer-numeric-literals": "warn",
213
214
  "prefer-object-has-own": "warn",
214
215
  "prefer-object-spread": "warn",
215
- "prefer-promise-reject-errors": [typescript ? "off" : "warn", { allowEmptyReject: true }],
216
+ "prefer-promise-reject-errors": [isTypeScriptEnabled ? "off" : "warn", { allowEmptyReject: true }],
216
217
  "prefer-regex-literals": ["warn", { disallowRedundantWrapping: true }],
217
218
  "prefer-rest-params": "warn",
218
219
  "prefer-spread": "warn",
219
220
  "prefer-template": "warn",
220
221
  "preserve-caught-error": "warn",
221
222
  "radix": "warn",
222
- "require-await": typescript ? "off" : "warn",
223
+ "require-await": isTypeScriptEnabled ? "off" : "warn",
223
224
  "require-yield": "error",
224
225
  "strict": "error",
225
226
  "symbol-description": "warn",
@@ -0,0 +1,35 @@
1
+ import { isEnabled } from "../utils/isEnabled.mjs";
2
+ //#region src/rules/node.ts
3
+ function getNodeRules(options) {
4
+ const { typescript } = options.configs;
5
+ return {
6
+ "n/file-extension-in-import": "error",
7
+ "n/hashbang": "error",
8
+ "n/no-deprecated-api": "error",
9
+ "n/no-exports-assign": "error",
10
+ "n/no-missing-import": isEnabled(typescript) ? "off" : "error",
11
+ "n/no-path-concat": "error",
12
+ "n/no-process-env": ["error", { allowedVariables: ["NODE_ENV"] }],
13
+ "n/no-process-exit": "error",
14
+ "n/no-sync": "warn",
15
+ "n/no-unpublished-import": "error",
16
+ "n/no-unsupported-features/es-builtins": "error",
17
+ "n/no-unsupported-features/es-syntax": "error",
18
+ "n/no-unsupported-features/node-builtins": "error",
19
+ "n/prefer-global/buffer": "warn",
20
+ "n/prefer-global/console": "warn",
21
+ "n/prefer-global/crypto": "warn",
22
+ "n/prefer-global/process": "warn",
23
+ "n/prefer-global/text-decoder": "warn",
24
+ "n/prefer-global/text-encoder": "warn",
25
+ "n/prefer-global/timers": "warn",
26
+ "n/prefer-global/url": "warn",
27
+ "n/prefer-global/url-search-params": "warn",
28
+ "n/prefer-node-protocol": "warn",
29
+ "n/prefer-promises/dns": "warn",
30
+ "n/prefer-promises/fs": "warn",
31
+ "n/process-exit-as-throw": "error"
32
+ };
33
+ }
34
+ //#endregion
35
+ export { getNodeRules };
@@ -57,15 +57,7 @@ function getStylisticRules(options) {
57
57
  "@stylistic/keyword-spacing": "warn",
58
58
  "@stylistic/linebreak-style": "warn",
59
59
  "@stylistic/lines-around-comment": ["warn", {
60
- allowTypeStart: true,
61
- allowEnumStart: true,
62
- allowClassStart: true,
63
- allowBlockStart: true,
64
- allowArrayStart: true,
65
- allowModuleStart: true,
66
- allowObjectStart: true,
67
- allowInterfaceStart: true,
68
- afterHashbangComment: true,
60
+ beforeBlockComment: false,
69
61
  applyDefaultIgnorePatterns: false,
70
62
  ignorePattern: "@ts|eslint"
71
63
  }],