diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 0eda8a1877..47fdc1f0be 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -6,9 +6,20 @@ ignorePatterns: - /web_src/fomantic - /public/assets/js +parser: "@typescript-eslint/parser" + parserOptions: sourceType: module ecmaVersion: latest + project: true + extraFileExtensions: [".vue"] + +settings: + import/extensions: [".js", ".ts"] + import/parsers: + "@typescript-eslint/parser": [".js", ".ts"] + import/resolver: + typescript: true plugins: - "@eslint-community/eslint-plugin-eslint-comments" @@ -103,6 +114,18 @@ overrides: - files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"] rules: no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression] + - files: ["**/*.vue"] + plugins: + - eslint-plugin-vue + - eslint-plugin-vue-scoped-css + extends: + - plugin:vue/vue3-recommended + - plugin:vue-scoped-css/vue3-recommended + rules: + vue/attributes-order: [0] + vue/html-closing-bracket-spacing: [2, {startTag: never, endTag: never, selfClosingTag: never}] + vue/max-attributes-per-line: [0] + vue/singleline-html-element-content-newline: [0] rules: "@eslint-community/eslint-comments/disable-enable-pair": [2] @@ -264,7 +287,7 @@ rules: i/no-internal-modules: [0] i/no-mutable-exports: [0] i/no-named-as-default-member: [0] - i/no-named-as-default: [2] + i/no-named-as-default: [0] i/no-named-default: [0] i/no-named-export: [0] i/no-namespace: [0] @@ -274,7 +297,7 @@ rules: i/no-restricted-paths: [0] i/no-self-import: [2] i/no-unassigned-import: [0] - i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$", ^vitest/]}] + i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}] i/no-unused-modules: [2, {unusedExports: true}] i/no-useless-path-segments: [2, {commonjs: true}] i/no-webpack-loader-syntax: [2] diff --git a/Makefile b/Makefile index 80efcbe46d..4bfbb62e28 100644 --- a/Makefile +++ b/Makefile @@ -373,11 +373,11 @@ lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig .PHONY: lint-js lint-js: node_modules - npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) + npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) .PHONY: lint-js-fix lint-js-fix: node_modules - npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) --fix + npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix .PHONY: lint-css lint-css: node_modules diff --git a/package-lock.json b/package-lock.json index 90cedd63d5..eff261d873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,8 +68,10 @@ "@stoplight/spectral-cli": "6.11.1", "@stylistic/eslint-plugin-js": "2.1.0", "@stylistic/stylelint-plugin": "2.1.2", + "@typescript-eslint/parser": "7.11.0", "@vitejs/plugin-vue": "5.0.4", "eslint": "8.57.0", + "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-array-func": "4.0.0", "eslint-plugin-github": "5.0.0-2", "eslint-plugin-i": "2.29.1", @@ -92,6 +94,7 @@ "stylelint-declaration-strict-value": "1.10.4", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", + "typescript": "5.4.5", "updates": "16.1.1", "vite-string-plugin": "1.3.1", "vitest": "1.6.0" @@ -2396,15 +2399,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", - "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4" }, "engines": { @@ -2423,6 +2426,93 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", @@ -5338,6 +5428,31 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, "node_modules/eslint-module-utils": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", @@ -11865,7 +11980,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "devOptional": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index d7588e093f..520f8c1566 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,10 @@ "@stoplight/spectral-cli": "6.11.1", "@stylistic/eslint-plugin-js": "2.1.0", "@stylistic/stylelint-plugin": "2.1.2", + "@typescript-eslint/parser": "7.11.0", "@vitejs/plugin-vue": "5.0.4", "eslint": "8.57.0", + "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-array-func": "4.0.0", "eslint-plugin-github": "5.0.0-2", "eslint-plugin-i": "2.29.1", @@ -91,6 +93,7 @@ "stylelint-declaration-strict-value": "1.10.4", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", + "typescript": "5.4.5", "updates": "16.1.1", "vite-string-plugin": "1.3.1", "vitest": "1.6.0" diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..dd14cb46a6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,37 @@ +{ + "include": [ + "*", + "tests/e2e/**/*", + "tools/**/*", + "web_src/js/**/*", + ], + "exclude": [ + "**/.git/**", + "**/.venv/**", + "**/node_modules/**", + "**/vendor/**", + ], + "compilerOptions": { + "target": "esnext", + "module": "nodenext", + "moduleResolution": "nodenext", + "moduleDetection": "force", + "lib": ["dom", "dom.iterable", "dom.asynciterable", "esnext"], + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "alwaysStrict": true, + "esModuleInterop": true, + "isolatedModules": true, + "noEmit": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "verbatimModuleSyntax": true, + "stripInternal": true, + "strict": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noPropertyAccessFromIndexSignature": false, + "exactOptionalPropertyTypes": false, + } +} diff --git a/web_src/js/components/.eslintrc.yaml b/web_src/js/components/.eslintrc.yaml deleted file mode 100644 index a79e96f330..0000000000 --- a/web_src/js/components/.eslintrc.yaml +++ /dev/null @@ -1,22 +0,0 @@ -plugins: - - eslint-plugin-vue - - eslint-plugin-vue-scoped-css - -extends: - - ../../../.eslintrc.yaml - - plugin:vue/vue3-recommended - - plugin:vue-scoped-css/vue3-recommended - -parserOptions: - sourceType: module - ecmaVersion: latest - -env: - browser: true - -rules: - vue/attributes-order: [0] - vue/html-closing-bracket-spacing: [2, {startTag: never, endTag: never, selfClosingTag: never}] - vue/max-attributes-per-line: [0] - vue/singleline-html-element-content-newline: [0] - vue-scoped-css/enforce-style-type: [0] diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue index 8b39d0504b..6c16658197 100644 --- a/web_src/js/components/RepoActionView.vue +++ b/web_src/js/components/RepoActionView.vue @@ -797,7 +797,7 @@ export function initRepositoryActionView() { } -