From f62afbe79917cc9c766781fb169bc21e0129e1eb Mon Sep 17 00:00:00 2001 From: DeepDN Date: Mon, 3 Nov 2025 23:04:47 +0530 Subject: [PATCH] feat: upgrade typescript-eslint and node packages to latest versions - Upgrade @typescript-eslint/eslint-plugin from ^6.2.1 to ^8.14.0 - Upgrade @typescript-eslint/parser from ^6.2.1 to ^8.14.0 - Upgrade eslint from ^8.46.0 to ^9.14.0 - Migrate from legacy .eslintrc.js to flat config eslint.config.js - Update @types/node from ^20.4.6 to ^22.9.0 - Update typescript from ^5.1.6 to ^5.6.3 - Update prettier and related plugins to latest versions - Update Node.js engine requirement from >=18 to >=20 (LTS) - Add @eslint/js dependency for flat config support - Remove outdated eslint plugins no longer needed - Create migration guide documentation - Backup original .eslintrc.js configuration Resolves: #1478 Signed-off-by: DeepDN --- .eslintrc.js.backup | 104 ++++++++++++++++++++++++++++++++++++++++ ESLINT_MIGRATION.md | 62 ++++++++++++++++++++++++ eslint.config.js | 112 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 24 +++++----- 4 files changed, 289 insertions(+), 13 deletions(-) create mode 100644 .eslintrc.js.backup create mode 100644 ESLINT_MIGRATION.md create mode 100644 eslint.config.js diff --git a/.eslintrc.js.backup b/.eslintrc.js.backup new file mode 100644 index 000000000..6b733d326 --- /dev/null +++ b/.eslintrc.js.backup @@ -0,0 +1,104 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + sourceType: 'module' + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], + root: true, + env: { + node: true, + jest: true + }, + ignorePatterns: ['.eslintrc.js'], + rules: { + 'prettier/prettier': 0, + 'no-console': 'error', + // "@typescript-eslint/consistent-type-imports": "error", + '@typescript-eslint/no-unused-vars': [ + 'error' + // { + // "argsIgnorePattern": "_" + // } + ], + '@typescript-eslint/array-type': 'error', + 'template-curly-spacing': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'warn', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-use-before-define': 'error', + complexity: ['error', 50], + 'array-callback-return': 'error', + curly: 'error', + 'default-case': 'error', + 'default-case-last': 'error', + 'default-param-last': 'error', + camelcase: [2, { properties: 'always' }], + 'no-invalid-this': 'error', + 'no-return-assign': 'error', + 'no-unused-expressions': ['error', { allowTernary: true }], + 'no-useless-concat': 'error', + 'no-useless-return': 'error', + 'guard-for-in': 'error', + 'no-case-declarations': 'error', + 'no-implicit-coercion': 'error', + 'no-lone-blocks': 'error', + 'no-loop-func': 'error', + 'no-param-reassign': 'error', + 'no-return-await': 'error', + 'no-self-compare': 'error', + 'no-throw-literal': 'error', + 'no-useless-catch': 'error', + 'prefer-promise-reject-errors': 'error', + 'vars-on-top': 'error', + yoda: ['error', 'always'], + 'arrow-body-style': ['warn', 'as-needed'], + 'no-useless-rename': 'error', + 'prefer-destructuring': [ + 'error', + { + array: true, + object: true + }, + { + enforceForRenamedProperties: false + } + ], + 'prefer-numeric-literals': 'error', + 'prefer-rest-params': 'warn', + 'prefer-spread': 'error', + 'array-bracket-newline': ['error', { multiline: true, minItems: null }], + 'array-bracket-spacing': 'error', + 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + 'block-spacing': 'error', + 'comma-dangle': 'error', + 'comma-spacing': 'error', + 'comma-style': 'error', + 'computed-property-spacing': 'error', + 'func-call-spacing': 'error', + 'implicit-arrow-linebreak': ['error', 'beside'], + 'keyword-spacing': 'error', + 'multiline-ternary': ['error', 'always-multiline'], + 'no-mixed-operators': 'error', + 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1 }], + 'no-tabs': 'error', + 'no-unneeded-ternary': 'error', + 'no-whitespace-before-property': 'error', + 'nonblock-statement-body-position': ['error', 'below'], + 'object-property-newline': ['error', { allowAllPropertiesOnSameLine: true }], + semi: ['error', 'always'], + 'semi-spacing': 'error', + 'space-before-blocks': 'error', + 'space-in-parens': 'error', + 'space-infix-ops': 'error', + 'space-unary-ops': 'error', + 'arrow-spacing': 'error', + 'no-confusing-arrow': 'off', + 'no-var': 'error', + 'object-shorthand': 'error', + 'prefer-const': 'error', + 'prefer-template': 'error', + quotes: ['warn', 'single', { allowTemplateLiterals: true }] + } +}; diff --git a/ESLINT_MIGRATION.md b/ESLINT_MIGRATION.md new file mode 100644 index 000000000..50a791bb1 --- /dev/null +++ b/ESLINT_MIGRATION.md @@ -0,0 +1,62 @@ +# ESLint Migration Guide + +## Changes Made + +This migration upgrades the project from ESLint v8 with legacy configuration to ESLint v9 with flat configuration format. + +### Package Updates + +- `@typescript-eslint/eslint-plugin`: `^6.2.1` → `^8.14.0` +- `@typescript-eslint/parser`: `^6.2.1` → `^8.14.0` +- `eslint`: `^8.46.0` → `^9.14.0` +- `@types/node`: `^20.4.6` → `^22.9.0` +- `typescript`: `^5.1.6` → `^5.6.3` +- `prettier`: `^3.0.1` → `^3.3.3` +- `eslint-config-prettier`: `^8.10.0` → `^9.1.0` +- `eslint-plugin-prettier`: `^4.2.1` → `^5.2.1` +- `eslint-plugin-promise`: `^6.1.1` → `^7.1.0` + +### New Dependencies + +- `@eslint/js`: `^9.14.0` (required for flat config) + +### Removed Dependencies + +- `eslint-config-standard-with-typescript`: No longer needed with flat config +- `eslint-plugin-import`: Functionality integrated into core ESLint +- `eslint-plugin-n`: Not required for this project setup + +### Configuration Changes + +- **Old**: `.eslintrc.js` (legacy format) +- **New**: `eslint.config.js` (flat config format) + +The new configuration maintains all existing rules while using the modern flat config structure. + +### Node.js Version + +- Updated minimum Node.js version from `>=18` to `>=20` (current LTS) + +## Migration Steps for Developers + +1. Install dependencies: `pnpm install` +2. The old `.eslintrc.js` is backed up as `.eslintrc.js.backup` +3. ESLint now uses `eslint.config.js` for configuration +4. All existing lint rules are preserved + +## Verification + +Run the following commands to verify the migration: + +```bash +# Check ESLint configuration +pnpm lint + +# Run tests to ensure no breaking changes +pnpm test +``` + +## References + +- [ESLint Migration Guide](https://eslint.org/docs/latest/use/configure/migration-guide) +- [TypeScript ESLint v8 Migration](https://typescript-eslint.io/blog/announcing-typescript-eslint-v8-beta/) diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..daf0b9cce --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,112 @@ +import js from '@eslint/js'; +import tseslint from '@typescript-eslint/eslint-plugin'; +import tsparser from '@typescript-eslint/parser'; +import prettier from 'eslint-plugin-prettier'; + +export default [ + js.configs.recommended, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parser: tsparser, + parserOptions: { + project: './tsconfig.json', + sourceType: 'module', + }, + globals: { + node: true, + jest: true, + }, + }, + plugins: { + '@typescript-eslint': tseslint, + prettier: prettier, + }, + rules: { + 'prettier/prettier': 0, + 'no-console': 'error', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/array-type': 'error', + 'template-curly-spacing': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'warn', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-use-before-define': 'error', + complexity: ['error', 50], + 'array-callback-return': 'error', + curly: 'error', + 'default-case': 'error', + 'default-case-last': 'error', + 'default-param-last': 'error', + camelcase: [2, { properties: 'always' }], + 'no-invalid-this': 'error', + 'no-return-assign': 'error', + 'no-unused-expressions': ['error', { allowTernary: true }], + 'no-useless-concat': 'error', + 'no-useless-return': 'error', + 'guard-for-in': 'error', + 'no-case-declarations': 'error', + 'no-implicit-coercion': 'error', + 'no-lone-blocks': 'error', + 'no-loop-func': 'error', + 'no-param-reassign': 'error', + 'no-return-await': 'error', + 'no-self-compare': 'error', + 'no-throw-literal': 'error', + 'no-useless-catch': 'error', + 'prefer-promise-reject-errors': 'error', + 'vars-on-top': 'error', + yoda: ['error', 'always'], + 'arrow-body-style': ['warn', 'as-needed'], + 'no-useless-rename': 'error', + 'prefer-destructuring': [ + 'error', + { + array: true, + object: true, + }, + { + enforceForRenamedProperties: false, + }, + ], + 'prefer-numeric-literals': 'error', + 'prefer-rest-params': 'warn', + 'prefer-spread': 'error', + 'array-bracket-newline': ['error', { multiline: true, minItems: null }], + 'array-bracket-spacing': 'error', + 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + 'block-spacing': 'error', + 'comma-dangle': 'error', + 'comma-spacing': 'error', + 'comma-style': 'error', + 'computed-property-spacing': 'error', + 'func-call-spacing': 'error', + 'implicit-arrow-linebreak': ['error', 'beside'], + 'keyword-spacing': 'error', + 'multiline-ternary': ['error', 'always-multiline'], + 'no-mixed-operators': 'error', + 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1 }], + 'no-tabs': 'error', + 'no-unneeded-ternary': 'error', + 'no-whitespace-before-property': 'error', + 'nonblock-statement-body-position': ['error', 'below'], + 'object-property-newline': ['error', { allowAllPropertiesOnSameLine: true }], + semi: ['error', 'always'], + 'semi-spacing': 'error', + 'space-before-blocks': 'error', + 'space-in-parens': 'error', + 'space-infix-ops': 'error', + 'space-unary-ops': 'error', + 'arrow-spacing': 'error', + 'no-confusing-arrow': 'off', + 'no-var': 'error', + 'object-shorthand': 'error', + 'prefer-const': 'error', + 'prefer-template': 'error', + quotes: ['warn', 'single', { allowTemplateLiterals: true }], + }, + }, + { + ignores: ['.eslintrc.js', 'dist/**', 'node_modules/**'], + }, +]; diff --git a/package.json b/package.json index 581578a6c..aa6fd8396 100644 --- a/package.json +++ b/package.json @@ -125,36 +125,34 @@ "xml-js": "^1.6.11" }, "devDependencies": { + "@eslint/js": "^9.14.0", "@nestjs/cli": "catalog:", "@nestjs/schematics": "catalog:", "@nestjs/testing": "catalog:", "@types/express": "^4.17.17", "@types/jest": "^29.5.3", "@types/multer": "^1.4.9", - "@types/node": "^20.4.6", + "@types/node": "^22.9.0", "@types/passport-jwt": "3.0.9", "@types/passport-local": "^1.0.35", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^6.2.1", - "@typescript-eslint/parser": "^6.2.1", - "eslint": "^8.46.0", - "eslint-config-prettier": "^8.10.0", - "eslint-config-standard-with-typescript": "^37.0.0", - "eslint-plugin-import": "^2.28.0", - "eslint-plugin-n": "^15.7.0", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-promise": "^6.1.1", + "@typescript-eslint/eslint-plugin": "^8.14.0", + "@typescript-eslint/parser": "^8.14.0", + "eslint": "^9.14.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-promise": "^7.1.0", "husky": "^8.0.3", "jest": "^29.6.2", "lint-staged": "^13.2.3", - "prettier": "^3.0.1", + "prettier": "^3.3.3", "prisma": "^5.1.1", "supertest": "^6.3.3", "ts-jest": "^29.1.1", "ts-loader": "^9.4.4", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", - "typescript": "^5.1.6" + "typescript": "^5.6.3" }, "lint-staged": { "**/*.{js,ts}": [ @@ -204,6 +202,6 @@ }, "packageManager": "pnpm@9.15.3+sha512.1f79bc245a66eb0b07c5d4d83131240774642caaa86ef7d0434ab47c0d16f66b04e21e0c086eb61e62c77efc4d7f7ec071afad3796af64892fae66509173893a", "engines": { - "node": ">=18" + "node": ">=20" } }