diff --git a/.changeset/add-eslint-configuration.md b/.changeset/add-eslint-configuration.md new file mode 100644 index 00000000..bfc0fc19 --- /dev/null +++ b/.changeset/add-eslint-configuration.md @@ -0,0 +1,12 @@ +--- +--- + +Add ESLint configuration for code quality and consistency + +Adds repository-wide ESLint configuration to catch common code quality issues. This is a development-only change that adds linting tooling without affecting any package functionality or APIs. + +**Configuration includes:** +- TypeScript-specific rules for type safety and promise handling +- Basic JavaScript rules for code consistency +- Lenient rules for test files +- Integration with lint-staged for pre-commit linting diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..135c3704 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,93 @@ +module.exports = { + root: true, + env: { + node: true, + es6: true, + }, + plugins: ['@typescript-eslint', 'jest'], + extends: ['eslint:recommended', 'plugin:jest/recommended'], + rules: { + // Best practices + 'no-console': 'off', // CLI tool, console is expected + 'prefer-const': 'error', + 'no-var': 'error', + + // Jest best practices + 'jest/expect-expect': 'warn', + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + }, + overrides: [ + { + // TypeScript files with type checking + files: ['**/*.ts', '**/*.tsx'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + project: ['./tsconfig.base.json', './packages/*/tsconfig.json'], + tsconfigRootDir: __dirname, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:jest/recommended', + ], + rules: { + // Catch implicit any (would catch Issue #1) + '@typescript-eslint/no-explicit-any': 'warn', // Warn, not error (any is sometimes needed) + '@typescript-eslint/no-unsafe-assignment': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + '@typescript-eslint/no-unsafe-call': 'warn', + + // Catch promise issues + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-misused-promises': 'error', + + // General code quality + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + + // Best practices + 'no-console': 'off', + 'prefer-const': 'error', + 'no-var': 'error', + + // Jest best practices + 'jest/expect-expect': 'warn', + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + }, + }, + { + // More lenient rules for test files + files: ['**/__tests__/**', '**/*.test.ts', '**/*.test.js'], + env: { + jest: true, + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + }, + }, + ], + ignorePatterns: [ + 'node_modules/', + 'dist/', + 'build/', + 'coverage/', + '*.config.js', + '.eslintrc.js', + 'jest.config.js', + 'jest.config.base.js', + '.changeset/', + ], +}; diff --git a/package.json b/package.json index dcd4a4e7..b5908fb1 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "docs": "npm run docs --workspaces --if-present", "prepare": "husky install", "pre-commit": "lint-staged", - "reset": "npm exec --workspaces -- npx rimraf node_modules && npx rimraf node_modules" + "reset": "npm exec --workspaces -- npx rimraf node_modules && npx rimraf node_modules", + "lint": "eslint . --ext .ts,.js,.tsx,.jsx", + "lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix" }, "devDependencies": { "@changesets/changelog-github": "^0.4.8", @@ -28,11 +30,15 @@ "@commitlint/config-conventional": "^19.1.0", "@twilio/test-dep": "npm:twilio@4.22.0", "@types/jest": "^29.2.4", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "all-contributors-cli": "^6.1.2", "commitizen": "^4.2.4", "commitlint-plugin-workspace-scopes": "^1.1.0", "conventional-changelog-cli": "^2.1.0", "cz-conventional-changelog": "^2.1.0", + "eslint": "^8.57.1", + "eslint-plugin-jest": "^27.9.0", "husky": "^8.0.2", "jest": "^29.7.0", "jest-express": "^1.10.1", @@ -47,6 +53,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ + "eslint --fix", "prettier --write", "git add" ]