diff --git a/README.md b/README.md index 06ca4203..e89428ca 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,41 @@ There are two ways to get help or provide feedback (and we try to always respond ## Development Tools -For information about the development tools used to maintain derived projects (like opensaas.sh), see [tools/README.md](./tools/README.md). +### Code Quality Tools + +This repository includes comprehensive code quality tooling to help maintain code standards: + +#### Prettier (Code Formatting) +Prettier is configured for automatic code formatting across all JavaScript, TypeScript, and other supported files. + +```bash +# Check if files are formatted correctly +npm run prettier:check + +# Automatically format all files +npm run prettier:format +``` + +#### ESLint (Code Linting) +ESLint is configured with TypeScript and React support to catch potential bugs and enforce code quality standards. + +```bash +# Run ESLint to check for issues +npm run lint + +# Automatically fix fixable issues +npm run lint:fix +``` + +The ESLint configuration includes: +- TypeScript support with `@typescript-eslint` +- React and React Hooks linting +- Sensible defaults tuned for a SaaS application +- Automatic support for CommonJS (.cjs), ES Modules (.mjs), and TypeScript files + +Both Prettier and ESLint checks are automatically run in CI/CD pipelines to ensure code quality. + +For information about other development tools used to maintain derived projects (like opensaas.sh), see [tools/README.md](./tools/README.md). ## Contributing diff --git a/eslint.config.js b/eslint.config.js index b52cdbf9..6fab8a66 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,7 +1,7 @@ import js from "@eslint/js"; -import tseslint from "typescript-eslint"; import reactPlugin from "eslint-plugin-react"; import reactHooksPlugin from "eslint-plugin-react-hooks"; +import tseslint from "typescript-eslint"; export default tseslint.config( // Ignore patterns @@ -42,6 +42,9 @@ export default tseslint.config( "react/prop-types": "off", // Using TypeScript for type checking "react/no-unescaped-entities": "off", // Allow apostrophes in JSX "react/no-unknown-property": "off", // Allow custom properties (e.g., Alpine.js x-data) + "react-hooks/exhaustive-deps": "warn", // React hooks dependencies - warning instead of error + "react-hooks/set-state-in-effect": "warn", // Allow setState in effects (common pattern in this codebase) + "react/jsx-key": "error", // JSX key prop - keep as error since it's important }, }, @@ -55,6 +58,21 @@ export default tseslint.config( require: "readonly", __dirname: "readonly", __filename: "readonly", + process: "readonly", + console: "readonly", + }, + }, + }, + + // Node.js scripts and MJS files + { + files: ["**/*.mjs", "**/scripts/**/*.js"], + languageOptions: { + globals: { + process: "readonly", + console: "readonly", + __dirname: "readonly", + __filename: "readonly", }, }, }, @@ -79,6 +97,18 @@ export default tseslint.config( "@typescript-eslint/ban-ts-comment": "warn", // Don't enforce preference for const "prefer-const": "warn", + // Allow extra non-null assertions - warn instead of error + "@typescript-eslint/no-extra-non-null-assertion": "warn", + // Allow unused expressions (common in ternaries) + "@typescript-eslint/no-unused-expressions": "warn", + // Case declarations - warn instead of error + "no-case-declarations": "warn", + // Sparse arrays - warn instead of error + "no-sparse-arrays": "warn", + // Extra boolean cast - warn + "no-extra-boolean-cast": "warn", + // Prefer rest params - warn + "prefer-rest-params": "warn", }, }, ); diff --git a/package.json b/package.json index 16ae0238..384d4cc9 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,10 @@ "name": "wasp-repo", "type": "module", "scripts": { - "prettier:check": "prettier --ignore-unknown --check --config .prettierrc .", - "prettier:format": "prettier --ignore-unknown --write --config .prettierrc .", "lint": "eslint .", - "lint:fix": "eslint . --fix" + "lint:fix": "eslint . --fix", + "prettier:check": "prettier --ignore-unknown --check --config .prettierrc .", + "prettier:format": "prettier --ignore-unknown --write --config .prettierrc ." }, "devDependencies": { "@eslint/js": "^9.39.1", diff --git a/template/app/src/admin/dashboards/analytics/SourcesTable.tsx b/template/app/src/admin/dashboards/analytics/SourcesTable.tsx index 16f0084e..8d5c48b5 100644 --- a/template/app/src/admin/dashboards/analytics/SourcesTable.tsx +++ b/template/app/src/admin/dashboards/analytics/SourcesTable.tsx @@ -32,7 +32,10 @@ const SourcesTable = ({ {sources && sources.length > 0 ? ( sources.map((source) => ( -
{source.name}