diff --git a/eslint.config.ts b/eslint.config.ts index d9320af6e3e..fb5e80ba15c 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -91,14 +91,17 @@ export default defineConfig([ '@stylistic/comma-spacing': [2, {before: false, after: true}], '@stylistic/comma-style': [2, 'last'], '@stylistic/computed-property-spacing': [2, 'never'], + '@stylistic/curly-newline': [0], '@stylistic/dot-location': [2, 'property'], '@stylistic/eol-last': [2], + '@stylistic/exp-list-style': [0], '@stylistic/function-call-argument-newline': [0], '@stylistic/function-call-spacing': [2, 'never'], '@stylistic/function-paren-newline': [0], '@stylistic/generator-star-spacing': [0], '@stylistic/implicit-arrow-linebreak': [0], '@stylistic/indent': [2, 2, {ignoreComments: true, SwitchCase: 1}], + '@stylistic/indent-binary-ops': [0], '@stylistic/key-spacing': [2], '@stylistic/keyword-spacing': [2], '@stylistic/line-comment-position': [0], @@ -107,6 +110,7 @@ export default defineConfig([ '@stylistic/lines-between-class-members': [0], '@stylistic/max-len': [0], '@stylistic/max-statements-per-line': [0], + '@stylistic/member-delimiter-style': [0], '@stylistic/multiline-comment-style': [0], '@stylistic/multiline-ternary': [0], '@stylistic/new-parens': [2], @@ -145,6 +149,9 @@ export default defineConfig([ '@stylistic/switch-colon-spacing': [2], '@stylistic/template-curly-spacing': [2, 'never'], '@stylistic/template-tag-spacing': [2, 'never'], + '@stylistic/type-annotation-spacing': [0], + '@stylistic/type-generic-spacing': [0], + '@stylistic/type-named-tuple-spacing': [0], '@stylistic/wrap-iife': [2, 'inside'], '@stylistic/wrap-regex': [0], '@stylistic/yield-star-spacing': [2, 'after'], @@ -199,6 +206,7 @@ export default defineConfig([ '@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-misused-spread': [0], // false-positives '@typescript-eslint/no-mixed-enums': [0], '@typescript-eslint/no-namespace': [2], '@typescript-eslint/no-non-null-asserted-nullish-coalescing': [0], @@ -213,12 +221,14 @@ export default defineConfig([ '@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-parameter-property-assignment': [2], '@typescript-eslint/no-unnecessary-qualifier': [0], '@typescript-eslint/no-unnecessary-template-expression': [0], '@typescript-eslint/no-unnecessary-type-arguments': [2], '@typescript-eslint/no-unnecessary-type-assertion': [2], '@typescript-eslint/no-unnecessary-type-constraint': [2], '@typescript-eslint/no-unnecessary-type-conversion': [2], + '@typescript-eslint/no-unnecessary-type-parameters': [0], '@typescript-eslint/no-unsafe-argument': [0], '@typescript-eslint/no-unsafe-assignment': [0], '@typescript-eslint/no-unsafe-call': [0], @@ -227,6 +237,7 @@ export default defineConfig([ '@typescript-eslint/no-unsafe-function-type': [2], '@typescript-eslint/no-unsafe-member-access': [0], '@typescript-eslint/no-unsafe-return': [0], + '@typescript-eslint/no-unsafe-type-assertion': [0], '@typescript-eslint/no-unsafe-unary-minus': [2], '@typescript-eslint/no-unused-expressions': [2], '@typescript-eslint/no-unused-private-class-members': [2], @@ -258,6 +269,7 @@ export default defineConfig([ '@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/related-getter-setter-pairs': [2], '@typescript-eslint/require-array-sort-compare': [0], '@typescript-eslint/require-await': [0], '@typescript-eslint/restrict-plus-operands': [2], @@ -269,6 +281,7 @@ export default defineConfig([ '@typescript-eslint/triple-slash-reference': [2], '@typescript-eslint/unbound-method': [0], // too many false-positives '@typescript-eslint/unified-signatures': [2], + '@typescript-eslint/use-unknown-in-catch-callback-variable': [0], 'accessor-pairs': [2], 'array-callback-return': [2, {checkForEach: true}], 'arrow-body-style': [0], @@ -315,6 +328,7 @@ export default defineConfig([ 'import-x/no-cycle': [2, {ignoreExternal: true, maxDepth: 1}], 'import-x/no-default-export': [0], 'import-x/no-deprecated': [0], + 'import-x/no-duplicates': [2], 'import-x/no-dynamic-require': [0], 'import-x/no-empty-named-blocks': [2], 'import-x/no-extraneous-dependencies': [2], @@ -329,6 +343,7 @@ export default defineConfig([ 'import-x/no-nodejs-modules': [0], 'import-x/no-relative-packages': [0], 'import-x/no-relative-parent-imports': [0], + 'import-x/no-rename-default': [0], 'import-x/no-restricted-paths': [0], 'import-x/no-self-import': [2], 'import-x/no-unassigned-import': [0], @@ -338,6 +353,7 @@ export default defineConfig([ 'import-x/no-webpack-loader-syntax': [2], 'import-x/order': [0], 'import-x/prefer-default-export': [0], + 'import-x/prefer-namespace-import': [0], 'import-x/unambiguous': [0], 'init-declarations': [0], 'logical-assignment-operators': [0], @@ -554,6 +570,7 @@ export default defineConfig([ 'no-unreachable': [2], 'no-unsafe-finally': [2], 'no-unsafe-negation': [2], + 'no-unsafe-optional-chaining': [2], 'no-unused-expressions': [0], // handled by @typescript-eslint/no-unused-expressions 'no-unused-labels': [2], 'no-unused-private-class-members': [0], // handled by @typescript-eslint/no-unused-private-class-members @@ -593,6 +610,7 @@ export default defineConfig([ 'radix': [0], 'regexp/confusing-quantifier': [2], 'regexp/control-character-escape': [2], + 'regexp/grapheme-string-literal': [0], 'regexp/hexadecimal-escape': [0], 'regexp/letter-case': [0], 'regexp/match-any': [2], @@ -663,12 +681,14 @@ export default defineConfig([ 'regexp/prefer-unicode-codepoint-escapes': [2], 'regexp/prefer-w': [0], 'regexp/require-unicode-regexp': [0], + 'regexp/require-unicode-sets-regexp': [0], 'regexp/simplify-set-operations': [2], 'regexp/sort-alternatives': [0], 'regexp/sort-character-class-elements': [0], 'regexp/sort-flags': [0], 'regexp/strict': [2], 'regexp/unicode-escape': [0], + 'regexp/unicode-property': [0], 'regexp/use-ignore-case': [0], 'require-atomic-updates': [0], 'require-await': [0], // handled by @typescript-eslint/require-await @@ -684,6 +704,7 @@ export default defineConfig([ 'unicorn/catch-error-name': [0], 'unicorn/class-reference-in-static-methods': [2], 'unicorn/comment-content': [0], + 'unicorn/consistent-arrow-return-style': [0], 'unicorn/consistent-assert': [0], 'unicorn/consistent-boolean-name': [0], 'unicorn/consistent-class-member-order': [0], @@ -713,6 +734,7 @@ export default defineConfig([ 'unicorn/id-match': [2], 'unicorn/import-style': [0], 'unicorn/isolated-functions': [2, {functions: []}], + 'unicorn/iteration-fallback-style': [2, 'fallback'], 'unicorn/logical-assignment-operators': [0], 'unicorn/max-nested-calls': [0], 'unicorn/name-replacements': [0], @@ -736,6 +758,7 @@ export default defineConfig([ 'unicorn/no-async-promise-finally': [2], 'unicorn/no-await-expression-member': [0], 'unicorn/no-await-in-promise-methods': [2], + 'unicorn/no-barrel-files': [0], 'unicorn/no-blob-to-file': [2], 'unicorn/no-boolean-sort-comparator': [2], 'unicorn/no-break-in-nested-loop': [0], @@ -834,6 +857,7 @@ export default defineConfig([ 'unicorn/no-unsafe-dom-html': [0], 'unicorn/no-unsafe-promise-all-settled-values': [2], 'unicorn/no-unsafe-property-key': [0], + 'unicorn/no-unsafe-sqlite-interpolation': [2], 'unicorn/no-unsafe-string-replacement': [0], 'unicorn/no-unused-array-method-return': [2], 'unicorn/no-unused-properties': [2], @@ -995,7 +1019,6 @@ export default defineConfig([ 'unicorn/prefer-url-href': [2], 'unicorn/prefer-url-search-parameters': [2], 'unicorn/prefer-while-loop-condition': [2], - 'unicorn/prevent-abbreviations': [0], 'unicorn/relative-url-style': [2], 'unicorn/require-array-join-separator': [2], 'unicorn/require-array-sort-compare': [0], @@ -1007,6 +1030,7 @@ export default defineConfig([ 'unicorn/require-passive-events': [2], 'unicorn/require-post-message-target-origin': [0], 'unicorn/require-proxy-trap-boolean-return': [2], + 'unicorn/single-line-block-comment-style': [0], 'unicorn/string-content': [0], 'unicorn/switch-case-braces': [0], 'unicorn/switch-case-break-position': [2], @@ -1060,7 +1084,7 @@ export default defineConfig([ }, extends: [ vue.configs['flat/recommended'], - vueScopedCss.configs.recommended as any, + vueScopedCss.configs.recommended, ], rules: { 'vue/attributes-order': [0], @@ -1077,9 +1101,12 @@ export default defineConfig([ rules: { 'gitea/unescaped-html-literal': [0], 'unicorn/no-error-property-assignment': [0], + 'vitest/consistent-each-for': [0], 'vitest/consistent-test-filename': [0], 'vitest/consistent-test-it': [0], + 'vitest/consistent-vitest-vi': [0], 'vitest/expect-expect': [0], + 'vitest/hoisted-apis-on-top': [0], 'vitest/max-expects': [0], 'vitest/max-nested-describe': [0], 'vitest/no-alias-methods': [0], @@ -1092,41 +1119,69 @@ export default defineConfig([ 'vitest/no-focused-tests': [2], 'vitest/no-hooks': [0], 'vitest/no-identical-title': [2], + 'vitest/no-import-node-test': [0], + 'vitest/no-importing-vitest-globals': [2], 'vitest/no-interpolation-in-snapshots': [0], 'vitest/no-large-snapshots': [0], 'vitest/no-mocks-import': [0], - 'vitest/no-importing-vitest-globals': [2], 'vitest/no-restricted-matchers': [0], 'vitest/no-restricted-vi-methods': [0], 'vitest/no-standalone-expect': [0], 'vitest/no-test-prefixes': [0], 'vitest/no-test-return-statement': [0], + 'vitest/no-unneeded-async-expect-function': [2], + 'vitest/padding-around-after-all-blocks': [0], + 'vitest/padding-around-after-each-blocks': [0], + 'vitest/padding-around-all': [0], + 'vitest/padding-around-before-all-blocks': [0], + 'vitest/padding-around-before-each-blocks': [0], + 'vitest/padding-around-describe-blocks': [0], + 'vitest/padding-around-expect-groups': [0], + 'vitest/padding-around-test-blocks': [0], + 'vitest/prefer-called-exactly-once-with': [0], + 'vitest/prefer-called-once': [0], + 'vitest/prefer-called-times': [0], 'vitest/prefer-called-with': [0], 'vitest/prefer-comparison-matcher': [0], + 'vitest/prefer-describe-function-title': [0], 'vitest/prefer-each': [0], 'vitest/prefer-equality-matcher': [0], + 'vitest/prefer-expect-assertions': [0], 'vitest/prefer-expect-resolves': [0], + 'vitest/prefer-expect-type-of': [0], 'vitest/prefer-hooks-in-order': [0], 'vitest/prefer-hooks-on-top': [2], + 'vitest/prefer-import-in-mock': [0], + 'vitest/prefer-importing-vitest-globals': [0], 'vitest/prefer-lowercase-title': [0], 'vitest/prefer-mock-promise-shorthand': [0], + 'vitest/prefer-mock-return-shorthand': [0], 'vitest/prefer-snapshot-hint': [0], 'vitest/prefer-spy-on': [0], + 'vitest/prefer-strict-boolean-matchers': [0], 'vitest/prefer-strict-equal': [0], 'vitest/prefer-to-be': [0], 'vitest/prefer-to-be-falsy': [0], 'vitest/prefer-to-be-object': [0], 'vitest/prefer-to-be-truthy': [0], 'vitest/prefer-to-contain': [0], + 'vitest/prefer-to-have-been-called-times': [0], 'vitest/prefer-to-have-length': [0], 'vitest/prefer-todo': [0], + 'vitest/prefer-vi-mocked': [0], + 'vitest/require-awaited-expect-poll': [0], 'vitest/require-hook': [0], + 'vitest/require-local-test-context-for-concurrent-snapshots': [0], + 'vitest/require-mock-type-parameters': [0], + 'vitest/require-test-timeout': [0], 'vitest/require-to-throw-message': [0], 'vitest/require-top-level-describe': [0], + 'vitest/unbound-method': [0], 'vitest/valid-describe-callback': [2], 'vitest/valid-expect': [2, {maxArgs: 2}], 'vitest/valid-expect-in-promise': [2], 'vitest/valid-title': [2], + 'vitest/warn-todo': [0], }, }, { diff --git a/web_src/js/features/admin/users.ts b/web_src/js/features/admin/users.ts index fec4aa0d5f0..e824ec83564 100644 --- a/web_src/js/features/admin/users.ts +++ b/web_src/js/features/admin/users.ts @@ -9,12 +9,10 @@ export function initAdminUserListSearchForm(): void { button.classList.add('active'); } - if (searchForm.StatusFilterMap) { - for (const [k, v] of Object.entries(searchForm.StatusFilterMap)) { - if (!v) continue; - for (const input of form.querySelectorAll(`input[name="status_filter[${CSS.escape(k)}]"][value="${CSS.escape(v)}"]`)) { - input.checked = true; - } + for (const [k, v] of Object.entries(searchForm.StatusFilterMap || {})) { + if (!v) continue; + for (const input of form.querySelectorAll(`input[name="status_filter[${CSS.escape(k)}]"][value="${CSS.escape(v)}"]`)) { + input.checked = true; } } diff --git a/web_src/js/features/user-auth-webauthn.ts b/web_src/js/features/user-auth-webauthn.ts index 087c18941f9..25554153019 100644 --- a/web_src/js/features/user-auth-webauthn.ts +++ b/web_src/js/features/user-auth-webauthn.ts @@ -251,10 +251,8 @@ async function webAuthnRegisterRequest() { options.publicKey.challenge = decodeURLEncodedBase64(options.publicKey.challenge); options.publicKey.user.id = decodeURLEncodedBase64(options.publicKey.user.id); - if (options.publicKey.excludeCredentials) { - for (const cred of options.publicKey.excludeCredentials) { - cred.id = decodeURLEncodedBase64(cred.id); - } + for (const cred of options.publicKey.excludeCredentials || []) { + cred.id = decodeURLEncodedBase64(cred.id); } try { diff --git a/web_src/js/user-events.sharedworker.ts b/web_src/js/user-events.sharedworker.ts index bcc2b4b0c82..2a4ca963c32 100644 --- a/web_src/js/user-events.sharedworker.ts +++ b/web_src/js/user-events.sharedworker.ts @@ -1,10 +1,10 @@ import { serverUserEventTypes, type SharedWorkerControlMessage, + type UserEventMessage, type WorkerEventMessage, type WorkerInboundMessage, } from './types.ts'; -import type {UserEventMessage} from './types.ts'; // chrome://inspect/#workers let showDebugLog = false;