diff --git a/.eslintrc.js b/.eslintrc.js index 29c7311c..f2a286f5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,22 +1,135 @@ -/** @type {import('@types/eslint').Linter.BaseConfig} */ +/** + * This is intended to be a basic starting point for linting in the Blues Stack. + * It relies on recommended configs out of the box for simplicity, but you can + * and should modify this configuration to best suit your team's needs. + */ + +/** @type {import('eslint').Linter.Config} */ module.exports = { root: true, - extends: [ - "@remix-run/eslint-config", - "@remix-run/eslint-config/node", - "@remix-run/eslint-config/jest-testing-library", - "prettier", - ], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + ecmaFeatures: { + jsx: true, + }, + }, env: { - "cypress/globals": true, + browser: true, + commonjs: true, + es6: true, }, - plugins: ["cypress"], - // We're using vitest which has a very similar API to jest - // (so the linting plugins work nicely), but we have to - // set the jest version explicitly. - settings: { - jest: { - version: 28, + + // Base config + extends: ["eslint:recommended"], + + overrides: [ + // React + { + files: ["**/*.{js,jsx,ts,tsx}"], + plugins: ["react", "jsx-a11y"], + extends: [ + "plugin:react/recommended", + "plugin:react/jsx-runtime", + "plugin:jsx-a11y/recommended", + "prettier", + ], + settings: { + react: { + version: "detect", + }, + formComponents: ["Form"], + linkComponents: [ + { name: "Link", linkAttribute: "to" }, + { name: "NavLink", linkAttribute: "to" }, + ], + }, + rules: { + "react/jsx-no-leaked-render": [ + "warn", + { validStrategies: ["ternary"] }, + ], + }, }, - }, + + // Typescript + { + files: ["**/*.{ts,tsx}"], + plugins: ["@typescript-eslint", "import"], + parser: "@typescript-eslint/parser", + settings: { + "import/internal-regex": "^~/", + "import/resolver": { + node: { + extensions: [".ts", ".tsx"], + }, + typescript: { + alwaysTryTypes: true, + }, + }, + }, + extends: [ + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/stylistic", + "plugin:import/recommended", + "plugin:import/typescript", + "prettier", + ], + rules: { + "import/order": [ + "error", + { + alphabetize: { caseInsensitive: true, order: "asc" }, + groups: ["builtin", "external", "internal", "parent", "sibling"], + "newlines-between": "always", + }, + ], + }, + }, + + // Markdown + { + files: ["**/*.md"], + plugins: ["markdown"], + extends: ["plugin:markdown/recommended", "prettier"], + }, + + // Jest/Vitest + { + files: ["**/*.test.{js,jsx,ts,tsx}"], + plugins: ["jest", "jest-dom", "testing-library"], + extends: [ + "plugin:jest/recommended", + "plugin:jest-dom/recommended", + "plugin:testing-library/react", + "prettier", + ], + env: { + "jest/globals": true, + }, + settings: { + jest: { + // we're using vitest which has a very similar API to jest + // (so the linting plugins work nicely), but it means we have to explicitly + // set the jest version. + version: 28, + }, + }, + }, + + // Cypress + { + files: ["cypress/**/*.ts"], + plugins: ["cypress"], + extends: ["plugin:cypress/recommended", "prettier"], + }, + + // Node + { + files: [".eslintrc.js", "mocks/**/*.js"], + env: { + node: true, + }, + }, + ], }; diff --git a/.eslintrc.repo.js b/.eslintrc.repo.js deleted file mode 100644 index 67f48962..00000000 --- a/.eslintrc.repo.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env es6 */ -const OFF = 0; -const WARN = 1; -// const ERROR = 2; - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - extends: [ - "./.eslintrc.js", - "@remix-run/eslint-config/internal", - "plugin:markdown/recommended", - ], - plugins: ["markdown"], - settings: { - "import/internal-regex": "^~/", - }, - rules: { - "prefer-let/prefer-let": OFF, - "prefer-const": WARN, - - "import/order": [ - WARN, - { - alphabetize: { caseInsensitive: true, order: "asc" }, - groups: ["builtin", "external", "internal", "parent", "sibling"], - "newlines-between": "always", - }, - ], - - "react/jsx-no-leaked-render": [WARN, { validStrategies: ["ternary"] }], - }, -}; diff --git a/.github/workflows/lint-repo.yml b/.github/workflows/lint-repo.yml index 5ee6c4a0..9b9cd382 100644 --- a/.github/workflows/lint-repo.yml +++ b/.github/workflows/lint-repo.yml @@ -30,4 +30,4 @@ jobs: run: npm install - name: 🔬 Lint - run: npm run lint:repo + run: npm run lint diff --git a/app/models/user.server.ts b/app/models/user.server.ts index ffdc0cca..42be9b7f 100644 --- a/app/models/user.server.ts +++ b/app/models/user.server.ts @@ -56,6 +56,7 @@ export async function verifyLogin( return null; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { password: _password, ...userWithoutPassword } = userWithPassword; return userWithoutPassword; diff --git a/app/routes/join.tsx b/app/routes/join.tsx index 5b42ad04..f1ea5660 100644 --- a/app/routes/join.tsx +++ b/app/routes/join.tsx @@ -100,6 +100,7 @@ export default function Join() { ref={emailRef} id="email" required + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus={true} name="email" type="email" diff --git a/app/routes/login.tsx b/app/routes/login.tsx index aa6250e3..c61981c8 100644 --- a/app/routes/login.tsx +++ b/app/routes/login.tsx @@ -95,6 +95,7 @@ export default function LoginPage() { ref={emailRef} id="email" required + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus={true} name="email" type="email" @@ -160,7 +161,7 @@ export default function LoginPage() {