From 0e5c9aaed6e447eb7fa891dc32f8b2f973c0d4ca Mon Sep 17 00:00:00 2001 From: Matsu Date: Tue, 29 Sep 2026 11:42:22 +0000 Subject: [PATCH] chore: Migrate backend tooling lint to Oxlint (no-changelog) (#39825) --- .../@n8n/backend-test-utils/oxlint.config.mts | 7 +++ packages/@n8n/backend-test-utils/package.json | 7 ++- packages/@n8n/benchmark/oxlint.config.mts | 11 +++++ packages/@n8n/benchmark/package.json | 7 ++- packages/@n8n/cli/oxlint.config.mts | 7 +++ packages/@n8n/cli/package.json | 7 ++- packages/@n8n/mcp-browser/oxlint.config.mts | 7 +++ packages/@n8n/mcp-browser/package.json | 7 ++- .../testing/test-impact/oxlint.config.mts | 8 ++++ packages/testing/test-impact/package.json | 7 ++- pnpm-lock.yaml | 45 +++++++++++++++++++ .../lint-parity/OXLINT_MIGRATION_BLOCKERS.md | 10 ++++- turbo.json | 15 +++++++ 13 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 packages/@n8n/backend-test-utils/oxlint.config.mts create mode 100644 packages/@n8n/benchmark/oxlint.config.mts create mode 100644 packages/@n8n/cli/oxlint.config.mts create mode 100644 packages/@n8n/mcp-browser/oxlint.config.mts create mode 100644 packages/testing/test-impact/oxlint.config.mts diff --git a/packages/@n8n/backend-test-utils/oxlint.config.mts b/packages/@n8n/backend-test-utils/oxlint.config.mts new file mode 100644 index 00000000000..b50c92512db --- /dev/null +++ b/packages/@n8n/backend-test-utils/oxlint.config.mts @@ -0,0 +1,7 @@ +import { backendConfig } from '@n8n/oxlint-config/backend'; +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + extends: [backendConfig], + options: { typeAware: true }, +}); diff --git a/packages/@n8n/backend-test-utils/package.json b/packages/@n8n/backend-test-utils/package.json index 2f66d27ee29..2d5eac6d51d 100644 --- a/packages/@n8n/backend-test-utils/package.json +++ b/packages/@n8n/backend-test-utils/package.json @@ -9,8 +9,8 @@ "build:unchecked": "tsc -p tsconfig.build.json --noCheck", "format": "biome format --write .", "format:check": "biome ci .", - "lint": "eslint . --quiet", - "lint:fix": "eslint . --fix", + "lint": "oxlint --quiet", + "lint:fix": "oxlint --fix", "watch": "tsc -p tsconfig.build.json --watch", "test": "node -e \"process.exit(0)\"", "test:dev": "echo \"WARNING: no test specified\" && exit 0" @@ -36,7 +36,10 @@ }, "devDependencies": { "@n8n/eslint-config": "workspace:*", + "@n8n/oxlint-config": "workspace:*", "@n8n/typescript-config": "workspace:*", + "oxlint": "catalog:", + "oxlint-tsgolint": "catalog:", "typescript": "catalog:typescript" }, "license": "LicenseRef-n8n-sustainable-use" diff --git a/packages/@n8n/benchmark/oxlint.config.mts b/packages/@n8n/benchmark/oxlint.config.mts new file mode 100644 index 00000000000..642d077122b --- /dev/null +++ b/packages/@n8n/benchmark/oxlint.config.mts @@ -0,0 +1,11 @@ +import { backendConfig } from '@n8n/oxlint-config/backend'; +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + extends: [backendConfig], + options: { typeAware: true }, + ignorePatterns: ['scenarios/**', 'scripts/**'], + rules: { + complexity: 'error', + }, +}); diff --git a/packages/@n8n/benchmark/package.json b/packages/@n8n/benchmark/package.json index e5707c421e4..d3b71a150ca 100644 --- a/packages/@n8n/benchmark/package.json +++ b/packages/@n8n/benchmark/package.json @@ -9,8 +9,8 @@ "build:unchecked": "tsc -p tsconfig.build.json --noCheck && tsc-alias -p tsconfig.build.json", "format": "biome format --write .", "format:check": "biome ci .", - "lint": "eslint . --quiet", - "lint:fix": "eslint . --fix", + "lint": "oxlint --quiet", + "lint:fix": "oxlint --fix", "start": "./bin/n8n-benchmark", "test": "node -e \"process.exit(0)\"", "typecheck": "tsc --noEmit", @@ -41,8 +41,11 @@ "zx": "^8.8.5" }, "devDependencies": { + "@n8n/oxlint-config": "workspace:*", "@n8n/typescript-config": "workspace:*", "@types/k6": "^0.52.0", + "oxlint": "catalog:", + "oxlint-tsgolint": "catalog:", "typescript": "catalog:typescript" }, "bin": { diff --git a/packages/@n8n/cli/oxlint.config.mts b/packages/@n8n/cli/oxlint.config.mts new file mode 100644 index 00000000000..b50c92512db --- /dev/null +++ b/packages/@n8n/cli/oxlint.config.mts @@ -0,0 +1,7 @@ +import { backendConfig } from '@n8n/oxlint-config/backend'; +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + extends: [backendConfig], + options: { typeAware: true }, +}); diff --git a/packages/@n8n/cli/package.json b/packages/@n8n/cli/package.json index 7d666edcdc8..48d644cfee5 100644 --- a/packages/@n8n/cli/package.json +++ b/packages/@n8n/cli/package.json @@ -21,8 +21,8 @@ "build:unchecked": "tsc -p tsconfig.build.json --noCheck", "format": "biome format --write .", "format:check": "biome ci .", - "lint": "eslint src --quiet", - "lint:fix": "eslint src --fix", + "lint": "oxlint src --quiet", + "lint:fix": "oxlint src --fix", "watch": "tsc -p tsconfig.build.json --watch", "test": "vitest run", "test:unit": "vitest run" @@ -84,9 +84,12 @@ "@oclif/core": "^4.5.2" }, "devDependencies": { + "@n8n/oxlint-config": "workspace:*", "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@types/node": "catalog:", + "oxlint": "catalog:", + "oxlint-tsgolint": "catalog:", "typescript": "catalog:typescript", "vitest": "catalog:" } diff --git a/packages/@n8n/mcp-browser/oxlint.config.mts b/packages/@n8n/mcp-browser/oxlint.config.mts new file mode 100644 index 00000000000..b50c92512db --- /dev/null +++ b/packages/@n8n/mcp-browser/oxlint.config.mts @@ -0,0 +1,7 @@ +import { backendConfig } from '@n8n/oxlint-config/backend'; +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + extends: [backendConfig], + options: { typeAware: true }, +}); diff --git a/packages/@n8n/mcp-browser/package.json b/packages/@n8n/mcp-browser/package.json index cec9b6ea227..54e3c1aa016 100644 --- a/packages/@n8n/mcp-browser/package.json +++ b/packages/@n8n/mcp-browser/package.json @@ -16,8 +16,8 @@ "build:unchecked": "tsc -p tsconfig.build.json --noCheck", "format": "biome format --write src", "format:check": "biome ci src", - "lint": "eslint . --quiet", - "lint:fix": "eslint . --fix", + "lint": "oxlint --quiet", + "lint:fix": "oxlint --fix", "watch": "tsc -p tsconfig.build.json --watch", "test": "vitest run", "test:unit": "vitest run", @@ -38,6 +38,7 @@ "zod": "catalog:" }, "devDependencies": { + "@n8n/oxlint-config": "workspace:*", "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", "@types/jsdom": "catalog:", @@ -45,6 +46,8 @@ "@types/ws": "catalog:", "@types/yargs-parser": "21.0.0", "@vitest/coverage-v8": "catalog:", + "oxlint": "catalog:", + "oxlint-tsgolint": "catalog:", "typescript": "catalog:typescript", "tsx": "catalog:", "vitest": "catalog:" diff --git a/packages/testing/test-impact/oxlint.config.mts b/packages/testing/test-impact/oxlint.config.mts new file mode 100644 index 00000000000..56848d01b6a --- /dev/null +++ b/packages/testing/test-impact/oxlint.config.mts @@ -0,0 +1,8 @@ +import { backendConfig } from '@n8n/oxlint-config/backend'; +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + extends: [backendConfig], + options: { typeAware: true }, + ignorePatterns: ['dist/**', 'coverage/**'], +}); diff --git a/packages/testing/test-impact/package.json b/packages/testing/test-impact/package.json index 743aa09ad0a..66c350dbf97 100644 --- a/packages/testing/test-impact/package.json +++ b/packages/testing/test-impact/package.json @@ -25,8 +25,8 @@ "test:coverage": "vitest run --coverage", "format": "biome format --write .", "format:check": "biome ci .", - "lint": "eslint . --quiet", - "lint:fix": "eslint . --fix", + "lint": "oxlint --quiet", + "lint:fix": "oxlint --fix", "typecheck": "tsc --noEmit" }, "keywords": [ @@ -41,9 +41,12 @@ "monocart-coverage-reports": "^2.12.0" }, "devDependencies": { + "@n8n/oxlint-config": "workspace:*", "@types/node": "catalog:", "@vitest/coverage-v8": "catalog:", "fast-check": "catalog:", + "oxlint": "catalog:", + "oxlint-tsgolint": "catalog:", "typescript": "catalog:typescript", "vitest": "catalog:" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3104057634d..46e3cb62faa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1854,9 +1854,18 @@ importers: '@n8n/eslint-config': specifier: workspace:* version: link:../eslint-config + '@n8n/oxlint-config': + specifier: workspace:* + version: link:../oxlint-config '@n8n/typescript-config': specifier: workspace:* version: link:../typescript-config + oxlint: + specifier: 'catalog:' + version: 1.78.0(oxlint-tsgolint@0.21.1) + oxlint-tsgolint: + specifier: 'catalog:' + version: 0.21.1 typescript: specifier: catalog:typescript version: 7.0.2 @@ -1876,12 +1885,21 @@ importers: specifier: ^8.8.5 version: 8.8.5 devDependencies: + '@n8n/oxlint-config': + specifier: workspace:* + version: link:../oxlint-config '@n8n/typescript-config': specifier: workspace:* version: link:../typescript-config '@types/k6': specifier: ^0.52.0 version: 0.52.0 + oxlint: + specifier: 'catalog:' + version: 1.78.0(oxlint-tsgolint@0.21.1) + oxlint-tsgolint: + specifier: 'catalog:' + version: 0.21.1 typescript: specifier: catalog:typescript version: 7.0.2 @@ -1981,6 +1999,9 @@ importers: specifier: ^4.5.2 version: 4.5.2 devDependencies: + '@n8n/oxlint-config': + specifier: workspace:* + version: link:../oxlint-config '@n8n/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -1990,6 +2011,12 @@ importers: '@types/node': specifier: ^20.17.50 version: 20.19.41 + oxlint: + specifier: 'catalog:' + version: 1.78.0(oxlint-tsgolint@0.21.1) + oxlint-tsgolint: + specifier: 'catalog:' + version: 0.21.1 typescript: specifier: catalog:typescript version: 7.0.2 @@ -3276,6 +3303,9 @@ importers: specifier: 3.25.76 version: 3.25.76 devDependencies: + '@n8n/oxlint-config': + specifier: workspace:* + version: link:../oxlint-config '@n8n/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -3297,6 +3327,12 @@ importers: '@vitest/coverage-v8': specifier: 'catalog:' version: 5.0.1(@vitest/browser@5.0.1)(vitest@5.0.1) + oxlint: + specifier: 'catalog:' + version: 1.78.0(oxlint-tsgolint@0.21.1) + oxlint-tsgolint: + specifier: 'catalog:' + version: 0.21.1 tsx: specifier: 'catalog:' version: 4.19.3 @@ -7887,6 +7923,9 @@ importers: specifier: ^2.12.0 version: 2.12.12 devDependencies: + '@n8n/oxlint-config': + specifier: workspace:* + version: link:../../@n8n/oxlint-config '@types/node': specifier: ^20.17.50 version: 20.19.41 @@ -7896,6 +7935,12 @@ importers: fast-check: specifier: 'catalog:' version: 3.23.2 + oxlint: + specifier: 'catalog:' + version: 1.78.0(oxlint-tsgolint@0.21.1) + oxlint-tsgolint: + specifier: 'catalog:' + version: 0.21.1 typescript: specifier: catalog:typescript version: 7.0.2 diff --git a/scripts/lint-parity/OXLINT_MIGRATION_BLOCKERS.md b/scripts/lint-parity/OXLINT_MIGRATION_BLOCKERS.md index 58e04e715a7..93e01efe22a 100644 --- a/scripts/lint-parity/OXLINT_MIGRATION_BLOCKERS.md +++ b/scripts/lint-parity/OXLINT_MIGRATION_BLOCKERS.md @@ -26,7 +26,7 @@ These rules come from the shared base or backend layers. Resolve these first bec | P2 | `import/export` | A native rule exists, but it is still in the nursery category. | Run parity samples and enable it after it becomes stable. | | P3 | `no-octal` | Oxlint has no rule. The parser already rejects relevant octal syntax in module and strict-mode code. | Confirm parser coverage and retire the explicit rule if no supported source form remains. | -## Package-level typed blocker +## Package-level blockers ### `@typescript-eslint/naming-convention` @@ -41,6 +41,14 @@ Possible approaches: Audit every package configuration before conversion. Do not copy the full generic naming rule into a new custom implementation. +## Retirement exceptions + +### `n8n-node-dev` + +Keep `n8n-node-dev` on ESLint. The v3 removal plan makes an Oxlint migration unnecessary. + +Reconsider this exception only if the package removal plan changes. + ## Frontend package blockers Oxlint can lint the script section of a Vue SFC, but it does not expose the Vue template AST. An Oxlint-only frontend package would lose the following 59 rules: diff --git a/turbo.json b/turbo.json index 2afed4031e2..f017d91b49f 100644 --- a/turbo.json +++ b/turbo.json @@ -68,6 +68,12 @@ "@n8n/backend-services#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] }, + "@n8n/backend-test-utils#lint": { + "dependsOn": ["^build", "@n8n/oxlint-config#build"] + }, + "@n8n/cli#lint": { + "dependsOn": ["^build", "@n8n/oxlint-config#build"] + }, "@n8n/client-oauth2#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] }, @@ -95,12 +101,21 @@ "@n8n/local-gateway#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] }, + "@n8n/mcp-browser#lint": { + "dependsOn": ["^build", "@n8n/oxlint-config#build"] + }, + "@n8n/n8n-benchmark#lint": { + "dependsOn": ["^build", "@n8n/oxlint-config#build"] + }, "@n8n/scheduler#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] }, "@n8n/syslog-client#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] }, + "@n8n/test-impact#lint": { + "dependsOn": ["^build", "@n8n/oxlint-config#build"] + }, "n8n#lint": { "dependsOn": ["^build", "@n8n/oxlint-config#build"] },