aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.yaml133
-rw-r--r--docs/content/contributing/guidelines-frontend.en-us.md16
-rw-r--r--package-lock.json176
-rw-r--r--package.json2
-rw-r--r--tests/e2e/example.test.e2e.ts24
-rw-r--r--tests/e2e/utils_e2e.ts4
-rw-r--r--web_src/js/components/RepoActionView.vue4
-rw-r--r--web_src/js/features/repo-code.js4
-rw-r--r--web_src/js/features/repo-findfile.js4
-rw-r--r--web_src/js/features/repo-home.js8
-rw-r--r--web_src/js/utils/dom.js2
11 files changed, 226 insertions, 151 deletions
diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index 55a0f556fc..293d435b11 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -13,6 +13,7 @@ parserOptions:
ecmaVersion: latest
project: true
extraFileExtensions: [".vue"]
+ parser: "@typescript-eslint/parser" # for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
settings:
import/extensions: [".js", ".ts"]
@@ -24,7 +25,9 @@ settings:
plugins:
- "@eslint-community/eslint-plugin-eslint-comments"
- "@stylistic/eslint-plugin-js"
+ - "@typescript-eslint/eslint-plugin"
- eslint-plugin-array-func
+ - eslint-plugin-deprecation
- eslint-plugin-github
- eslint-plugin-i
- eslint-plugin-no-jquery
@@ -209,6 +212,123 @@ rules:
"@stylistic/js/wrap-iife": [2, inside]
"@stylistic/js/wrap-regex": [0]
"@stylistic/js/yield-star-spacing": [2, after]
+ "@typescript-eslint/adjacent-overload-signatures": [0]
+ "@typescript-eslint/array-type": [0]
+ "@typescript-eslint/await-thenable": [2]
+ "@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}]
+ "@typescript-eslint/ban-tslint-comment": [0]
+ "@typescript-eslint/ban-types": [2, {extendDefaults: true, types: {Function: false}}]
+ "@typescript-eslint/class-literal-property-style": [0]
+ "@typescript-eslint/class-methods-use-this": [0]
+ "@typescript-eslint/consistent-generic-constructors": [0]
+ "@typescript-eslint/consistent-indexed-object-style": [0]
+ "@typescript-eslint/consistent-return": [0]
+ "@typescript-eslint/consistent-type-assertions": [2, {assertionStyle: as, objectLiteralTypeAssertions: allow}]
+ "@typescript-eslint/consistent-type-definitions": [2, type]
+ "@typescript-eslint/consistent-type-exports": [2, {fixMixedExportsWithInlineTypeSpecifier: false}]
+ "@typescript-eslint/consistent-type-imports": [2, {prefer: type-imports, fixStyle: separate-type-imports, disallowTypeAnnotations: true}]
+ "@typescript-eslint/default-param-last": [0]
+ "@typescript-eslint/dot-notation": [0]
+ "@typescript-eslint/explicit-function-return-type": [0]
+ "@typescript-eslint/explicit-member-accessibility": [0]
+ "@typescript-eslint/explicit-module-boundary-types": [0]
+ "@typescript-eslint/init-declarations": [0]
+ "@typescript-eslint/max-params": [0]
+ "@typescript-eslint/member-ordering": [0]
+ "@typescript-eslint/method-signature-style": [0]
+ "@typescript-eslint/naming-convention": [0]
+ "@typescript-eslint/no-array-constructor": [2]
+ "@typescript-eslint/no-array-delete": [2]
+ "@typescript-eslint/no-base-to-string": [0]
+ "@typescript-eslint/no-confusing-non-null-assertion": [2]
+ "@typescript-eslint/no-confusing-void-expression": [0]
+ "@typescript-eslint/no-dupe-class-members": [0]
+ "@typescript-eslint/no-duplicate-enum-values": [2]
+ "@typescript-eslint/no-duplicate-type-constituents": [2, {ignoreUnions: true}]
+ "@typescript-eslint/no-dynamic-delete": [0]
+ "@typescript-eslint/no-empty-function": [0]
+ "@typescript-eslint/no-empty-interface": [0]
+ "@typescript-eslint/no-explicit-any": [0]
+ "@typescript-eslint/no-extra-non-null-assertion": [2]
+ "@typescript-eslint/no-extraneous-class": [0]
+ "@typescript-eslint/no-floating-promises": [0]
+ "@typescript-eslint/no-for-in-array": [2]
+ "@typescript-eslint/no-implied-eval": [2]
+ "@typescript-eslint/no-import-type-side-effects": [0] # dupe with consistent-type-imports
+ "@typescript-eslint/no-inferrable-types": [0]
+ "@typescript-eslint/no-invalid-this": [0]
+ "@typescript-eslint/no-invalid-void-type": [0]
+ "@typescript-eslint/no-loop-func": [0]
+ "@typescript-eslint/no-loss-of-precision": [2]
+ "@typescript-eslint/no-magic-numbers": [0]
+ "@typescript-eslint/no-meaningless-void-operator": [0]
+ "@typescript-eslint/no-misused-new": [2]
+ "@typescript-eslint/no-misused-promises": [2, {checksVoidReturn: {attributes: false, arguments: false}}]
+ "@typescript-eslint/no-mixed-enums": [0]
+ "@typescript-eslint/no-namespace": [2]
+ "@typescript-eslint/no-non-null-asserted-nullish-coalescing": [0]
+ "@typescript-eslint/no-non-null-asserted-optional-chain": [2]
+ "@typescript-eslint/no-non-null-assertion": [0]
+ "@typescript-eslint/no-redeclare": [0]
+ "@typescript-eslint/no-redundant-type-constituents": [2]
+ "@typescript-eslint/no-require-imports": [0]
+ "@typescript-eslint/no-restricted-imports": [0]
+ "@typescript-eslint/no-shadow": [0]
+ "@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": [0]
+ "@typescript-eslint/no-unnecessary-condition": [0]
+ "@typescript-eslint/no-unnecessary-qualifier": [0]
+ "@typescript-eslint/no-unnecessary-template-expression": [0]
+ "@typescript-eslint/no-unnecessary-type-arguments": [0]
+ "@typescript-eslint/no-unnecessary-type-assertion": [2]
+ "@typescript-eslint/no-unnecessary-type-constraint": [2]
+ "@typescript-eslint/no-unsafe-argument": [0]
+ "@typescript-eslint/no-unsafe-assignment": [0]
+ "@typescript-eslint/no-unsafe-call": [0]
+ "@typescript-eslint/no-unsafe-declaration-merging": [2]
+ "@typescript-eslint/no-unsafe-enum-comparison": [2]
+ "@typescript-eslint/no-unsafe-member-access": [0]
+ "@typescript-eslint/no-unsafe-return": [0]
+ "@typescript-eslint/no-unsafe-unary-minus": [2]
+ "@typescript-eslint/no-unused-expressions": [0]
+ "@typescript-eslint/no-unused-vars": [2, {vars: all, args: all, caughtErrors: all, ignoreRestSiblings: false, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_}]
+ "@typescript-eslint/no-use-before-define": [0]
+ "@typescript-eslint/no-useless-constructor": [0]
+ "@typescript-eslint/no-useless-empty-export": [0]
+ "@typescript-eslint/no-var-requires": [2]
+ "@typescript-eslint/non-nullable-type-assertion-style": [0]
+ "@typescript-eslint/only-throw-error": [2]
+ "@typescript-eslint/parameter-properties": [0]
+ "@typescript-eslint/prefer-as-const": [2]
+ "@typescript-eslint/prefer-destructuring": [0]
+ "@typescript-eslint/prefer-enum-initializers": [0]
+ "@typescript-eslint/prefer-find": [2]
+ "@typescript-eslint/prefer-for-of": [2]
+ "@typescript-eslint/prefer-function-type": [2]
+ "@typescript-eslint/prefer-includes": [2]
+ "@typescript-eslint/prefer-literal-enum-member": [0]
+ "@typescript-eslint/prefer-namespace-keyword": [0]
+ "@typescript-eslint/prefer-nullish-coalescing": [0]
+ "@typescript-eslint/prefer-optional-chain": [2, {requireNullish: true}]
+ "@typescript-eslint/prefer-promise-reject-errors": [0]
+ "@typescript-eslint/prefer-readonly": [0]
+ "@typescript-eslint/prefer-readonly-parameter-types": [0]
+ "@typescript-eslint/prefer-reduce-type-parameter": [0]
+ "@typescript-eslint/prefer-regexp-exec": [0]
+ "@typescript-eslint/prefer-return-this-type": [0]
+ "@typescript-eslint/prefer-string-starts-ends-with": [2, {allowSingleElementEquality: always}]
+ "@typescript-eslint/promise-function-async": [0]
+ "@typescript-eslint/require-array-sort-compare": [0]
+ "@typescript-eslint/require-await": [0]
+ "@typescript-eslint/restrict-plus-operands": [2]
+ "@typescript-eslint/restrict-template-expressions": [0]
+ "@typescript-eslint/return-await": [0]
+ "@typescript-eslint/strict-boolean-expressions": [0]
+ "@typescript-eslint/switch-exhaustiveness-check": [0]
+ "@typescript-eslint/triple-slash-reference": [2]
+ "@typescript-eslint/typedef": [0]
+ "@typescript-eslint/unbound-method": [2]
+ "@typescript-eslint/unified-signatures": [2]
accessor-pairs: [2]
array-callback-return: [2, {checkForEach: true}]
array-func/avoid-reverse: [2]
@@ -230,6 +350,7 @@ rules:
default-case-last: [2]
default-case: [0]
default-param-last: [0]
+ deprecation/deprecation: [2]
dot-notation: [0]
eqeqeq: [2]
for-direction: [2]
@@ -321,7 +442,7 @@ rules:
multiline-comment-style: [2, separate-lines]
new-cap: [0]
no-alert: [0]
- no-array-constructor: [2]
+ no-array-constructor: [0] # handled by @typescript-eslint/no-array-constructor
no-async-promise-executor: [0]
no-await-in-loop: [0]
no-bitwise: [0]
@@ -365,7 +486,7 @@ rules:
no-global-assign: [2]
no-implicit-coercion: [2]
no-implicit-globals: [0]
- no-implied-eval: [2]
+ no-implied-eval: [0] # handled by @typescript-eslint/no-implied-eval
no-import-assign: [2]
no-inline-comments: [0]
no-inner-declarations: [2]
@@ -471,7 +592,7 @@ rules:
no-lone-blocks: [2]
no-lonely-if: [0]
no-loop-func: [0]
- no-loss-of-precision: [2]
+ no-loss-of-precision: [0] # handled by @typescript-eslint/no-loss-of-precision
no-magic-numbers: [0]
no-misleading-character-class: [2]
no-multi-assign: [0]
@@ -493,7 +614,7 @@ rules:
no-promise-executor-return: [0]
no-proto: [2]
no-prototype-builtins: [2]
- no-redeclare: [2]
+ no-redeclare: [0] # must be disabled for typescript overloads
no-regex-spaces: [2]
no-restricted-exports: [0]
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
@@ -526,7 +647,7 @@ rules:
no-unused-expressions: [2]
no-unused-labels: [2]
no-unused-private-class-members: [2]
- no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
+ no-unused-vars: [0] # handled by @typescript-eslint/no-unused-vars
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
no-use-extend-native/no-use-extend-native: [2]
no-useless-backreference: [2]
@@ -641,7 +762,7 @@ rules:
regexp/unicode-escape: [0]
regexp/use-ignore-case: [0]
require-atomic-updates: [0]
- require-await: [0]
+ require-await: [0] # handled by @typescript-eslint/require-await
require-unicode-regexp: [0]
require-yield: [2]
sonarjs/cognitive-complexity: [0]
diff --git a/docs/content/contributing/guidelines-frontend.en-us.md b/docs/content/contributing/guidelines-frontend.en-us.md
index a08098a931..5539532c52 100644
--- a/docs/content/contributing/guidelines-frontend.en-us.md
+++ b/docs/content/contributing/guidelines-frontend.en-us.md
@@ -79,6 +79,22 @@ We use htmx for simple interactions. You can see an example for simple interacti
Although mixing different frameworks is discouraged,
it should also work if the mixing is necessary and the code is well-designed and maintainable.
+### Typescript
+
+Gitea is in the process of migrating to type-safe Typescript. Here are some specific guidelines regarding Typescript in the codebase:
+
+#### Use type aliases instead of interfaces
+
+Prefer to use type aliases because they can represent any type and are generally more flexible to use than interfaces.
+
+#### Use separate type imports
+
+We use `verbatimModuleSyntax` so type and non-type imports from the same file must be split into two `import type` statements. This enables the typescript compiler to completely eliminate the type import statements during compilation.
+
+#### Use `@ts-expect-error` instead of `@ts-ignore`
+
+Both annotations should be avoided, but if you have to use them, use `@ts-expect-error` because it will not leave ineffective statements after the issue is fixed.
+
### `async` Functions
Only mark a function as `async` if and only if there are `await` calls
diff --git a/package-lock.json b/package-lock.json
index 3102d02233..502489e726 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -69,11 +69,13 @@
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "2.2.1",
"@stylistic/stylelint-plugin": "2.1.2",
+ "@typescript-eslint/eslint-plugin": "7.14.1",
"@typescript-eslint/parser": "7.14.1",
"@vitejs/plugin-vue": "5.0.5",
"eslint": "8.57.0",
"eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-array-func": "4.0.0",
+ "eslint-plugin-deprecation": "3.0.0",
"eslint-plugin-github": "5.0.1",
"eslint-plugin-i": "2.29.1",
"eslint-plugin-no-jquery": "3.0.1",
@@ -2370,16 +2372,17 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz",
- "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz",
+ "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.13.1",
- "@typescript-eslint/type-utils": "7.13.1",
- "@typescript-eslint/utils": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1",
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/type-utils": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@@ -2431,7 +2434,7 @@
}
}
},
- "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
+ "node_modules/@typescript-eslint/scope-manager": {
"version": "7.14.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
"integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
@@ -2449,105 +2452,15 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
- "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
- "dev": true,
- "license": "MIT",
- "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.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
- "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/types": "7.14.1",
- "@typescript-eslint/visitor-keys": "7.14.1",
- "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": {
+ "node_modules/@typescript-eslint/type-utils": {
"version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
- "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz",
+ "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.14.1",
- "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,
- "license": "Apache-2.0",
- "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.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz",
- "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz",
- "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/typescript-estree": "7.13.1",
- "@typescript-eslint/utils": "7.13.1",
+ "@typescript-eslint/typescript-estree": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@@ -2568,10 +2481,11 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz",
- "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
+ "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
@@ -2581,13 +2495,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz",
- "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
+ "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -2609,15 +2524,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz",
- "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
+ "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.13.1",
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/typescript-estree": "7.13.1"
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/typescript-estree": "7.14.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2631,12 +2547,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.13.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz",
- "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
+ "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.13.1",
+ "@typescript-eslint/types": "7.14.1",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@@ -2652,6 +2569,7 @@
"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,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -5513,6 +5431,22 @@
"eslint": ">=8.40.0"
}
},
+ "node_modules/eslint-plugin-deprecation": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-3.0.0.tgz",
+ "integrity": "sha512-JuVLdNg/uf0Adjg2tpTyYoYaMbwQNn/c78P1HcccokvhtRphgnRjZDKmhlxbxYptppex03zO76f97DD/yQHv7A==",
+ "dev": true,
+ "license": "LGPL-3.0-or-later",
+ "dependencies": {
+ "@typescript-eslint/utils": "^7.0.0",
+ "ts-api-utils": "^1.3.0",
+ "tslib": "^2.3.1"
+ },
+ "peerDependencies": {
+ "eslint": "^8.0.0",
+ "typescript": "^4.2.4 || ^5.0.0"
+ }
+ },
"node_modules/eslint-plugin-escompat": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.4.0.tgz",
diff --git a/package.json b/package.json
index ec1500fb8b..e44415ee32 100644
--- a/package.json
+++ b/package.json
@@ -68,11 +68,13 @@
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "2.2.1",
"@stylistic/stylelint-plugin": "2.1.2",
+ "@typescript-eslint/eslint-plugin": "7.14.1",
"@typescript-eslint/parser": "7.14.1",
"@vitejs/plugin-vue": "5.0.5",
"eslint": "8.57.0",
"eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-array-func": "4.0.0",
+ "eslint-plugin-deprecation": "3.0.0",
"eslint-plugin-github": "5.0.1",
"eslint-plugin-i": "2.29.1",
"eslint-plugin-no-jquery": "3.0.1",
diff --git a/tests/e2e/example.test.e2e.ts b/tests/e2e/example.test.e2e.ts
index 32813b3934..1689f1b8ef 100644
--- a/tests/e2e/example.test.e2e.ts
+++ b/tests/e2e/example.test.e2e.ts
@@ -7,21 +7,21 @@ test.beforeAll(async ({browser}, workerInfo) => {
test('homepage', async ({page}) => {
const response = await page.goto('/');
- await expect(response?.status()).toBe(200); // Status OK
+ expect(response?.status()).toBe(200); // Status OK
await expect(page).toHaveTitle(/^Gitea: Git with a cup of tea\s*$/);
await expect(page.locator('.logo')).toHaveAttribute('src', '/assets/img/logo.svg');
});
test('register', async ({page}, workerInfo) => {
const response = await page.goto('/user/sign_up');
- await expect(response?.status()).toBe(200); // Status OK
- await page.type('input[name=user_name]', `e2e-test-${workerInfo.workerIndex}`);
- await page.type('input[name=email]', `e2e-test-${workerInfo.workerIndex}@test.com`);
- await page.type('input[name=password]', 'test123test123');
- await page.type('input[name=retype]', 'test123test123');
+ expect(response?.status()).toBe(200); // Status OK
+ await page.locator('input[name=user_name]').fill(`e2e-test-${workerInfo.workerIndex}`);
+ await page.locator('input[name=email]').fill(`e2e-test-${workerInfo.workerIndex}@test.com`);
+ await page.locator('input[name=password]').fill('test123test123');
+ await page.locator('input[name=retype]').fill('test123test123');
await page.click('form button.ui.primary.button:visible');
// Make sure we routed to the home page. Else login failed.
- await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
+ expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
await expect(page.locator('.secondary-nav span>img.ui.avatar')).toBeVisible();
await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created. Welcome!');
@@ -30,15 +30,15 @@ test('register', async ({page}, workerInfo) => {
test('login', async ({page}, workerInfo) => {
const response = await page.goto('/user/login');
- await expect(response?.status()).toBe(200); // Status OK
+ expect(response?.status()).toBe(200); // Status OK
- await page.type('input[name=user_name]', `user2`);
- await page.type('input[name=password]', `password`);
+ await page.locator('input[name=user_name]').fill(`user2`);
+ await page.locator('input[name=password]').fill(`password`);
await page.click('form button.ui.primary.button:visible');
await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle
- await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
+ expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
save_visual(page);
});
@@ -50,7 +50,7 @@ test('logged in user', async ({browser}, workerInfo) => {
await page.goto('/');
// Make sure we routed to the home page. Else login failed.
- await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
+ expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
save_visual(page);
});
diff --git a/tests/e2e/utils_e2e.ts b/tests/e2e/utils_e2e.ts
index 5678c9c9d0..14ec836600 100644
--- a/tests/e2e/utils_e2e.ts
+++ b/tests/e2e/utils_e2e.ts
@@ -14,7 +14,7 @@ export async function login_user(browser, workerInfo, user) {
// Route to login page
// Note: this could probably be done more quickly with a POST
const response = await page.goto('/user/login');
- await expect(response?.status()).toBe(200); // Status OK
+ expect(response?.status()).toBe(200); // Status OK
// Fill out form
await page.type('input[name=user_name]', user);
@@ -23,7 +23,7 @@ export async function login_user(browser, workerInfo, user) {
await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle
- await expect(page.url(), {message: `Failed to login user ${user}`}).toBe(`${workerInfo.project.use.baseURL}/`);
+ expect(page.url(), {message: `Failed to login user ${user}`}).toBe(`${workerInfo.project.use.baseURL}/`);
// Save state
await context.storageState({path: `${ARTIFACTS_PATH}/state-${user}-${workerInfo.workerIndex}.json`});
diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue
index 97dc0d950f..e751018f90 100644
--- a/web_src/js/components/RepoActionView.vue
+++ b/web_src/js/components/RepoActionView.vue
@@ -89,7 +89,9 @@ const sfc = {
// load job data and then auto-reload periodically
// need to await first loadJob so this.currentJobStepsStates is initialized and can be used in hashChangeListener
await this.loadJob();
- this.intervalID = setInterval(this.loadJob, 1000);
+ this.intervalID = setInterval(() => {
+ this.loadJob();
+ }, 1000);
document.body.addEventListener('click', this.closeDropdown);
this.hashChangeListener();
window.addEventListener('hashchange', this.hashChangeListener);
diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js
index f0f4ead125..658fa7e11c 100644
--- a/web_src/js/features/repo-code.js
+++ b/web_src/js/features/repo-code.js
@@ -153,7 +153,7 @@ export function initRepoCodeView() {
});
$(window).on('hashchange', () => {
- let m = rangeAnchorRegex.exec(window.location.hash.match);
+ let m = rangeAnchorRegex.exec(window.location.hash);
const $linesEls = $(getLineEls());
let $first;
if (m) {
@@ -170,7 +170,7 @@ export function initRepoCodeView() {
return;
}
}
- m = singleAnchorRegex.exec(window.location.hash.match);
+ m = singleAnchorRegex.exec(window.location.hash);
if (m) {
$first = $linesEls.filter(`[rel=L${m[2]}]`);
if ($first.length) {
diff --git a/web_src/js/features/repo-findfile.js b/web_src/js/features/repo-findfile.js
index 945eeeceff..828acfa65c 100644
--- a/web_src/js/features/repo-findfile.js
+++ b/web_src/js/features/repo-findfile.js
@@ -55,8 +55,8 @@ export function filterRepoFilesWeighted(files, filter) {
const filterLower = filter.toLowerCase();
// TODO: for large repo, this loop could be slow, maybe there could be one more limit:
// ... && filterResult.length < threshold * 20, wait for more feedbacks
- for (let i = 0; i < files.length; i++) {
- const res = strSubMatch(files[i], filterLower);
+ for (const file of files) {
+ const res = strSubMatch(file, filterLower);
if (res.length > 1) { // length==1 means unmatched, >1 means having matched sub strings
filterResult.push({matchResult: res, matchWeight: calcMatchedWeight(res)});
}
diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js
index f48c1b1bb3..3a8e41bde1 100644
--- a/web_src/js/features/repo-home.js
+++ b/web_src/js/features/repo-home.js
@@ -102,16 +102,16 @@ export function initRepoTopicBar() {
if (res.topics) {
let found = false;
- for (let i = 0; i < res.topics.length; i++) {
+ for (const {topic_name} of res.topics) {
// skip currently added tags
- if (current_topics.includes(res.topics[i].topic_name)) {
+ if (current_topics.includes(topic_name)) {
continue;
}
- if (res.topics[i].topic_name.toLowerCase() === query.toLowerCase()) {
+ if (topic_name.toLowerCase() === query.toLowerCase()) {
found_query = true;
}
- formattedResponse.results.push({description: res.topics[i].topic_name, 'data-value': res.topics[i].topic_name});
+ formattedResponse.results.push({description: topic_name, 'data-value': topic_name});
found = true;
}
formattedResponse.success = found;
diff --git a/web_src/js/utils/dom.js b/web_src/js/utils/dom.js
index 9bdb233236..8d75c724de 100644
--- a/web_src/js/utils/dom.js
+++ b/web_src/js/utils/dom.js
@@ -270,7 +270,7 @@ export function replaceTextareaSelection(textarea, text) {
textarea.contentEditable = 'true';
try {
- success = document.execCommand('insertText', false, text);
+ success = document.execCommand('insertText', false, text); // eslint-disable-line deprecation/deprecation
} catch {
success = false;
}