diff --git a/.changeset/violet-toes-warn.md b/.changeset/violet-toes-warn.md new file mode 100644 index 00000000..3adaedea --- /dev/null +++ b/.changeset/violet-toes-warn.md @@ -0,0 +1,8 @@ +--- +"eslint-config-sheriff": minor +"docs-website": minor +"create-sheriff-config": patch +"sheriff-webservices": patch +--- + +feat(rules): added eslint-plugin-arrow-return-style diff --git a/apps/config-validation-playground/package.json b/apps/config-validation-playground/package.json index 4436387b..cd5d7ecc 100644 --- a/apps/config-validation-playground/package.json +++ b/apps/config-validation-playground/package.json @@ -5,7 +5,7 @@ "type": "module", "packageManager": "pnpm@8.8.0", "scripts": { - "validate-config": "eslint . --max-warnings=0 --cache --cache-location 'node_modules/.cache/.eslintcache'" + "validate-config": "eslint . --max-warnings=0 --cache --cache-location=node_modules/.cache/.eslintcache" }, "dependencies": { "astro": "^4.0.8", diff --git a/apps/config-validation-playground/src/samples/basic.ts b/apps/config-validation-playground/src/samples/basic.ts index 8ecb03ef..ce85e67f 100644 --- a/apps/config-validation-playground/src/samples/basic.ts +++ b/apps/config-validation-playground/src/samples/basic.ts @@ -4,7 +4,9 @@ export const addNumbers = function (a: number, b: number): number { }; // Function to check if a number is even -export const isEven = (num: number): boolean => num % 2 === 0; +export const isEven = (num: number): boolean => { + return num % 2 === 0; +}; // Function to calculate the factorial of a number export const factorial = (num: number): number => { @@ -16,5 +18,6 @@ export const factorial = (num: number): number => { }; // Function to calculate the sum of a list of numbers -export const sum = (numbers: number[]): number => - numbers.reduce((acc, curr) => acc + curr, 0); +export const sum = (numbers: number[]): number => { + return numbers.reduce((acc, curr) => acc + curr, 0); +}; diff --git a/apps/config-validation-playground/src/samples/react.tsx b/apps/config-validation-playground/src/samples/react.tsx index fa3152b3..823c2ac1 100644 --- a/apps/config-validation-playground/src/samples/react.tsx +++ b/apps/config-validation-playground/src/samples/react.tsx @@ -1,5 +1,7 @@ -export const MyComponent = (): JSX.Element => ( -
-

Hello, World!

-
-); +export const MyComponent = (): JSX.Element => { + return ( +
+

Hello, World!

+
+ ); +}; diff --git a/apps/docs-website/docs/eslint-plugins.md b/apps/docs-website/docs/eslint-plugins.md index 0660a2a9..bd4c2233 100644 --- a/apps/docs-website/docs/eslint-plugins.md +++ b/apps/docs-website/docs/eslint-plugins.md @@ -16,6 +16,7 @@ sidebar_position: 7 - [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs) - [eslint-plugin-fp](https://github.com/jfmengels/eslint-plugin-fp) - [@regru/eslint-plugin-prefer-early-return](https://github.com/regru/eslint-plugin-prefer-early-return) +- [eslint-plugin-arrow-return-style](https://github.com/u3u/eslint-plugin-arrow-return-style) - [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) - [eslint-plugin-tsdoc](https://www.npmjs.com/package/eslint-plugin-tsdoc) - [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) diff --git a/apps/docs-website/eslint.config.js b/apps/docs-website/eslint.config.js index b37fd68e..3ec7ab03 100644 --- a/apps/docs-website/eslint.config.js +++ b/apps/docs-website/eslint.config.js @@ -47,7 +47,6 @@ module.exports = defineFlatConfig([ files: ["**/*ts", "**/*tsx"], rules: { "sonarjs/no-duplicate-string": 0, - "arrow-body-style": 0, "react/jsx-props-no-spreading": 0, "@typescript-eslint/no-misused-promises": [ 2, diff --git a/apps/docs-website/package.json b/apps/docs-website/package.json index 847c0c85..49dd9489 100644 --- a/apps/docs-website/package.json +++ b/apps/docs-website/package.json @@ -13,7 +13,7 @@ "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "typecheck": "tsc --noEmit", - "lint": "eslint . --max-warnings=0 --cache --cache-location 'node_modules/.cache/.eslintcache'", + "lint": "eslint . --max-warnings=0 --cache --cache-location=node_modules/.cache/.eslintcache", "typesync": "typesync --dry=fail", "clean": "rm -rf .turbo && rm -rf dist" }, diff --git a/apps/docs-website/src/components/RulesTable.tsx b/apps/docs-website/src/components/RulesTable.tsx index f06197b0..a9eda9b0 100644 --- a/apps/docs-website/src/components/RulesTable.tsx +++ b/apps/docs-website/src/components/RulesTable.tsx @@ -45,11 +45,13 @@ const columns = [ }), columnHelper.accessor("docs", { header: "Docs", - cell: (info) => ( - - {info.getValue().description || info.getValue().url} - - ), + cell: (info) => { + return ( + + {info.getValue().description || info.getValue().url} + + ); + }, }), columnHelper.accessor("affectedFiles", { header: "Files", @@ -161,60 +163,76 @@ export const RulesTable = (): JSX.Element => { placeholder="Filter by plugins..." value={selectValue} styles={{ - control: (baseStyles) => ({ - ...baseStyles, - minWidth: "300px", - backgroundColor: - "var(--ifm-color-secondary-contrast-background)", - }), - input: (baseStyles) => ({ - ...baseStyles, - color: "var(--ifm-font-color-primary)", - }), - menu: (baseStyles) => ({ - ...baseStyles, - backgroundColor: - "var(--ifm-color-secondary-contrast-background)", - }), - option: (baseStyles, state) => ({ - ...baseStyles, - transition: - "color var(--ifm-transition-fast) var(--ifm-transition-timing-default)", - backgroundColor: state.isFocused - ? "var(--ifm-menu-color-background-hover)" - : "var(--ifm-color-secondary-contrast-background)", - color: state.isFocused - ? "var(--ifm-menu-color)" - : "var(--ifm-font-color-secondary)", - ":active": { - backgroundColor: "var(--ifm-menu-color-background-hover)", - }, - }), - singleValue: (baseStyles) => ({ - ...baseStyles, - color: "var(--ifm-font-color-primary)", - }), - clearIndicator: (baseStyles) => ({ - ...baseStyles, - color: "var(--ifm-font-color-secondary)", - ":hover": { + control: (baseStyles) => { + return { + ...baseStyles, + minWidth: "300px", + backgroundColor: + "var(--ifm-color-secondary-contrast-background)", + }; + }, + input: (baseStyles) => { + return { + ...baseStyles, color: "var(--ifm-font-color-primary)", - }, - cursor: "pointer", - }), - dropdownIndicator: (baseStyles) => ({ - ...baseStyles, - color: "var(--ifm-font-color-secondary)", - ":hover": { + }; + }, + menu: (baseStyles) => { + return { + ...baseStyles, + backgroundColor: + "var(--ifm-color-secondary-contrast-background)", + }; + }, + option: (baseStyles, state) => { + return { + ...baseStyles, + transition: + "color var(--ifm-transition-fast) var(--ifm-transition-timing-default)", + backgroundColor: state.isFocused + ? "var(--ifm-menu-color-background-hover)" + : "var(--ifm-color-secondary-contrast-background)", + color: state.isFocused + ? "var(--ifm-menu-color)" + : "var(--ifm-font-color-secondary)", + ":active": { + backgroundColor: "var(--ifm-menu-color-background-hover)", + }, + }; + }, + singleValue: (baseStyles) => { + return { + ...baseStyles, color: "var(--ifm-font-color-primary)", - }, - cursor: "pointer", - }), + }; + }, + clearIndicator: (baseStyles) => { + return { + ...baseStyles, + color: "var(--ifm-font-color-secondary)", + ":hover": { + color: "var(--ifm-font-color-primary)", + }, + cursor: "pointer", + }; + }, + dropdownIndicator: (baseStyles) => { + return { + ...baseStyles, + color: "var(--ifm-font-color-secondary)", + ":hover": { + color: "var(--ifm-font-color-primary)", + }, + cursor: "pointer", + }; + }, }} - options={pluginsNames.map((pluginName) => ({ - value: pluginName, - label: pluginName, - }))} + options={pluginsNames.map((pluginName) => { + return { + value: pluginName, + label: pluginName, + }; + })} onChange={(selectedOption) => { setSelectValue(selectedOption); resetInputValue(); @@ -233,43 +251,54 @@ export const RulesTable = (): JSX.Element => { ) : ( - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - ))} - - ))} + {table.getHeaderGroups().map((headerGroup) => { + return ( + + {headerGroup.headers.map((header) => { + return ( + + ); + })} + + ); + })} - {table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - ))} - - ))} + {table.getRowModel().rows.map((row) => { + return ( + + {row.getVisibleCells().map((cell) => { + return ( + + ); + })} + + ); + })}
- {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} -
+ {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} +
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
+ {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} +
)} diff --git a/apps/docs-website/src/components/TableSkeleton.tsx b/apps/docs-website/src/components/TableSkeleton.tsx index 4168e9da..6d9098c1 100644 --- a/apps/docs-website/src/components/TableSkeleton.tsx +++ b/apps/docs-website/src/components/TableSkeleton.tsx @@ -1,63 +1,65 @@ import ContentLoader, { type IContentLoaderProps } from "react-content-loader"; -export const TableSkeleton = (props: IContentLoaderProps): JSX.Element => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); +export const TableSkeleton = (props: IContentLoaderProps): JSX.Element => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/docs-website/src/components/constants.ts b/apps/docs-website/src/components/constants.ts index 68363469..b62676e9 100644 --- a/apps/docs-website/src/components/constants.ts +++ b/apps/docs-website/src/components/constants.ts @@ -5,4 +5,4 @@ export const configCombinationDefaultValues = { playwright: true, vitest: true, jest: false, -}; +} as const; diff --git a/apps/sheriff-webservices/package.json b/apps/sheriff-webservices/package.json index f03d2287..7490e15d 100644 --- a/apps/sheriff-webservices/package.json +++ b/apps/sheriff-webservices/package.json @@ -8,7 +8,7 @@ "start": "tsx watch ./src/index.ts", "build": "tsc", "typecheck": "tsc --noEmit", - "lint": "eslint . --max-warnings=0 --cache --cache-location 'node_modules/.cache/.eslintcache'", + "lint": "eslint . --max-warnings=0 --cache --cache-location=node_modules/.cache/.eslintcache", "typesync": "typesync --dry=fail", "serve": "node ./dist/index.js", "clean": "rm -rf .turbo && rm -rf dist" diff --git a/knip.jsonc b/knip.jsonc index 077a8143..e6236776 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -17,5 +17,5 @@ "eslint-import-resolver-typescript", "type-fest" ], - "ignoreBinaries": ["only-allow"] + "ignoreBinaries": ["only-allow", "set"] } diff --git a/package.json b/package.json index 70fc6d97..c33485cb 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "typesync": "turbo run typesync", "knip": "knip", "validate-config": "turbo run validate-config", - "merge-checks": "FORCE_COLOR=1 turbo run publint manypkg typesync knip typecheck lint validate-config", + "merge-checks": "set FORCE_COLOR=1 && turbo run publint manypkg typesync knip typecheck lint validate-config", "cleanall": "turbo run clean", "delete-node-modules": "pnpm exec rm -rf node_modules && pnpm -r exec rm -rf node_modules", "nuke": "pnpm cleanall && pnpm delete-node-modules", diff --git a/packages/create-sheriff-config/package.json b/packages/create-sheriff-config/package.json index edc1c23d..f6662b4b 100644 --- a/packages/create-sheriff-config/package.json +++ b/packages/create-sheriff-config/package.json @@ -9,7 +9,7 @@ "clean": "rm -rf .turbo && rm -rf dist", "build": "tsup", "typecheck": "tsc --noEmit", - "lint": "eslint . --max-warnings=0 --cache --cache-location 'node_modules/.cache/.eslintcache'", + "lint": "eslint . --max-warnings=0 --cache --cache-location=node_modules/.cache/.eslintcache", "publint": "publint", "typesync": "typesync --dry=fail" }, diff --git a/packages/eslint-config-sheriff/package.json b/packages/eslint-config-sheriff/package.json index 61fe92bb..cb745ad7 100644 --- a/packages/eslint-config-sheriff/package.json +++ b/packages/eslint-config-sheriff/package.json @@ -66,6 +66,7 @@ "eslint-config-flat-gitignore": "^0.1.2", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-arrow-return-style": "^1.2.2", "eslint-plugin-astro": "^0.29.0", "eslint-plugin-fp": "^2.3.0", "eslint-plugin-fsecond": "^1.1.0", @@ -81,7 +82,7 @@ "eslint-plugin-sonarjs": "^0.19.0", "eslint-plugin-storybook": "^0.6.11", "eslint-plugin-tsdoc": "^0.2.17", - "eslint-plugin-unicorn": "^49.0.0", + "eslint-plugin-unicorn": "^50.0.1", "eslint-plugin-vitest": "^0.2.8" }, "peerDependencies": { diff --git a/packages/eslint-config-sheriff/src/getBaseEslintHandPickedRules.ts b/packages/eslint-config-sheriff/src/getBaseEslintHandPickedRules.ts index d8deb006..dafc99fd 100644 --- a/packages/eslint-config-sheriff/src/getBaseEslintHandPickedRules.ts +++ b/packages/eslint-config-sheriff/src/getBaseEslintHandPickedRules.ts @@ -98,7 +98,6 @@ export const getBaseEslintHandPickedRules = ( 'no-console': [2, { allow: ['warn', 'error', 'debug', 'info', 'table'] }], eqeqeq: 2, 'prefer-arrow-callback': 2, - 'arrow-body-style': [2, 'as-needed'], 'no-restricted-syntax': [ 2, ...getFilteredBaseNoRestrictedSyntax( @@ -116,5 +115,6 @@ export const getBaseEslintHandPickedRules = ( 'dot-notation': 0, // we are using the @typescript/eslint version 'no-shadow': 0, // we are using the @typescript/eslint version 'default-param-last': 0, // we are using the @typescript/eslint version + 'arrow-body-style': 0, // we are using the eslint-plugin-arrow-return-style version }; }; diff --git a/packages/eslint-config-sheriff/src/getExportableConfig.ts b/packages/eslint-config-sheriff/src/getExportableConfig.ts index 0edf260b..00940482 100644 --- a/packages/eslint-config-sheriff/src/getExportableConfig.ts +++ b/packages/eslint-config-sheriff/src/getExportableConfig.ts @@ -16,6 +16,7 @@ import preferEarlyReturn from '@regru/eslint-plugin-prefer-early-return'; import tsdoc from 'eslint-plugin-tsdoc'; import storybook from 'eslint-plugin-storybook'; import fsecond from 'eslint-plugin-fsecond'; +import arrowReturnStyle from 'eslint-plugin-arrow-return-style'; import stylistic from '@stylistic/eslint-plugin'; import getGitignorePatterns from 'eslint-config-flat-gitignore'; import lodash from 'lodash'; @@ -212,6 +213,14 @@ const getBaseConfig = (userConfigChoices: SheriffSettings) => { ...sonarjsHandPickedRules, }, }, + { + files: [supportedFileTypes], + plugins: { 'arrow-return-style': arrowReturnStyle }, + rules: { + 'arrow-return-style/arrow-return-style': 2, + 'arrow-return-style/no-export-default-arrow': 2, + }, + }, { files: [supportedFileTypes], plugins: { import: pluginImport }, diff --git a/packages/eslint-config-sheriff/src/unicornHandPickedRules.ts b/packages/eslint-config-sheriff/src/unicornHandPickedRules.ts index de47708c..504bb5f1 100644 --- a/packages/eslint-config-sheriff/src/unicornHandPickedRules.ts +++ b/packages/eslint-config-sheriff/src/unicornHandPickedRules.ts @@ -36,4 +36,5 @@ export const unicornHandPickedRules = { 'unicorn/prefer-switch': [2, { emptyDefaultCase: 'do-nothing-comment' }], 'unicorn/switch-case-braces': 2, 'unicorn/catch-error-name': 2, + 'unicorn/consistent-destructuring': 2, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27b71ac6..4164b29d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -329,6 +329,9 @@ importers: eslint-import-resolver-typescript: specifier: ^3.5.5 version: 3.6.1(@typescript-eslint/parser@6.17.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-plugin-arrow-return-style: + specifier: ^1.2.2 + version: 1.2.2(eslint@8.56.0)(typescript@5.3.3) eslint-plugin-astro: specifier: ^0.29.0 version: 0.29.1(eslint@8.56.0) @@ -375,8 +378,8 @@ importers: specifier: ^0.2.17 version: 0.2.17 eslint-plugin-unicorn: - specifier: ^49.0.0 - version: 49.0.0(eslint@8.56.0) + specifier: ^50.0.1 + version: 50.0.1(eslint@8.56.0) eslint-plugin-vitest: specifier: ^0.2.8 version: 0.2.8(eslint@8.56.0)(typescript@5.3.3) @@ -9034,6 +9037,19 @@ packages: - supports-color dev: false + /eslint-plugin-arrow-return-style@1.2.2(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-aGZdjczx3t7mJViUHNNKFgpJZST6yhzTjvBYzgX+cQIea3903uA/yDUezYQVxLYpE66qD7eY8ZiJ6X6zG0x8+g==} + peerDependencies: + eslint: '>=8.0.0' + dependencies: + '@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + scule: 1.1.1 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /eslint-plugin-astro@0.29.1(eslint@8.56.0): resolution: {integrity: sha512-ffuUc7zFz8HavaAVaS5iRUzWqBf3/YbrFWUhx0GxXW3gVtnbri5UyvkN8EMOkZWkNXG1zqD2y9dlEsAezhbC0w==} engines: {node: ^14.18.0 || >=16.0.0} @@ -9331,6 +9347,33 @@ packages: strip-indent: 3.0.0 dev: false + /eslint-plugin-unicorn@50.0.1(eslint@8.56.0): + resolution: {integrity: sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.56.0' + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint/eslintrc': 2.1.4 + ci-info: 4.0.0 + clean-regexp: 1.0.0 + core-js-compat: 3.35.0 + eslint: 8.56.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.5.4 + strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: false + /eslint-plugin-vitest@0.2.8(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-q8s4tStyKtn3gXf+8nf1ZYTHhoCXKdnozZzp6u8b4ni5v68Y4vxhNh4Z8njUfNjEY8HoPBB77MazHMR23IPb+g==} engines: {node: 14.x || >= 16} @@ -16062,6 +16105,10 @@ packages: ajv-keywords: 5.1.0(ajv@8.12.0) dev: false + /scule@1.1.1: + resolution: {integrity: sha512-sHtm/SsIK9BUBI3EFT/Gnp9VoKfY6QLvlkvAE6YK7454IF8FSgJEAnJpVdSC7K5/pjI5NfxhzBLW2JAfYA/shQ==} + dev: false + /search-insights@2.13.0: resolution: {integrity: sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==} dev: false