@open-xchange/linter-presets 0.10.3 → 0.11.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## `0.11.0` – 2024-Nov-19
4
+
5
+ - change: (ESLint) switch from `eslint-plugin-react` to `@eslint-react/eslint-plugin`
6
+ - change: (ESLint) remove `eslint-plugin-jsx-expressions` plugin
7
+
8
+ ## `0.10.4` – 2024-Nov-18
9
+
10
+ - fix: (ESLint) correctly configure `vue/html-indent` rule
11
+
3
12
  ## `0.10.3` – 2024-Nov-18
4
13
 
5
14
  - chore: (ESLint) bump dependencies to fix ESLint v9.15 API errors
@@ -1,5 +1,5 @@
1
1
  import type { Linter } from "eslint";
2
- import { type LanguageConfig } from "../shared/env-utils.js";
2
+ import type { LanguageConfig, StylisticConfig } from "../shared/env-utils.js";
3
3
  /**
4
4
  * Creates configuration objects with linter rules for Vue.js.
5
5
  *
@@ -9,7 +9,10 @@ import { type LanguageConfig } from "../shared/env-utils.js";
9
9
  * @param languageConfig
10
10
  * Resolved language configuration options.
11
11
  *
12
+ * @param stylisticConfig
13
+ * Resolved stylistic configuration options.
14
+ *
12
15
  * @returns
13
16
  * An array of configuration objects to be added to the flat configuration.
14
17
  */
15
- export default function vue(languageConfig: LanguageConfig): Linter.Config[];
18
+ export default function vue(languageConfig: LanguageConfig, stylisticConfig: StylisticConfig): Linter.Config[];
@@ -12,10 +12,13 @@ import { fixMissingFilesOption } from "../shared/env-utils.js";
12
12
  * @param languageConfig
13
13
  * Resolved language configuration options.
14
14
  *
15
+ * @param stylisticConfig
16
+ * Resolved stylistic configuration options.
17
+ *
15
18
  * @returns
16
19
  * An array of configuration objects to be added to the flat configuration.
17
20
  */
