810 lines
37 KiB
JSON
810 lines
37 KiB
JSON
{
|
|
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
"categories": {
|
|
"correctness": "off"
|
|
},
|
|
"ignorePatterns": ["**/coverage", "**/.vscode", "**/docker-compose.yml", "!.github", "assets/build", "lib/routes-deprecated", "lib/router.js", "dist", "dist-lib", "dist-worker"],
|
|
"env": {
|
|
"builtin": true,
|
|
"browser": true,
|
|
"es2026": true,
|
|
"node": true
|
|
},
|
|
"plugins": ["eslint", "typescript", "node", "unicorn", "import"],
|
|
"jsPlugins": [
|
|
{ "name": "n", "specifier": "eslint-plugin-n" },
|
|
{ "name": "unicorn-js", "specifier": "eslint-plugin-unicorn" },
|
|
{ "name": "regexp", "specifier": "eslint-plugin-regexp" },
|
|
"@stylistic/eslint-plugin",
|
|
"eslint-plugin-simple-import-sort",
|
|
{ "name": "eslint-js", "specifier": "oxlint-plugin-eslint" },
|
|
"./eslint-plugins/nsfw-flag.js"
|
|
],
|
|
"rules": {
|
|
// #region --- ESLint js/recommended possible problems ---
|
|
"constructor-super": "error",
|
|
"for-direction": "error",
|
|
"getter-return": "error",
|
|
"no-async-promise-executor": "error",
|
|
"no-class-assign": "error",
|
|
"no-compare-neg-zero": "error",
|
|
"no-cond-assign": "error",
|
|
"no-const-assign": "error",
|
|
"no-constant-binary-expression": "error",
|
|
"no-constant-condition": "error",
|
|
"no-control-regex": "error",
|
|
"no-debugger": "error",
|
|
"no-dupe-class-members": "error",
|
|
"no-dupe-else-if": "error",
|
|
"no-dupe-keys": "error",
|
|
"no-duplicate-case": "error",
|
|
// "no-empty-character-class": "error", -> off, handled by eslint-plugin-regexp
|
|
"no-empty-pattern": "error",
|
|
"no-ex-assign": "error",
|
|
"no-fallthrough": "error",
|
|
"no-func-assign": "error",
|
|
"no-import-assign": "error",
|
|
// "no-invalid-regexp": "error", -> off, handled by eslint-plugin-regexp
|
|
"no-irregular-whitespace": "error",
|
|
"no-loss-of-precision": "error",
|
|
"no-misleading-character-class": "error",
|
|
"no-new-native-nonconstructor": "error",
|
|
"no-nonoctal-decimal-escape": "error",
|
|
"no-obj-calls": "error",
|
|
// "no-prototype-builtins": "error", -> off
|
|
"no-self-assign": "error",
|
|
"no-setter-return": "error",
|
|
"no-sparse-arrays": "error",
|
|
"no-this-before-super": "error",
|
|
"no-unassigned-vars": "error",
|
|
// "no-undef": "error",
|
|
"no-unexpected-multiline": "error",
|
|
"no-unreachable": "error",
|
|
"no-unsafe-finally": "error",
|
|
"no-unsafe-negation": "error",
|
|
"no-unsafe-optional-chaining": "error",
|
|
"no-unused-private-class-members": "error",
|
|
// "no-unused-vars": "error", -> off for @typescript-eslint/no-unused-vars
|
|
// "no-useless-backreference": "error", -> off, handled by eslint-plugin-regexp
|
|
"use-isnan": "error",
|
|
"valid-typeof": "error",
|
|
// #endregion
|
|
|
|
// #region --- ESLint js/recommended suggestions ---
|
|
"no-case-declarations": "error",
|
|
"no-delete-var": "error",
|
|
"no-empty": "error",
|
|
"no-empty-static-block": "error",
|
|
"no-extra-boolean-cast": "error",
|
|
"no-global-assign": "error",
|
|
"no-redeclare": "error",
|
|
"no-regex-spaces": "error",
|
|
"no-shadow-restricted-names": "error",
|
|
"no-unused-labels": "error",
|
|
"no-useless-catch": "error",
|
|
"no-useless-escape": "error",
|
|
"no-with": "error",
|
|
"preserve-caught-error": "error",
|
|
"require-yield": "error",
|
|
// #endregion
|
|
|
|
// #region --- TypeScript flat/recommended ---
|
|
// "@typescript-eslint/ban-ts-comment": "error",
|
|
"no-array-constructor": "error", // equivalent to @typescript-eslint/no-array-constructor in oxlint
|
|
"@typescript-eslint/no-duplicate-enum-values": "error",
|
|
"@typescript-eslint/no-empty-object-type": "error",
|
|
// "@typescript-eslint/no-explicit-any": "error",
|
|
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
|
"@typescript-eslint/no-misused-new": "error",
|
|
"@typescript-eslint/no-namespace": "error",
|
|
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
|
"@typescript-eslint/no-require-imports": "error",
|
|
"@typescript-eslint/no-this-alias": "error",
|
|
"@typescript-eslint/no-unnecessary-type-constraint": "error",
|
|
"@typescript-eslint/no-unsafe-declaration-merging": "error",
|
|
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
// "no-unused-expressions": "off",
|
|
// "@typescript-eslint/no-unused-expressions": "error",
|
|
// "no-unused-vars": "off",
|
|
// "@typescript-eslint/no-unused-vars": "error",
|
|
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
"@typescript-eslint/prefer-as-const": "error",
|
|
"@typescript-eslint/prefer-namespace-keyword": "error",
|
|
"@typescript-eslint/triple-slash-reference": "error",
|
|
// #endregion
|
|
|
|
// #region --- TypeScript flat/stylistic ---
|
|
"@typescript-eslint/adjacent-overload-signatures": "error",
|
|
// "@typescript-eslint/array-type": "error",
|
|
"@typescript-eslint/ban-tslint-comment": "error",
|
|
"@typescript-eslint/class-literal-property-style": "error",
|
|
"@typescript-eslint/consistent-generic-constructors": "error",
|
|
// "@typescript-eslint/consistent-indexed-object-style": "error",
|
|
"@typescript-eslint/consistent-type-assertions": "error",
|
|
// "@typescript-eslint/consistent-type-definitions": "error",
|
|
"@typescript-eslint/no-confusing-non-null-assertion": "error",
|
|
// "no-empty-function": "off",
|
|
// "@typescript-eslint/no-empty-function": "error",
|
|
// "@typescript-eslint/no-inferrable-types": "error",
|
|
"@typescript-eslint/prefer-for-of": "error",
|
|
"@typescript-eslint/prefer-function-type": "error",
|
|
// #endregion
|
|
|
|
// #region --- n flat/recommended-script ---
|
|
"n/hashbang": "error",
|
|
// "n/no-deprecated-api": "error",
|
|
"node/no-exports-assign": "error",
|
|
"n/no-extraneous-import": "error",
|
|
// "n/no-extraneous-require": "error",
|
|
// "n/no-missing-import": "error",
|
|
// "n/no-missing-require": "error",
|
|
// "n/no-process-exit": "error",
|
|
// "n/no-unpublished-import": "error",
|
|
// "n/no-unpublished-require": "error",
|
|
"n/no-unsupported-features/es-builtins": "error",
|
|
"n/no-unsupported-features/es-syntax": "error",
|
|
// "n/no-unsupported-features/node-builtins": "error",
|
|
"n/process-exit-as-throw": "error",
|
|
// #endregion
|
|
|
|
// #region --- unicorn recommended ---
|
|
// "unicorn-js/better-dom-traversing": "error", false positive on cheerio
|
|
"unicorn/catch-error-name": "error",
|
|
"unicorn-js/class-reference-in-static-methods": "error",
|
|
"unicorn/consistent-assert": "error",
|
|
// "unicorn-js/consistent-boolean-name": "error", // unopinionated
|
|
"unicorn-js/consistent-class-member-order": "error",
|
|
"unicorn-js/consistent-compound-words": "error",
|
|
"unicorn-js/consistent-conditional-object-spread": "error",
|
|
"unicorn/consistent-date-clone": "error",
|
|
"unicorn/consistent-empty-array-spread": "error",
|
|
"unicorn/consistent-existence-index-check": "error",
|
|
"unicorn-js/consistent-export-decorator-position": "error",
|
|
// "unicorn/consistent-function-scoping": "error", -> warn
|
|
"unicorn-js/consistent-json-file-read": "error",
|
|
"unicorn-js/consistent-optional-chaining": "error",
|
|
"unicorn/consistent-template-literal-escape": "error",
|
|
"unicorn-js/consistent-tuple-labels": "error",
|
|
"unicorn-js/default-export-style": "error",
|
|
"unicorn/empty-brace-spaces": "error",
|
|
"unicorn/error-message": "error",
|
|
"unicorn/escape-case": "error",
|
|
// "unicorn/expiring-todo-comments": "error", // not yet implemented
|
|
// "unicorn/explicit-length-check": "error",
|
|
"unicorn-js/explicit-timer-delay": "error",
|
|
// "unicorn/filename-case": "error",
|
|
"unicorn/import-style": "error",
|
|
"unicorn-js/isolated-functions": ["error", { "overrideGlobals": { "document": "readonly", "window": "readonly", "fetch": "readonly", "XMLHttpRequest": "readonly" } }],
|
|
"unicorn-js/logical-assignment-operators": "error",
|
|
"unicorn/max-nested-calls": "error",
|
|
// "unicorn-js/name-replacements": "error", // unopinionated, rebranded prevent-abbreviations
|
|
"unicorn/new-for-builtins": "error",
|
|
"unicorn/no-abusive-eslint-disable": "error",
|
|
"unicorn/no-accessor-recursion": "error",
|
|
"unicorn-js/no-accidental-bitwise-operator": "error",
|
|
"unicorn/no-anonymous-default-export": "error",
|
|
// "unicorn/no-array-callback-reference": "error",
|
|
"unicorn-js/no-array-concat-in-loop": "error",
|
|
"unicorn/no-array-fill-with-reference-type": "error",
|
|
"unicorn/no-array-for-each": "error",
|
|
"unicorn-js/no-array-from-fill": "error",
|
|
"unicorn/no-array-method-this-argument": "error",
|
|
// "unicorn/no-array-reduce": "error",
|
|
"unicorn/no-array-reverse": "error",
|
|
// "unicorn/no-array-sort": "error",
|
|
"unicorn-js/no-array-sort-for-min-max": "error",
|
|
"unicorn-js/no-array-splice": "error",
|
|
"unicorn-js/no-async-promise-finally": "error",
|
|
// "unicorn/no-await-expression-member": "error",
|
|
"unicorn/no-await-in-promise-methods": "error",
|
|
"unicorn-js/no-blob-to-file": "error",
|
|
"unicorn-js/no-boolean-sort-comparator": "error",
|
|
// "unicorn-js/no-break-in-nested-loop": "error", // unopinionated
|
|
// "unicorn-js/no-canvas-to-image": "error", // unused
|
|
"unicorn-js/no-chained-comparison": "error",
|
|
"unicorn-js/no-collection-bracket-access": "error",
|
|
"unicorn-js/no-computed-property-existence-check": "error",
|
|
"unicorn-js/no-confusing-array-splice": "error",
|
|
"unicorn-js/no-confusing-array-with": "error",
|
|
"unicorn/no-console-spaces": "error",
|
|
"unicorn-js/no-constant-zero-expression": "error",
|
|
// "unicorn-js/no-declarations-before-early-exit": "error", // unopinionated
|
|
"unicorn/no-document-cookie": "error",
|
|
"unicorn-js/no-double-comparison": "error",
|
|
"unicorn-js/no-duplicate-if-branches": "error",
|
|
"unicorn-js/no-duplicate-logical-operands": "error",
|
|
"unicorn-js/no-duplicate-loops": "error",
|
|
"unicorn-js/no-duplicate-set-values": "error",
|
|
// "unicorn/no-empty-file": "error",
|
|
"unicorn-js/no-error-property-assignment": "error",
|
|
"unicorn-js/no-exports-in-scripts": "error",
|
|
// "unicorn/no-for-loop": "error", // won't be implemented
|
|
"unicorn-js/no-global-object-property-assignment": "error",
|
|
"unicorn/no-immediate-mutation": "error",
|
|
"unicorn-js/no-impossible-length-comparison": "error",
|
|
"unicorn-js/no-incorrect-query-selector": "error",
|
|
// "unicorn-js/no-incorrect-template-string-interpolation": "error", // unopinionated, too many false positives in v68
|
|
"unicorn/no-instanceof-builtins": "error",
|
|
"unicorn-js/no-invalid-argument-count": "error",
|
|
"unicorn-js/no-invalid-character-comparison": "error",
|
|
"unicorn/no-invalid-fetch-options": "error",
|
|
"unicorn/no-invalid-remove-event-listener": "error",
|
|
"unicorn-js/no-invalid-well-known-symbol-methods": "error",
|
|
"unicorn-js/no-late-current-target-access": "error",
|
|
"unicorn-js/no-late-event-control": "error",
|
|
"unicorn/no-lonely-if": "error",
|
|
"unicorn-js/no-loop-iterable-mutation": "error",
|
|
"unicorn/no-magic-array-flat-depth": "error",
|
|
"unicorn-js/no-mismatched-map-key": "error",
|
|
"unicorn-js/no-misrefactored-assignment": "error",
|
|
// "unicorn/no-named-default": "error", -> use import/no-named-default
|
|
"unicorn-js/no-negated-array-predicate": "error",
|
|
"unicorn-js/no-negated-comparison": "error",
|
|
"no-negated-condition": "off",
|
|
"unicorn/no-negated-condition": "error",
|
|
"unicorn/no-negation-in-equality-check": "error",
|
|
"no-nested-ternary": "off",
|
|
// "unicorn/no-nested-ternary": "error",
|
|
"unicorn/no-new-array": "error",
|
|
"unicorn/no-new-buffer": "error",
|
|
"unicorn-js/no-non-function-verb-prefix": "error",
|
|
"unicorn-js/no-nonstandard-builtin-properties": "error",
|
|
// "unicorn/no-null": "error",
|
|
// "unicorn/no-object-as-default-parameter": "error",
|
|
"unicorn-js/no-object-methods-with-collections": "error",
|
|
"unicorn-js/no-optional-chaining-on-undeclared-variable": "error",
|
|
// "unicorn/no-process-exit": "error",
|
|
"unicorn-js/no-redundant-comparison": "error",
|
|
"unicorn-js/no-return-array-push": "error",
|
|
"unicorn-js/no-selector-as-dom-name": "error",
|
|
"unicorn/no-single-promise-in-promise-methods": "error",
|
|
"unicorn/no-static-only-class": "error",
|
|
"unicorn-js/no-subtraction-comparison": "error",
|
|
"unicorn/no-thenable": "error",
|
|
"unicorn/no-this-assignment": "error",
|
|
"unicorn-js/no-this-outside-of-class": "error",
|
|
// "unicorn-js/no-top-level-assignment-in-function": "error", // unopinionated
|
|
// "unicorn-js/no-top-level-side-effects": "error", // allows dayjs.extend()
|
|
"unicorn/no-typeof-undefined": "error",
|
|
"unicorn-js/no-uncalled-method": "error",
|
|
"unicorn-js/no-undeclared-class-members": "error",
|
|
"unicorn/no-unnecessary-array-flat-depth": "error",
|
|
"unicorn-js/no-unnecessary-array-flat-map": "error",
|
|
"unicorn/no-unnecessary-array-splice-count": "error",
|
|
"unicorn/no-unnecessary-await": "error",
|
|
"unicorn-js/no-unnecessary-boolean-comparison": "error",
|
|
"unicorn-js/no-unnecessary-fetch-options": "error",
|
|
"unicorn-js/no-unnecessary-global-this": "error",
|
|
"unicorn-js/no-unnecessary-nested-ternary": "error",
|
|
"unicorn-js/no-unnecessary-polyfills": "error",
|
|
"unicorn/no-unnecessary-slice-end": "error",
|
|
"unicorn-js/no-unnecessary-splice": "error",
|
|
"unicorn/no-unreadable-array-destructuring": "error",
|
|
"unicorn-js/no-unreadable-for-of-expression": "error",
|
|
"unicorn/no-unreadable-iife": "error",
|
|
"unicorn-js/no-unreadable-object-destructuring": "error",
|
|
"unicorn-js/no-unsafe-buffer-conversion": "error",
|
|
"unicorn-js/no-unsafe-promise-all-settled-values": "error",
|
|
"unicorn-js/no-unsafe-property-key": "error",
|
|
"unicorn-js/no-unsafe-string-replacement": "error",
|
|
"unicorn-js/no-unused-array-method-return": "error",
|
|
"unicorn-js/no-useless-boolean-cast": "error",
|
|
"unicorn-js/no-useless-coercion": "error",
|
|
"unicorn/no-useless-collection-argument": "error",
|
|
"unicorn-js/no-useless-compound-assignment": "error",
|
|
"unicorn-js/no-useless-concat": "error",
|
|
"unicorn-js/no-useless-continue": "error",
|
|
"unicorn-js/no-useless-delete-check": "error",
|
|
"unicorn-js/no-useless-else": "error",
|
|
"unicorn/no-useless-error-capture-stack-trace": "error",
|
|
"unicorn/no-useless-fallback-in-spread": "error",
|
|
// "unicorn/no-useless-iterator-to-array": "error",
|
|
"unicorn/no-useless-length-check": "error",
|
|
"unicorn-js/no-useless-logical-operand": "error",
|
|
"unicorn-js/no-useless-override": "error",
|
|
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
// "unicorn-js/no-useless-recursion": "error", unopinionated
|
|
"unicorn/no-useless-spread": "error",
|
|
// "unicorn/no-useless-switch-case": "error",
|
|
"unicorn-js/no-useless-template-literals": "error",
|
|
// "unicorn/no-useless-undefined": "error",
|
|
"unicorn-js/no-xor-as-exponentiation": "error",
|
|
"unicorn/no-zero-fractions": "error",
|
|
// "unicorn/number-literal-case": "error",
|
|
// "unicorn/numeric-separators-style": "error",
|
|
"unicorn-js/operator-assignment": "error",
|
|
"unicorn-js/prefer-abort-signal-any": "error",
|
|
"unicorn-js/prefer-abort-signal-timeout": "error",
|
|
"unicorn/prefer-add-event-listener": "error",
|
|
"unicorn-js/prefer-add-event-listener-options": "error",
|
|
"unicorn-js/prefer-aggregate-error": "error",
|
|
"unicorn/prefer-array-find": "error",
|
|
"unicorn/prefer-array-flat": "error",
|
|
"unicorn/prefer-array-flat-map": "error",
|
|
"unicorn-js/prefer-array-from-async": "error",
|
|
"unicorn-js/prefer-array-from-map": "error",
|
|
"unicorn-js/prefer-array-from-range": "error",
|
|
"unicorn/prefer-array-index-of": "error",
|
|
"unicorn-js/prefer-array-iterable-methods": "error",
|
|
"unicorn-js/prefer-array-last-methods": "error",
|
|
"unicorn-js/prefer-array-slice": "error",
|
|
"unicorn/prefer-array-some": "error",
|
|
"unicorn/prefer-at": "error",
|
|
"unicorn-js/prefer-await": "error",
|
|
"unicorn/prefer-bigint-literals": "error",
|
|
"unicorn/prefer-blob-reading-methods": "error",
|
|
"unicorn-js/prefer-block-statement-over-iife": "error",
|
|
"unicorn-js/prefer-boolean-return": "error",
|
|
"unicorn/prefer-class-fields": "error",
|
|
"unicorn/prefer-classlist-toggle": "error",
|
|
// "unicorn/prefer-code-point": "error",
|
|
"unicorn-js/prefer-continue": "error",
|
|
"unicorn/prefer-date-now": "error",
|
|
"unicorn/prefer-default-parameters": "error",
|
|
"unicorn-js/prefer-direct-iteration": "error",
|
|
"unicorn/prefer-dom-node-append": "error",
|
|
"unicorn/prefer-dom-node-dataset": "error",
|
|
"unicorn/prefer-dom-node-remove": "error",
|
|
"unicorn-js/prefer-dom-node-replace-children": "error",
|
|
"unicorn/prefer-dom-node-text-content": "error",
|
|
"unicorn-js/prefer-early-return": "error",
|
|
"unicorn-js/prefer-else-if": "error",
|
|
"unicorn/prefer-event-target": "error",
|
|
"unicorn/prefer-export-from": "error",
|
|
"unicorn-js/prefer-flat-math-min-max": "error",
|
|
"unicorn-js/prefer-get-or-insert-computed": "error",
|
|
"unicorn-js/prefer-global-number-constants": "error",
|
|
// "unicorn/prefer-global-this": "error",
|
|
"unicorn-js/prefer-group-by": "error",
|
|
"unicorn-js/prefer-has-check": "error",
|
|
"unicorn-js/prefer-hoisting-branch-code": "error",
|
|
// "unicorn-js/prefer-https": "error",
|
|
"unicorn-js/prefer-identifier-import-export-specifiers": "error",
|
|
"unicorn/prefer-includes": "error",
|
|
"unicorn-js/prefer-includes-over-repeated-comparisons": "error",
|
|
"unicorn-js/prefer-iterable-in-constructor": "error",
|
|
"unicorn-js/prefer-iterator-helpers": "error",
|
|
"unicorn-js/prefer-iterator-to-array": "error",
|
|
// "unicorn-js/prefer-iterator-to-array-at-end": "error",
|
|
"unicorn/prefer-keyboard-event-key": "error",
|
|
"unicorn-js/prefer-location-assign": "error",
|
|
"unicorn/prefer-logical-operator-over-ternary": "error",
|
|
"unicorn-js/prefer-map-from-entries": "error",
|
|
"unicorn-js/prefer-math-abs": "error",
|
|
"unicorn-js/prefer-math-constants": "error",
|
|
"unicorn/prefer-math-min-max": "error",
|
|
"unicorn/prefer-math-trunc": "error",
|
|
// "unicorn-js/prefer-minimal-ternary": "error", // unopinionated, fixes have less readability
|
|
"unicorn/prefer-modern-dom-apis": "error",
|
|
"unicorn/prefer-modern-math-apis": "error",
|
|
// "unicorn/prefer-module": "error",
|
|
"unicorn/prefer-native-coercion-functions": "error",
|
|
"unicorn/prefer-negative-index": "error",
|
|
"unicorn/prefer-node-protocol": "error",
|
|
"unicorn/prefer-number-coercion": "error",
|
|
"unicorn-js/prefer-number-is-safe-integer": "error",
|
|
// "unicorn/prefer-number-properties": "error", // checkNaN: false
|
|
"unicorn-js/prefer-object-define-properties": "error",
|
|
"unicorn-js/prefer-object-destructuring-defaults": "error",
|
|
"unicorn/prefer-object-from-entries": "error",
|
|
"unicorn-js/prefer-object-iterable-methods": "error",
|
|
"unicorn-js/prefer-observer-apis": "error",
|
|
"unicorn/prefer-optional-catch-binding": "error",
|
|
// "unicorn-js/prefer-path2d": "error", // unused
|
|
"unicorn-js/prefer-private-class-fields": "error",
|
|
"unicorn-js/prefer-promise-try": "error",
|
|
"unicorn-js/prefer-promise-with-resolvers": "error",
|
|
"unicorn/prefer-prototype-methods": "error",
|
|
"unicorn/prefer-query-selector": "error",
|
|
"unicorn-js/prefer-queue-microtask": "error",
|
|
"unicorn/prefer-reflect-apply": "error",
|
|
"unicorn/prefer-regexp-test": "error",
|
|
"unicorn/prefer-response-static-json": "error",
|
|
"unicorn-js/prefer-scoped-selector": "error",
|
|
"unicorn/prefer-set-has": "error",
|
|
"unicorn-js/prefer-set-methods": "error",
|
|
"unicorn/prefer-set-size": "error",
|
|
"unicorn-js/prefer-short-arrow-method": "warn",
|
|
"unicorn-js/prefer-simple-condition-first": "error",
|
|
"unicorn-js/prefer-simple-sort-comparator": "error",
|
|
"unicorn-js/prefer-simplified-conditions": "error",
|
|
"unicorn-js/prefer-single-array-predicate": "error",
|
|
"unicorn/prefer-single-call": "error",
|
|
"unicorn-js/prefer-single-object-destructuring": "error",
|
|
"unicorn-js/prefer-single-replace": "error",
|
|
"unicorn-js/prefer-smaller-scope": "error",
|
|
"unicorn-js/prefer-split-limit": "error",
|
|
// "unicorn/prefer-spread": "error",
|
|
"unicorn-js/prefer-string-match-all": "error",
|
|
"unicorn-js/prefer-string-pad-start-end": "error",
|
|
"unicorn/prefer-string-raw": "error",
|
|
"unicorn-js/prefer-string-repeat": "error",
|
|
"unicorn/prefer-string-replace-all": "error",
|
|
// "unicorn/prefer-string-slice": "error",
|
|
// "unicorn/prefer-string-starts-ends-with": "error", use typescript/prefer-string-starts-ends-with
|
|
"unicorn/prefer-string-trim-start-end": "error",
|
|
"unicorn/prefer-structured-clone": "error",
|
|
// "unicorn/prefer-switch": "error",
|
|
"unicorn/prefer-ternary": "error",
|
|
"unicorn-js/prefer-toggle-attribute": "error",
|
|
// "unicorn/prefer-top-level-await": "error",
|
|
"unicorn/prefer-type-error": "error",
|
|
"unicorn-js/prefer-type-literal-last": "error",
|
|
// "unicorn-js/prefer-uint8array-base64": "error", re-evaluate when node > 25
|
|
"unicorn-js/prefer-unary-minus": "error",
|
|
"unicorn-js/prefer-unicode-code-point-escapes": "error",
|
|
"unicorn-js/prefer-url-can-parse": "error",
|
|
"unicorn-js/prefer-url-href": "error",
|
|
"unicorn-js/prefer-url-search-parameters": "error",
|
|
"unicorn-js/prefer-while-loop-condition": "error",
|
|
// "unicorn/prevent-abbreviations": "error",
|
|
"unicorn/relative-url-style": "error",
|
|
"unicorn/require-array-join-separator": "error",
|
|
"unicorn-js/require-array-sort-compare": "error",
|
|
"unicorn-js/require-css-escape": "error",
|
|
"unicorn/require-module-attributes": "error",
|
|
"unicorn/require-module-specifiers": "error",
|
|
"unicorn/require-number-to-fixed-digits-argument": "error",
|
|
"unicorn-js/require-passive-events": "error",
|
|
"unicorn-js/require-proxy-trap-boolean-return": "error",
|
|
// "unicorn/switch-case-braces": "error",
|
|
"unicorn-js/switch-case-break-position": "error",
|
|
"unicorn-js/template-indent": "error",
|
|
// "unicorn/text-encoding-identifier-case": "error",
|
|
"unicorn/throw-new-error": "error",
|
|
// #endregion
|
|
|
|
// #region --- regexp recommended ---
|
|
"regexp/confusing-quantifier": "warn",
|
|
"regexp/control-character-escape": "error",
|
|
"regexp/match-any": "error",
|
|
"regexp/negation": "error",
|
|
"regexp/no-contradiction-with-assertion": "error",
|
|
"regexp/no-dupe-characters-character-class": "error",
|
|
"regexp/no-dupe-disjunctions": "error",
|
|
"regexp/no-empty-alternative": "warn",
|
|
"regexp/no-empty-capturing-group": "error",
|
|
"regexp/no-empty-character-class": "error",
|
|
"regexp/no-empty-group": "error",
|
|
"regexp/no-empty-lookarounds-assertion": "error",
|
|
"regexp/no-empty-string-literal": "error",
|
|
"regexp/no-escape-backspace": "error",
|
|
"regexp/no-extra-lookaround-assertions": "error",
|
|
"regexp/no-invalid-regexp": "error",
|
|
"regexp/no-invisible-character": "error",
|
|
"regexp/no-lazy-ends": "warn",
|
|
"regexp/no-legacy-features": "error",
|
|
"regexp/no-misleading-capturing-group": "error",
|
|
"regexp/no-misleading-unicode-character": "error",
|
|
"regexp/no-missing-g-flag": "error",
|
|
"regexp/no-non-standard-flag": "error",
|
|
"regexp/no-obscure-range": "error",
|
|
"regexp/no-optional-assertion": "error",
|
|
"regexp/no-potentially-useless-backreference": "warn",
|
|
"regexp/no-super-linear-backtracking": "error",
|
|
"regexp/no-trivially-nested-assertion": "error",
|
|
"regexp/no-trivially-nested-quantifier": "error",
|
|
"regexp/no-unused-capturing-group": "error",
|
|
"regexp/no-useless-assertions": "error",
|
|
"regexp/no-useless-backreference": "error",
|
|
"regexp/no-useless-character-class": "error",
|
|
"regexp/no-useless-dollar-replacements": "error",
|
|
"regexp/no-useless-escape": "error",
|
|
"regexp/no-useless-flag": "warn",
|
|
"regexp/no-useless-lazy": "error",
|
|
"regexp/no-useless-non-capturing-group": "error",
|
|
"regexp/no-useless-quantifier": "error",
|
|
"regexp/no-useless-range": "error",
|
|
"regexp/no-useless-set-operand": "error",
|
|
"regexp/no-useless-string-literal": "error",
|
|
"regexp/no-useless-two-nums-quantifier": "error",
|
|
"regexp/no-zero-quantifier": "error",
|
|
"regexp/optimal-lookaround-quantifier": "warn",
|
|
"regexp/optimal-quantifier-concatenation": "error",
|
|
"regexp/prefer-character-class": "error",
|
|
"regexp/prefer-d": "error",
|
|
"regexp/prefer-plus-quantifier": "error",
|
|
"regexp/prefer-predefined-assertion": "error",
|
|
"regexp/prefer-question-quantifier": "error",
|
|
"regexp/prefer-range": "error",
|
|
"regexp/prefer-set-operation": "error",
|
|
"regexp/prefer-star-quantifier": "error",
|
|
"regexp/prefer-unicode-codepoint-escapes": "error",
|
|
"regexp/prefer-w": "error",
|
|
"regexp/simplify-set-operations": "error",
|
|
"regexp/sort-flags": "error",
|
|
"regexp/strict": "error",
|
|
"regexp/use-ignore-case": "error",
|
|
// #endregion
|
|
|
|
// --- custom rules ---
|
|
// #region --- possible problems ---
|
|
"array-callback-return": ["error", { "allowImplicit": true }],
|
|
|
|
"no-await-in-loop": "error",
|
|
"no-prototype-builtins": "off",
|
|
"no-undef": "off", // typescript/eslint-recommended, ts(2552)
|
|
// #endregion
|
|
|
|
// #region --- suggestions ---
|
|
"arrow-body-style": "error",
|
|
"block-scoped-var": "error",
|
|
"curly": "error",
|
|
// "dot-notation": "error", -> use @typescript-eslint/dot-notation
|
|
"eqeqeq": "error",
|
|
|
|
"default-case": ["warn", { "commentPattern": "^no default$" }],
|
|
|
|
"default-case-last": "error",
|
|
"no-console": "error",
|
|
"no-eval": "error",
|
|
"no-extend-native": "error",
|
|
"no-extra-label": "error",
|
|
|
|
"no-implicit-coercion": [
|
|
"error",
|
|
{
|
|
"boolean": false,
|
|
"number": false,
|
|
"string": false,
|
|
"disallowTemplateShorthand": true
|
|
}
|
|
],
|
|
|
|
"eslint-js/no-implicit-globals": "error",
|
|
"no-labels": "error",
|
|
"no-lonely-if": "error",
|
|
"no-multi-str": "error",
|
|
"no-new-func": "error",
|
|
|
|
"eslint-js/no-restricted-syntax": [
|
|
"error",
|
|
{
|
|
"selector": "CallExpression[callee.property.name='get'][arguments.length=0]",
|
|
"message": "Please use .toArray() instead."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name='toArray'] MemberExpression[object.callee.property.name='map']",
|
|
"message": "Please use .toArray() before .map()."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"catch\"] > ArrowFunctionExpression[params.length=0][body.value=null]",
|
|
"message": "Usage of .catch(() => null) is not allowed. Please handle the error appropriately."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"catch\"] > ArrowFunctionExpression[params.length=0][body.type=\"Identifier\"][body.name=\"undefined\"]",
|
|
"message": "Usage of .catch(() => undefined) is not allowed. Please handle the error appropriately."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"catch\"] > ArrowFunctionExpression[params.length=0] > ArrayExpression[elements.length=0]",
|
|
"message": "Usage of .catch(() => []) is not allowed. Please handle the error appropriately."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"catch\"] > ArrowFunctionExpression[params.length=0] > BlockStatement[body.length=0]",
|
|
"message": "Usage of .catch(() => {}) is not allowed. Please handle the error appropriately."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.name=\"load\"] AwaitExpression > CallExpression",
|
|
"message": "Do not use await in call expressions. Extract the result into a variable first."
|
|
},
|
|
{
|
|
"selector": "Identifier[name=\"_ctx\"]",
|
|
"message": "Usage of `_ctx` is not allowed."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"each\"] > FunctionExpression",
|
|
"message": "Use an arrow function instead."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"filter\"] > FunctionExpression",
|
|
"message": "Use an arrow function instead."
|
|
},
|
|
{
|
|
"selector": "CallExpression[callee.property.name=\"map\"] > FunctionExpression",
|
|
"message": "Use an arrow function instead."
|
|
}
|
|
],
|
|
|
|
"no-unneeded-ternary": "error",
|
|
"no-useless-computed-key": "error",
|
|
"no-useless-concat": "warn",
|
|
"no-useless-rename": "error",
|
|
"no-var": "error",
|
|
"eslint-js/object-shorthand": "error",
|
|
"prefer-arrow-callback": "error",
|
|
"prefer-const": "error",
|
|
"prefer-object-has-own": "error",
|
|
"prefer-regex-literals": [
|
|
"error",
|
|
{
|
|
"disallowRedundantWrapping": true
|
|
}
|
|
],
|
|
"require-await": "error",
|
|
// #endregion
|
|
|
|
// #region --- TypeScript ---
|
|
"@typescript-eslint/array-type": ["error", { "default": "array-simple" }],
|
|
|
|
"@typescript-eslint/ban-ts-comment": "off",
|
|
"@typescript-eslint/consistent-indexed-object-style": "off", // stylistic
|
|
"@typescript-eslint/consistent-type-definitions": "off", // stylistic
|
|
"@typescript-eslint/dot-notation": "error", // type-aware
|
|
"@typescript-eslint/no-empty-function": "off", // stylistic && tests
|
|
"@typescript-eslint/no-explicit-any": "off",
|
|
|
|
"@typescript-eslint/no-inferrable-types": ["error", { "ignoreParameters": true, "ignoreProperties": true }],
|
|
|
|
"@typescript-eslint/no-unnecessary-template-expression": "error", // type-aware
|
|
|
|
"@typescript-eslint/no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true }],
|
|
"@typescript-eslint/no-unused-vars": ["error", { "args": "after-used", "argsIgnorePattern": "^_" }],
|
|
|
|
"@typescript-eslint/prefer-string-starts-ends-with": "error", // type-aware
|
|
|
|
// type-aware
|
|
// "@typescript-eslint/await-thenable": "off",
|
|
// "@typescript-eslint/no-base-to-string": "off",
|
|
// "@typescript-eslint/no-floating-promises": "off",
|
|
// "@typescript-eslint/no-misused-spread": "off",
|
|
// "@typescript-eslint/no-redundant-type-constituents": "off",
|
|
// "@typescript-eslint/unbound-method": "off",
|
|
// "@typescript-eslint/restrict-template-expressions": "off",
|
|
// #endregion
|
|
|
|
// #region --- unicorn ---
|
|
"unicorn/consistent-function-scoping": "warn",
|
|
"unicorn/explicit-length-check": "off",
|
|
|
|
"unicorn/filename-case": [
|
|
"error",
|
|
{
|
|
"case": "kebabCase",
|
|
"ignore": [".*\\.(yaml|yml)$", "RequestInProgress\\.js$"]
|
|
}
|
|
],
|
|
|
|
"unicorn/no-array-callback-reference": "warn",
|
|
"unicorn/no-array-reduce": "warn",
|
|
"unicorn/no-array-sort": "warn",
|
|
"unicorn/no-await-expression-member": "off",
|
|
"unicorn/no-empty-file": "warn",
|
|
// "unicorn/no-for-loop": "off", // won't be implemented
|
|
"unicorn/no-nested-ternary": "off",
|
|
"unicorn/no-null": "off",
|
|
"unicorn/no-object-as-default-parameter": "warn",
|
|
"unicorn/no-process-exit": "off",
|
|
"unicorn/no-useless-iterator-to-array": "off",
|
|
"unicorn/no-useless-switch-case": "off",
|
|
|
|
"unicorn/no-useless-undefined": ["error", { "checkArguments": false }],
|
|
|
|
"unicorn/number-literal-case": "off",
|
|
|
|
"unicorn/numeric-separators-style": [
|
|
"warn",
|
|
{
|
|
"onlyIfContainsSeparator": false,
|
|
"number": {
|
|
"minimumDigits": 7,
|
|
"groupLength": 3
|
|
},
|
|
"binary": {
|
|
"minimumDigits": 9,
|
|
"groupLength": 4
|
|
},
|
|
"octal": {
|
|
"minimumDigits": 9,
|
|
"groupLength": 4
|
|
},
|
|
"hexadecimal": {
|
|
"minimumDigits": 5,
|
|
"groupLength": 2
|
|
}
|
|
}
|
|
],
|
|
|
|
"unicorn/prefer-code-point": "warn",
|
|
"unicorn/prefer-global-this": "off",
|
|
"unicorn-js/prefer-import-meta-properties": "warn",
|
|
"unicorn/prefer-module": "off",
|
|
|
|
"unicorn/prefer-number-properties": ["error", { "checkInfinity": false, "checkNaN": false }],
|
|
|
|
"unicorn/prefer-spread": "warn",
|
|
"unicorn/prefer-string-slice": "warn",
|
|
|
|
"unicorn-js/prefer-switch": [
|
|
"warn",
|
|
{
|
|
"emptyDefaultCase": "do-nothing-comment"
|
|
}
|
|
],
|
|
|
|
"unicorn/prefer-top-level-await": "off",
|
|
// "unicorn/prevent-abbreviations": "off",
|
|
"unicorn/switch-case-braces": ["error", "avoid"],
|
|
"unicorn/text-encoding-identifier-case": "off",
|
|
// #endregion
|
|
|
|
// #region --- stylistic ---
|
|
"@stylistic/arrow-parens": "error",
|
|
"@stylistic/arrow-spacing": "error",
|
|
"@stylistic/comma-spacing": "error",
|
|
"@stylistic/comma-style": "error",
|
|
"@stylistic/function-call-spacing": "error",
|
|
"@stylistic/keyword-spacing": "off",
|
|
"@stylistic/linebreak-style": "error",
|
|
|
|
"@stylistic/lines-around-comment": ["error", { "beforeBlockComment": false }],
|
|
|
|
"@stylistic/no-multiple-empty-lines": "error",
|
|
"@stylistic/no-trailing-spaces": "error",
|
|
|
|
"@stylistic/quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": "avoidEscape" }],
|
|
|
|
"@stylistic/rest-spread-spacing": "error",
|
|
"@stylistic/semi": "error",
|
|
"@stylistic/space-before-blocks": "error",
|
|
"@stylistic/space-in-parens": "error",
|
|
"@stylistic/space-infix-ops": "error",
|
|
"@stylistic/space-unary-ops": "error",
|
|
"@stylistic/spaced-comment": "error",
|
|
// #endregion
|
|
|
|
// #region --- import sorting ---
|
|
// oxfmt also handles import sorting
|
|
"sort-imports": "off",
|
|
// "import-x/order": "off",
|
|
"simple-import-sort/imports": "error", // oxc doesn't sort named imports yet https://github.com/oxc-project/oxc/issues/13610
|
|
"simple-import-sort/exports": "error",
|
|
|
|
"import-x/first": "error",
|
|
"import-x/newline-after-import": "error",
|
|
"no-duplicate-imports": "off",
|
|
"import-x/no-duplicates": "error",
|
|
|
|
"@typescript-eslint/consistent-type-imports": "error",
|
|
// #endregion
|
|
|
|
// #region --- n ---
|
|
"n/no-extraneous-require": "error",
|
|
"n/no-deprecated-api": "warn",
|
|
"n/no-missing-import": "off",
|
|
"n/no-missing-require": "off",
|
|
"n/no-process-exit": "off",
|
|
"n/no-unpublished-import": "off",
|
|
|
|
"n/no-unpublished-require": ["error", { "allowModules": ["tosource"] }],
|
|
|
|
"n/no-unsupported-features/node-builtins": [
|
|
"error",
|
|
{
|
|
"version": "^22.20.0 || ^24",
|
|
"allowExperimental": true,
|
|
"ignores": []
|
|
}
|
|
],
|
|
// #endregion
|
|
|
|
// rsshub
|
|
"@rsshub/nsfw-flag/add-nsfw-flag": "error"
|
|
},
|
|
"overrides": [
|
|
{
|
|
"files": [".puppeteerrc.cjs"],
|
|
"plugins": ["typescript"],
|
|
"rules": {
|
|
"@typescript-eslint/no-require-imports": "off"
|
|
}
|
|
},
|
|
{
|
|
"files": ["**/*.test.ts"],
|
|
"plugins": ["typescript"],
|
|
"rules": {
|
|
"@typescript-eslint/no-unnecessary-template-expression": "off"
|
|
}
|
|
}
|
|
]
|
|
}
|