ci: Setup eslint-import-resolver-typescript for improved TS linting (#4996)

* Setup stricter linting for typescript

* make `import/no-unresolved` an error everywhere

* use prettier to format `.vscode/settings.default.json`

* address PR comments
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2022-12-22 09:55:39 +01:00 committed by GitHub
parent 9568b747c7
commit 17f13b3b6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 181 additions and 58 deletions

View file

@ -6,6 +6,13 @@
"dist": true,
"pnpm-lock.yaml": true
},
"typescript.format.enable": false,
"typescript.tsdk": "node_modules/typescript/lib",
"workspace-default-settings.runOnActivation": true
"workspace-default-settings.runOnActivation": true,
"eslint.probe": ["javascript", "typescript", "vue"],
"eslint.workingDirectories": [
{
"mode": "auto"
}
]
}

View file

@ -66,7 +66,8 @@
"browserslist": "^4.21.4",
"ejs": "^3.1.8",
"fork-ts-checker-webpack-plugin": "^6.0.4",
"globby": "^11.1.0"
"cpy@8>globby": "^11.1.0",
"qqjs>globby": "^11.1.0"
}
}
}

View file

@ -2,12 +2,6 @@
* @type {import('@types/eslint').ESLint.ConfigData}
*/
const config = (module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'module',
project: ['./tsconfig.json'],
},
ignorePatterns: [
'node_modules/**',
'dist/**',
@ -318,11 +312,21 @@ const config = (module.exports = {
// eslint-plugin-import
// ----------------------------------
/**
* https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md
*/
'import/no-cycle': 'error',
/**
* https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-default-export.md
*/
'import/no-default-export': 'error',
/**
* https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md
*/
'import/no-unresolved': 'error',
/**
* https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/order.md
*/

View file

@ -12,16 +12,6 @@ module.exports = {
node: true,
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: {
ts: '@typescript-eslint/parser',
js: '@typescript-eslint/parser',
vue: 'vue-eslint-parser',
template: 'vue-eslint-parser',
},
},
ignorePatterns: ['**/*.js', '**/*.d.ts', 'vite.config.ts', '**/*.ts.snap'],
rules: {

View file

@ -10,6 +10,7 @@
"eslint": "~8.28",
"eslint-config-airbnb-typescript": "~17.0",
"eslint-config-prettier": "~8.5",
"eslint-import-resolver-typescript": "~3.5",
"eslint-plugin-diff": "~2.0",
"eslint-plugin-import": "~2.26",
"eslint-plugin-n8n-local-rules": "~1.0",

View file

@ -0,0 +1,41 @@
/**
* @type {(dir: string, mode: 'frontend' | undefined) => import('@types/eslint').ESLint.ConfigData}
*/
exports.sharedOptions = (tsconfigRootDir, mode) => {
const isFrontend = mode === 'frontend';
const parser = isFrontend ? 'vue-eslint-parser' : '@typescript-eslint/parser';
const extraParserOptions = isFrontend
? {
extraFileExtensions: ['.vue'],
parser: {
ts: '@typescript-eslint/parser',
js: '@typescript-eslint/parser',
vue: 'vue-eslint-parser',
template: 'vue-eslint-parser',
},
}
: {};
const settings = {
'import/parsers': {
'@typescript-eslint/parser': isFrontend ? ['.ts', '.vue'] : ['.ts'],
},
'import/resolver': {
typescript: {
tsconfigRootDir,
project: './tsconfig.json',
},
},
};
return {
parser,
parserOptions: {
tsconfigRootDir,
project: ['./tsconfig.json'],
...extraParserOptions,
},
settings,
};
};

View file

@ -1,13 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/node'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
...sharedOptions(__dirname),
ignorePatterns: [
'jest.config.js',
@ -15,8 +14,10 @@ module.exports = {
'src/databases/migrations/**',
'src/databases/ormconfig.ts',
],
rules: {
// TODO: Remove this
'import/no-cycle': 'warn',
'import/order': 'off',
'import/extensions': 'off',
'@typescript-eslint/ban-ts-comment': ['warn', { 'ts-ignore': true }],

View file

@ -1,13 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/node'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
...sharedOptions(__dirname),
ignorePatterns: ['bin/*.js'],

View file

@ -1,14 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/frontend'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
extraFileExtensions: ['.vue'],
},
...sharedOptions(__dirname, 'frontend'),
rules: {
// TODO: Remove these

View file

@ -1,14 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/frontend'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
extraFileExtensions: ['.vue'],
},
...sharedOptions(__dirname, 'frontend'),
ignorePatterns: ['*.d.cts'],
@ -19,6 +17,7 @@ module.exports = {
'import/no-default-export': 'off',
'import/no-extraneous-dependencies': 'off',
'import/order': 'off',
'import/no-cycle': 'warn',
indent: 'off',
'prettier/prettier': 'off',
'@typescript-eslint/ban-types': 'off',

View file

@ -41,7 +41,7 @@ import {
import { FAKE_DOOR_FEATURES } from './constants';
import { BulkCommand, Undoable } from '@/models/history';
export * from 'n8n-design-system/src/types';
export * from 'n8n-design-system/types';
declare module 'jsplumb' {
interface PaintStyle {

View file

@ -1,4 +1,4 @@
import { IExecutionResponse, IExecutionsCurrentSummaryExtended, IPushData } from '../../Interface';
import { IExecutionResponse, IExecutionsCurrentSummaryExtended, IPushData } from '@/Interface';
import { externalHooks } from '@/mixins/externalHooks';
import { nodeHelpers } from '@/mixins/nodeHelpers';

View file

@ -1,6 +1,6 @@
import Vue from 'vue';
import { WorkflowTitleStatus } from '../../Interface';
import { WorkflowTitleStatus } from '@/Interface';
export const titleChange = Vue.extend({
methods: {

View file

@ -1,5 +1,5 @@
import Vue from 'vue';
import 'n8n-design-system/src/shims-element-ui';
import 'n8n-design-system/shims-element-ui';
declare module '*.vue' {
import Vue from 'vue';

View file

@ -1,4 +1,4 @@
import startCase from 'lodash.startCase';
import { startCase } from 'lodash';
import { defineStore } from 'pinia';
import {
INodePropertyCollection,

View file

@ -13,7 +13,8 @@
"baseUrl": ".",
"types": ["vitest/globals"],
"paths": {
"@/*": ["src/*"]
"@/*": ["src/*"],
"n8n-design-system/*": ["../design-system/src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"],
// TODO: remove all options below this line

View file

@ -36,7 +36,7 @@ function renderChunks() {
const publicPath = process.env.VUE_APP_PUBLIC_PATH || '/';
const lodashAliases = ['orderBy', 'camelCase', 'cloneDeep', 'isEqual'].map((name) => ({
const lodashAliases = ['orderBy', 'camelCase', 'cloneDeep', 'isEqual', 'startCase'].map((name) => ({
find: new RegExp(`^lodash.${name}$`, 'i'),
replacement: require.resolve(`lodash-es/${name}`),
}));

View file

@ -1,8 +1,11 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/base'],
...sharedOptions(__dirname),
ignorePatterns: [
'templates/**', // TODO: remove this
],

View file

@ -1,12 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/node'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
...sharedOptions(__dirname),
rules: {
// TODO: remove all the following rules

View file

@ -1,13 +1,12 @@
const { sharedOptions } = require('@n8n_io/eslint-config/shared');
/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/base'],
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
...sharedOptions(__dirname),
rules: {
'import/order': 'off', // TODO: remove this

View file

@ -8,7 +8,8 @@ overrides:
browserslist: ^4.21.4
ejs: ^3.1.8
fork-ts-checker-webpack-plugin: ^6.0.4
globby: ^11.1.0
cpy@8>globby: ^11.1.0
qqjs>globby: ^11.1.0
importers:
@ -68,6 +69,7 @@ importers:
eslint: ~8.28
eslint-config-airbnb-typescript: ~17.0
eslint-config-prettier: ~8.5
eslint-import-resolver-typescript: ~3.5
eslint-plugin-diff: ~2.0
eslint-plugin-import: ~2.26
eslint-plugin-n8n-local-rules: ~1.0
@ -81,8 +83,9 @@ importers:
eslint: 8.28.0
eslint-config-airbnb-typescript: 17.0.0_twozqnrpw2n42bn4rzkw5rgv4m
eslint-config-prettier: 8.5.0_eslint@8.28.0
eslint-import-resolver-typescript: 3.5.2_ktrec6dplf4now6nlbc6d67jee
eslint-plugin-diff: 2.0.1_eslint@8.28.0
eslint-plugin-import: 2.26.0_vbnhqcxlbs7ynbxw44hu2vq7eq
eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq
eslint-plugin-n8n-local-rules: 1.0.0
eslint-plugin-prettier: 4.2.1_pgxuib4rd7wiymfktharf5ydt4
eslint-plugin-vue: 7.17.0_eslint@8.28.0
@ -3646,6 +3649,18 @@ packages:
- vue
dev: true
/@pkgr/utils/2.3.1:
resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
dependencies:
cross-spawn: 7.0.3
is-glob: 4.0.3
open: 8.4.0
picocolors: 1.0.0
tiny-glob: 0.2.9
tslib: 2.4.0
dev: true
/@rollup/pluginutils/4.2.1:
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
engines: {node: '>= 8.0.0'}
@ -10842,7 +10857,7 @@ packages:
dependencies:
confusing-browser-globals: 1.0.11
eslint: 8.28.0
eslint-plugin-import: 2.26.0_vbnhqcxlbs7ynbxw44hu2vq7eq
eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq
object.assign: 4.1.4
object.entries: 1.1.5
semver: 6.3.0
@ -10860,7 +10875,7 @@ packages:
'@typescript-eslint/parser': 5.45.0_zksrc6ykdxhogxjbhb5axiabwi
eslint: 8.28.0
eslint-config-airbnb-base: 15.0.0_ktrec6dplf4now6nlbc6d67jee
eslint-plugin-import: 2.26.0_vbnhqcxlbs7ynbxw44hu2vq7eq
eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq
dev: true
/eslint-config-prettier/8.5.0_eslint@8.28.0:
@ -10885,7 +10900,27 @@ packages:
- supports-color
dev: true
/eslint-module-utils/2.7.4_kr6tb4mi2cmpd7whrqyyy67tyi:
/eslint-import-resolver-typescript/3.5.2_ktrec6dplf4now6nlbc6d67jee:
resolution: {integrity: sha512-zX4ebnnyXiykjhcBvKIf5TNvt8K7yX6bllTRZ14MiurKPjDpCAZujlszTdB8pcNXhZcOf+god4s9SjQa5GnytQ==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
eslint: '*'
eslint-plugin-import: '*'
dependencies:
debug: 4.3.4
enhanced-resolve: 5.10.0
eslint: 8.28.0
eslint-plugin-import: 2.26.0_xmouedd5rhgbah4737x2hltudq
get-tsconfig: 4.2.0
globby: 13.1.3
is-core-module: 2.11.0
is-glob: 4.0.3
synckit: 0.8.4
transitivePeerDependencies:
- supports-color
dev: true
/eslint-module-utils/2.7.4_zkfsjkvh2muiaosb2bwsbw52mq:
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
engines: {node: '>=4'}
peerDependencies:
@ -10910,6 +10945,7 @@ packages:
debug: 3.2.7
eslint: 8.28.0
eslint-import-resolver-node: 0.3.6
eslint-import-resolver-typescript: 3.5.2_ktrec6dplf4now6nlbc6d67jee
transitivePeerDependencies:
- supports-color
dev: true
@ -10923,7 +10959,7 @@ packages:
eslint: 8.28.0
dev: true
/eslint-plugin-import/2.26.0_vbnhqcxlbs7ynbxw44hu2vq7eq:
/eslint-plugin-import/2.26.0_xmouedd5rhgbah4737x2hltudq:
resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
engines: {node: '>=4'}
peerDependencies:
@ -10940,7 +10976,7 @@ packages:
doctrine: 2.1.0
eslint: 8.28.0
eslint-import-resolver-node: 0.3.6
eslint-module-utils: 2.7.4_kr6tb4mi2cmpd7whrqyyy67tyi
eslint-module-utils: 2.7.4_zkfsjkvh2muiaosb2bwsbw52mq
has: 1.0.3
is-core-module: 2.11.0
is-glob: 4.0.3
@ -12172,6 +12208,10 @@ packages:
engines: {node: '>8.0.0'}
dev: false
/get-tsconfig/4.2.0:
resolution: {integrity: sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==}
dev: true
/get-uri/3.0.2:
resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==}
engines: {node: '>= 6'}
@ -12342,6 +12382,10 @@ packages:
dependencies:
define-properties: 1.1.4
/globalyzer/0.1.0:
resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==}
dev: true
/globby/11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
@ -12353,6 +12397,21 @@ packages:
merge2: 1.4.1
slash: 3.0.0
/globby/13.1.3:
resolution: {integrity: sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
dir-glob: 3.0.1
fast-glob: 3.2.12
ignore: 5.2.0
merge2: 1.4.1
slash: 4.0.0
dev: true
/globrex/0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
dev: true
/glogg/1.0.2:
resolution: {integrity: sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==}
engines: {node: '>= 0.10'}
@ -19015,6 +19074,11 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
/slash/4.0.0:
resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
engines: {node: '>=12'}
dev: true
/slice-ansi/3.0.0:
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
engines: {node: '>=8'}
@ -19853,6 +19917,14 @@ packages:
resolution: {integrity: sha512-qImOD23aDfnIDNqlG1NOehdB9IYsn1V9oByPjKY1nakv2MQYCEMyX033/q+aEtYCpmYK1cv2+NTmlH+ra6GA5A==}
dev: true
/synckit/0.8.4:
resolution: {integrity: sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==}
engines: {node: ^14.18.0 || >=16.0.0}
dependencies:
'@pkgr/utils': 2.3.1
tslib: 2.4.0
dev: true
/systemjs/6.13.0:
resolution: {integrity: sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==}
dev: true
@ -20112,6 +20184,13 @@ packages:
setimmediate: 1.0.5
dev: true
/tiny-glob/0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
dependencies:
globalyzer: 0.1.0
globrex: 0.1.2
dev: true
/tinycolor2/1.4.2:
resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==}
dev: false