18
- export default function vue(languageConfig) {
21
+ export default function vue(languageConfig, stylisticConfig) {
19
22
  // add missing "files" property in configurations with rules (otherwise, plugin conflicts with "@eslint/markdown")
20
23
  return fixMissingFilesOption([
21
24
  // use TypeScript parser for Vue files
@@ -34,8 +37,9 @@ export default function vue(languageConfig) {
34
37
  // reconfigure plugin rules
35
38
  {
36
39
  rules: {
37
- "vue/singleline-html-element-content-newline": "off",
40
+ "vue/html-indent": ["error", stylisticConfig.indent.vue],
38
41
  "vue/max-attributes-per-line": "off",
42
+ "vue/singleline-html-element-content-newline": "off",
39
43
  },
40
44
  },
41
45
  ]);
@@ -1,5 +1,5 @@
1
1
  import type { Linter } from "eslint";
2
- import { type EnvBaseOptions } from "../shared/env-utils.js";
2
+ import type { EnvBaseOptions } from "../shared/env-utils.js";
3
3
  /**
4
4
  * Configuration options for the environment preset "env.react".
5
5
  */
@@ -13,11 +13,10 @@ export interface EnvReactOptions extends EnvBaseOptions {
13
13
  * Creates configuration objects with linter rules for ReactJS.
14
14
  *
15
15
  * Wraps the following packages:
16
- * - `eslint-plugin-react`
16
+ * - `@eslint-react/eslint-plugin`
17
17
  * - `eslint-plugin-react-hooks`
18
18
  * - `eslint-plugin-react-hooks-static-deps`
19
19
  * - `eslint-plugin-react-refresh`
20
- * - `eslint-plugin-jsx-expressions`
21
20
  * - `eslint-plugin-jsx-a11y`
22
21
  *
23
22
  * @param envOptions
@@ -1,22 +1,20 @@
1
- import reactPlugin from "eslint-plugin-react";
1
+ import reactPlugin from "@eslint-react/eslint-plugin";
2
2
  import reactHooksPlugin from "eslint-plugin-react-hooks";
3
3
  import reactHooksStaticDepsPlugin from "eslint-plugin-react-hooks-static-deps";
4
4
  import reactRefreshPlugin from "eslint-plugin-react-refresh";
5
- import jsxExpressionsPlugin from "eslint-plugin-jsx-expressions";
6
5
  import jsxA11yPlugin from "eslint-plugin-jsx-a11y";
7
6
  import { fixupPluginRules } from "@eslint/compat";
8
- import { JS_GLOB } from "../shared/env-utils.js";
9
- import { concatConfigs, createConfig, customRules } from "../shared/env-utils.js";
7
+ import { parser } from "typescript-eslint";
8
+ import { concatConfigs, createConfig, customRules, convertRuleWarningsToErrors } from "../shared/env-utils.js";
10
9
  // functions ==================================================================
11
10
  /**
12
11
  * Creates configuration objects with linter rules for ReactJS.
13
12
  *
14
13
  * Wraps the following packages:
15
- * - `eslint-plugin-react`
14
+ * - `@eslint-react/eslint-plugin`
16
15
  * - `eslint-plugin-react-hooks`
17
16
  * - `eslint-plugin-react-hooks-static-deps`
18
17
  * - `eslint-plugin-react-refresh`
19
- * - `eslint-plugin-jsx-expressions`
20
18
  * - `eslint-plugin-jsx-a11y`
21
19
  *
22
20
  * @param envOptions
@@ -26,35 +24,36 @@ import { concatConfigs, createConfig, customRules } from "../shared/env-utils.js
26
24
  * An array of configuration objects to be added to the flat configuration.
27
25
  */
28
26
  export default function react(envOptions) {
27
+ // recommended configuration of the main plugin
28
+ const recommendedConfig = reactPlugin.configs["recommended-type-checked"];
29
29
  return concatConfigs(
30
30
  // configure "react" plugin for all source files (JSX and TSX)
31
31
  createConfig(envOptions, {
32
32
  // auto-detect installed React version
33
- settings: {
34
- react: {
35
- version: "detect",
36
- },
33
+ languageOptions: {
34
+ parser: parser,
35
+ parserOptions: { projectService: true },
37
36
  },
38
37
  // register rule implementations and language settings
39
- // TODO: remove type cast after fix: https://github.com/jsx-eslint/eslint-plugin-react/issues/3838
40
- ...reactPlugin.configs.flat.recommended,
38
+ ...recommendedConfig,
41
39
  rules: {
42
- // recommended rules
43
- ...(reactPlugin.configs.flat.recommended.rules),
44
- ...(reactPlugin.configs.flat["jsx-runtime"].rules),
40
+ // recommended rules (move all to error level)
41
+ ...convertRuleWarningsToErrors(recommendedConfig.rules),
45
42
  // custom overrides
46
- "react/hook-use-state": "error",
47
- "react/iframe-missing-sandbox": "error",
48
- "react/jsx-boolean-value": "error",
49
- "react/jsx-no-script-url": "error",
50
- "react/jsx-no-useless-fragment": "error",
51
- "react/jsx-props-no-spread-multi": "error",
52
- "react/no-danger": "error",
53
- "react/no-invalid-html-attribute": "error",
54
- "react/no-typos": "error",
55
- "react/prop-types": ["error", { skipUndeclared: true }],
56
- "react/style-prop-object": "error",
57
- "react/void-dom-elements-no-children": "error",
43
+ "@eslint-react/jsx-no-duplicate-props": "error",
44
+ "@eslint-react/jsx-uses-vars": "error",
45
+ "@eslint-react/no-children-prop": "error",
46
+ "@eslint-react/no-class-component": "error",
47
+ "@eslint-react/no-implicit-key": "error",
48
+ "@eslint-react/no-missing-component-display-name": "error",
49
+ "@eslint-react/no-useless-fragment": "error",
50
+ "@eslint-react/prefer-shorthand-boolean": "error",
51
+ "@eslint-react/prefer-shorthand-fragment": "error",
52
+ "@eslint-react/dom/no-unknown-property": "error",
53
+ "@eslint-react/hooks-extra/no-unnecessary-use-callback": "error",
54
+ "@eslint-react/hooks-extra/no-unnecessary-use-memo": "error",
55
+ "@eslint-react/naming-convention/filename-extension": ["error", { allow: "as-needed" }],
56
+ "@eslint-react/naming-convention/use-state": "error",
58
57
  },
59
58
  }),
60
59
  // "react-hooks" plugin
@@ -86,18 +85,6 @@ export default function react(envOptions) {
86
85
  "react-refresh/only-export-components": ["error", { allowConstantExport: true }],
87
86
  },
88
87
  }),
89
- // "jsx-expressions" plugin (TSX only)
90
- createConfig(envOptions, {
91
- ignores: JS_GLOB,
92
- // register rule implementations of the plugins
93
- plugins: {
94
- "jsx-expressions": fixupPluginRules(jsxExpressionsPlugin), // https://github.com/hluisson/eslint-plugin-jsx-expressions/issues/18
95
- },
96
- rules: {
97
- // replace "react/jsx-no-leaked-render" rule with advanced alternative
98
- "jsx-expressions/strict-logical-expressions": "error",
99
- },
100
- }),
101
88
  // "jsx-a11y" plugin
102
89
  createConfig(envOptions, jsxA11yPlugin.flatConfigs.recommended),
103
90
  // custom rules
@@ -86,7 +86,7 @@ export function configure(options) {
86
86
  // default configuration for TypeScript files
87
87
  ...ts(),
88
88
  // default configuration for Vue.js files
89
- ...vue(languageConfig),
89
+ ...vue(languageConfig, stylisticConfig),
90
90
  // default configuration for JSON files
91
91
  ...json(stylisticConfig),
92
92
  // default configuration for YAML files
@@ -233,3 +233,13 @@ export declare function customRules(envOptions: EnvBaseOptions, rules?: Linter.R
233
233
  * The fixed configuration options.
234
234
  */
235
235
  export declare function fixMissingFilesOption(configs: Linter.Config[]): Linter.Config[];
236
+ /**
237
+ * Converts all warnings in the passed rule options to errors.
238
+ *
239
+ * @param rules
240
+ * The rules record to be converted.
241
+ *
242
+ * @returns
243
+ * The converted rules record.
244
+ */
245
+ export declare function convertRuleWarningsToErrors(rules: Linter.RulesRecord): Linter.RulesRecord;
@@ -141,3 +141,23 @@ export function fixMissingFilesOption(configs) {
141
141
  const files = configs.find(config => config.files)?.files;
142
142
  return files ? configs.map(config => (!config.files && (config.languageOptions || config.rules)) ? { ...config, files } : config) : configs;
143
143
  }
144
+ /**
145
+ * Converts all warnings in the passed rule options to errors.
146
+ *
147
+ * @param rules
148
+ * The rules record to be converted.
149
+ *
150
+ * @returns
151
+ * The converted rules record.
152
+ */
153
+ export function convertRuleWarningsToErrors(rules) {
154
+ return Object.fromEntries(Object.entries(rules).map(([key, value]) => {
155
+ if (value === "warn") {
156
+ value = "error";
157
+ }
158
+ else if (Array.isArray(value) && (value[0] === "warn")) {
159
+ value = ["error", ...value.slice(1)];
160
+ }
161
+ return [key, value];
162
+ }));
163
+ }
@@ -2,11 +2,10 @@
2
2
 
3
3
  Creates configuration objects with linter rules for ReactJS. Adds the following plugins and their recommended rules:
4
4
 
5
- - [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react)
5
+ - [@eslint-react/eslint-plugin](https://eslint-react.xyz/)
6
6
  - [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks)
7
7
  - [eslint-plugin-react-hooks-static-deps](https://github.com/stoikio/eslint-plugin-react-hooks-static-deps)
8
8
  - [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh)
9
- - [eslint-plugin-jsx-expressions](https://github.com/hluisson/eslint-plugin-jsx-expressions)
10
9
  - [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
11
10
 
12
11
  ## Signature
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-xchange/linter-presets",
3
- "version": "0.10.3",
3
+ "version": "0.11.0",
4
4
  "description": "Configuration presets for ESLint and StyleLint",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,6 +25,7 @@
25
25
  "@babel/eslint-parser": "^7.25.9",
26
26
  "@babel/plugin-proposal-decorators": "^7.25.9",
27
27
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
28
+ "@eslint-react/eslint-plugin": "^1.16.1",
28
29
  "@eslint/compat": "^1.2.3",
29
30
  "@eslint/js": "^9.15.0",
30
31
  "@eslint/markdown": "^6.2.1",
@@ -44,11 +45,9 @@
44
45
  "eslint-plugin-jsdoc": "^50.5.0",
45
46
  "eslint-plugin-jsonc": "^2.18.2",
46
47
  "eslint-plugin-jsx-a11y": "^6.10.2",
47
- "eslint-plugin-jsx-expressions": "^1.3.2",
48
48
  "eslint-plugin-license-header": "^0.6.1",
49
49
  "eslint-plugin-n": "^17.13.2",
50
50
  "eslint-plugin-promise": "^7.1.0",
51
- "eslint-plugin-react": "^7.37.2",
52
51
  "eslint-plugin-react-hooks": "^5.0.0",
53
52
  "eslint-plugin-react-hooks-static-deps": "^1.0.7",
54
53
  "eslint-plugin-react-refresh": "^0.4.14",