eslint.config.mjs•6.26 kB
import { defineConfig, globalIgnores } from "eslint/config";
import tsParser from "@typescript-eslint/parser";
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import reactHooks from "eslint-plugin-react-hooks";
import react from "eslint-plugin-react";
import jest from "eslint-plugin-jest";
import { fixupPluginRules } from "@eslint/compat";
import globals from "globals";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default defineConfig([
{
languageOptions: {
parser: tsParser,
globals: {
...globals.amd,
...globals.browser,
...globals.jest,
...globals.node,
},
},
plugins: {
"@typescript-eslint": typescriptEslint,
"react-hooks": fixupPluginRules(reactHooks),
react,
jest,
},
extends: compat.extends(
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
"plugin:jest/recommended",
),
rules: {
// any is terrible but we use it a lot (even in our public code).
"@typescript-eslint/no-explicit-any": "off",
// asserting that values aren't null is risky but useful.
"@typescript-eslint/no-non-null-assertion": "off",
// Add React hooks rules so we don't misuse them.
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
eqeqeq: ["error", "always"],
// In uncompiled demos we need to demonstrate `require` syntax
"@typescript-eslint/no-var-requires": "off",
// allow (_arg: number) => {}
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
"jest/expect-expect": "off",
"jest/no-conditional-expect": "off",
},
},
{
rules: {
"no-console": "error",
},
basePath: path.join(__dirname, "..", ".."),
ignores: [
"**/dont-publish-alpha-as-latest.mjs",
"**/version-check.mjs",
"npm-packages-private/data/**",
"npm-packages-private/postalservice/**",
"npm-packages/@convex-dev/codemod/**",
"npm-packages/component-tests/**",
"npm-packages/convex-analytics/**",
"npm-packages/convex-chat-speculative/**",
"npm-packages/demos/**",
"npm-packages/docs/**",
"npm-packages/js-integration-tests/**",
"npm-packages/local-store/**",
"npm-packages/node-executor/**",
"npm-packages/private-demos/**",
"npm-packages/publishing-tests/**",
"npm-packages/retention-tester/**",
"npm-packages/scenario-runner/**",
"npm-packages/shared-cursors/**",
"npm-packages/simulation/**",
"npm-packages/text-importer/**",
"npm-packages/udf-runtime/**",
"npm-packages/udf-tests/**",
"npm-packages/version/**",
],
},
{
files: ["**/*.js", "**/*.cjs"],
rules: {
"@typescript-eslint/no-require-imports": "off",
},
},
...["js-integration-tests", "scenario-runner/convex", "udf-tests/convex"].map(
(pkg) => ({
files: [path.join(pkg, "**/*.ts"), path.join(pkg, "**/*.tsx")],
rules: {
"@typescript-eslint/no-floating-promises": "error",
},
languageOptions: {
parserOptions: {
project: path.join(__dirname, "..", pkg, "tsconfig.json"),
},
},
}),
),
globalIgnores([
"**/.next/**",
"**/.nuxt/**",
"**/node_modules",
"**/dist",
"**/.next",
"**/.nuxt",
"**/build",
"common/deploy",
"common/scripts",
"common/temp",
"convex", // has a similar config, separate so vscode can find it
"@convex-dev/react-query", // separate because OSS
"@convex-dev/eslint-plugin", // has its own config using different dependencies
"@convex-dev/design-system", // has its own config using different dependencies
"dashboard", // has its own config using different dependencies
"dashboard-common", // has its own config using different dependencies
"dashboard-self-hosted", // has its own config using different dependencies
"dashboard-storybook", // has its own config using different dependencies
"docs/.docusaurus", // auto-generated by Docusaurus
"system-udfs/convex", // has its own config using different dependencies
"demos/nextjs-pages-router", // has its own config using different dependencies
"demos/nextjs-app-router", // has its own config using different dependencies
"private-demos/react-native", // has its own config using different dependencies
"private-demos/actions", // has its own ESLint
"private-demos/npm-showcase", // has its own ESLint and `"@typescript-eslint"`
"private-demos/quickstarts/nodejs/script.js", // uses require
"private-demos/quickstarts/nextjs-app-dir", // should match Next.js quickstart
"private-demos/quickstarts/nextjs-app-dir-14", // should match Next.js quickstart
"private-demos/nextjs-app-router-snippets", // should match Next.js quickstart
"private-demos/nextjs-15-app", // should match Next.js quickstart
"private-demos/nextjs-15-app-clerk", // should match Next.js quickstart
"private-demos/quickstarts/sveltekit", // sveltekit linting is annoying to set up
"private-demos/quickstarts/remix", // won't have these deps installed
"private-demos/quickstarts/vue", // won't have these deps installed
"private-demos/snippets", // has its own config
"private-demos/tanstack-start", // has its own config
"private-demos/tanstack-start-clerk", // has its own config
"private-demos/tutorial/src/App.tsx", // tutorial warning will go away once user does tutorial
"demos/html/script.js", // uses js-doc
"demos/html/browser.bundle.js", // just until we can link to a CDN for this
"create-convex/template-*",
"convex-ai-chat/esm",
"convex-ai-chat/cjs",
"**/_generated/**", // auto-generated files
]),
]);