From 5acbab5e61de7df130e44ae225149cc55ae34762 Mon Sep 17 00:00:00 2001 From: awsr <43862868+awsr@users.noreply.github.com> Date: Fri, 2 Jan 2026 18:24:55 -0800 Subject: [PATCH] Upgrade to ESLint 9 - Upgraded to new plugins for other languages - Added markdown linting - Added `extensions-builtin` to `globalIgnores` - *Disabled CSS and HTML linters for now* - Updated rules that were migrated from eslint to stylistic - Updated VSCode settings to work with new linting features - Updated a few rules to have better defaults instead of disabling them --- .eslintrc.json | 138 ------------------- .vscode/settings.json | 10 +- eslint.config.mjs | 299 ++++++++++++++++++++++++++++++++++++++++++ javascript/gallery.js | 4 +- package.json | 24 ++-- 5 files changed, 322 insertions(+), 153 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.mjs diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 77b6fb242..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "root": true, - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "html", - "json" - ], - "extends": [ - "eslint:recommended", - "airbnb-base", - "plugin:css/recommended", - "plugin:json/recommended", - "plugin:node/recommended" - ], - "env": { - "browser": true, - "commonjs": true, - "node": true, - "jquery": true, - "es2024": true - }, - "rules": { - "max-len": [1, 275, 3], - "camelcase":"off", - "default-case":"off", - "no-await-in-loop":"off", - "no-bitwise":"off", - "no-continue":"off", - "no-confusing-arrow":"off", - "no-console":"off", - "no-empty":"off", - "no-loop-func":"off", - "no-mixed-operators":"off", - "no-param-reassign":"off", - "no-process-exit":"off", - "no-plusplus":"off", - "no-restricted-globals":"off", - "no-restricted-syntax":"off", - "no-return-assign":"off", - "no-unused-vars":"off", - "no-useless-escape":"off", - "object-curly-newline":"off", - "prefer-rest-params":"off", - "prefer-destructuring":"off", - "radix":"off", - "node/shebang": "off" - }, - "globals": { - "panzoom": "readonly", - "authFetch": "readonly", - "log": "readonly", - "debug": "readonly", - "error": "readonly", - "xhrGet": "readonly", - "xhrPost": "readonly", - "gradioApp": "readonly", - "executeCallbacks": "readonly", - "onAfterUiUpdate": "readonly", - "onOptionsChanged": "readonly", - "optionsChangedCallbacks": "readonly", - "onUiLoaded": "readonly", - "onUiUpdate": "readonly", - "onUiTabChange": "readonly", - "onUiReady": "readonly", - "uiCurrentTab": "writable", - "uiElementIsVisible": "readonly", - "uiElementInSight": "readonly", - "getUICurrentTabContent": "readonly", - "waitForFlag": "readonly", - "logFn": "readonly", - "generateForever": "readonly", - "showContributors": "readonly", - "opts": "writable", - "sortUIElements": "readonly", - "all_gallery_buttons": "readonly", - "selected_gallery_button": "readonly", - "selected_gallery_index": "readonly", - "switch_to_txt2img": "readonly", - "switch_to_img2img_tab": "readonly", - "switch_to_img2img": "readonly", - "switch_to_sketch": "readonly", - "switch_to_inpaint": "readonly", - "witch_to_inpaint_sketch": "readonly", - "switch_to_extras": "readonly", - "get_tab_index": "readonly", - "create_submit_args": "readonly", - "restartReload": "readonly", - "markSelectedCards": "readonly", - "updateInput": "readonly", - "toggleCompact": "readonly", - "setFontSize": "readonly", - "setTheme": "readonly", - "registerDragDrop": "readonly", - "getToken": "readonly", - "getENActiveTab": "readonly", - "quickApplyStyle": "readonly", - "quickSaveStyle": "readonly", - "setupExtraNetworks": "readonly", - "showNetworks": "readonly", - "localization": "readonly", - "randomId": "readonly", - "requestProgress": "readonly", - "setRefreshInterval": "readonly", - "modalPrevImage": "readonly", - "modalNextImage": "readonly", - "galleryClickEventHandler": "readonly", - "getExif": "readonly", - "jobStatusEl": "readonly", - "removeSplash": "readonly", - "initGPU": "readonly", - "startGPU": "readonly", - "disableNVML": "readonly", - "idbGet": "readonly", - "idbPut": "readonly", - "idbDel": "readonly", - "idbAdd": "readonly", - "idbCount": "readonly", - "idbFolderCleanup": "readonly", - "initChangelog": "readonly", - "sendNotification": "readonly", - "monitorConnection": "readonly" - }, - "ignorePatterns": [ - "node_modules", - "extensions", - "repositories", - "venv", - "panzoom.js", - "split.js", - "exifr.js", - "jquery.js", - "sparkline.js", - "iframeResizer.min.js" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index d62ba10b8..c7ddf8ba2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,13 @@ "python.analysis.extraPaths": [".", "./modules", "./scripts", "./pipelines"], "python.analysis.typeCheckingMode": "off", "editor.formatOnSave": false, - "python.REPL.enableREPLSmartSend": false + "python.REPL.enableREPLSmartSend": false, + "eslint.enable": true, + "eslint.validate": [ + "javascript", + "html", + "css", + "json", + "markdown" + ] } diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..3fcfdab6c --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,299 @@ +import path from 'node:path'; + +import { includeIgnoreFile } from '@eslint/compat'; +import js from '@eslint/js'; +import { defineConfig, globalIgnores } from 'eslint/config'; +import { helpers, plugins, rules } from 'eslint-config-airbnb-extended'; +import globals from 'globals'; +import css from '@eslint/css'; +import html from '@html-eslint/eslint-plugin'; +import json from '@eslint/json'; +// eslint-disable-next-line import-x/no-rename-default +import markdown from '@eslint/markdown'; + +const gitignorePath = path.resolve('.', '.gitignore'); + +const jsConfig = defineConfig([ + // ESLint recommended config + { + name: 'js/config', + ...js.configs.recommended, + files: helpers.extensions.jsFileWithoutReact, + }, + // Stylistic plugin + plugins.stylistic, + // Import X plugin + plugins.importX, + // Trimmed from Airbnb base recommended config + rules.base.bestPractices, + rules.base.errors, + rules.base.es6, + rules.base.imports, + rules.base.style, + rules.base.stylistic, + rules.base.variables, + { + name: 'sdnext', + files: helpers.extensions.jsFileWithoutReact, + languageOptions: { + globals: { + ...globals.builtin, + ...globals.browser, + ...globals.jquery, + panzoom: 'readonly', + authFetch: 'readonly', + log: 'readonly', + debug: 'readonly', + error: 'readonly', + xhrGet: 'readonly', + xhrPost: 'readonly', + gradioApp: 'readonly', + executeCallbacks: 'readonly', + onAfterUiUpdate: 'readonly', + onOptionsChanged: 'readonly', + optionsChangedCallbacks: 'readonly', + onUiLoaded: 'readonly', + onUiUpdate: 'readonly', + onUiTabChange: 'readonly', + onUiReady: 'readonly', + uiCurrentTab: 'writable', + uiElementIsVisible: 'readonly', + uiElementInSight: 'readonly', + getUICurrentTabContent: 'readonly', + waitForFlag: 'readonly', + logFn: 'readonly', + generateForever: 'readonly', + showContributors: 'readonly', + opts: 'writable', + sortUIElements: 'readonly', + all_gallery_buttons: 'readonly', + selected_gallery_button: 'readonly', + selected_gallery_index: 'readonly', + switch_to_txt2img: 'readonly', + switch_to_img2img_tab: 'readonly', + switch_to_img2img: 'readonly', + switch_to_sketch: 'readonly', + switch_to_inpaint: 'readonly', + witch_to_inpaint_sketch: 'readonly', + switch_to_extras: 'readonly', + get_tab_index: 'readonly', + create_submit_args: 'readonly', + restartReload: 'readonly', + markSelectedCards: 'readonly', + updateInput: 'readonly', + toggleCompact: 'readonly', + setFontSize: 'readonly', + setTheme: 'readonly', + registerDragDrop: 'readonly', + getToken: 'readonly', + getENActiveTab: 'readonly', + quickApplyStyle: 'readonly', + quickSaveStyle: 'readonly', + setupExtraNetworks: 'readonly', + showNetworks: 'readonly', + localization: 'readonly', + randomId: 'readonly', + requestProgress: 'readonly', + setRefreshInterval: 'readonly', + modalPrevImage: 'readonly', + modalNextImage: 'readonly', + galleryClickEventHandler: 'readonly', + getExif: 'readonly', + jobStatusEl: 'readonly', + removeSplash: 'readonly', + initGPU: 'readonly', + startGPU: 'readonly', + disableNVML: 'readonly', + idbGet: 'readonly', + idbPut: 'readonly', + idbDel: 'readonly', + idbAdd: 'readonly', + idbCount: 'readonly', + idbFolderCleanup: 'readonly', + initChangelog: 'readonly', + sendNotification: 'readonly', + monitorConnection: 'readonly', + }, + parserOptions: { + ecmaVersion: 'latest', + }, + }, + rules: { + camelcase: 'off', + 'default-case': 'off', + 'max-classes-per-file': 'warn', + 'no-await-in-loop': 'off', + 'no-bitwise': 'off', + 'no-continue': 'off', + 'no-console': 'off', + 'no-loop-func': 'off', + 'no-param-reassign': 'off', + 'no-plusplus': 'off', + 'no-redeclare': 'off', + 'no-restricted-globals': 'off', + 'no-restricted-syntax': 'off', + 'no-return-assign': 'off', + 'no-unused-vars': 'off', + 'no-use-before-define': 'warn', + 'no-useless-escape': 'off', + 'prefer-destructuring': 'off', + 'prefer-rest-params': 'off', + 'prefer-template': 'warn', + radix: 'off', + '@stylistic/brace-style': [ + 'error', + '1tbs', + { + allowSingleLine: true, + }, + ], + '@stylistic/indent': ['error', 2], + '@stylistic/lines-between-class-members': [ + 'error', + 'always', + { + exceptAfterSingleLine: true, + }, + ], + '@stylistic/max-len': [ + 'warn', + { + code: 275, + tabWidth: 2, + }, + ], + '@stylistic/max-statements-per-line': 'off', + '@stylistic/no-mixed-operators': 'off', + '@stylistic/object-curly-newline': [ + 'error', + { + multiline: true, + consistent: true, + }, + ], + '@stylistic/quotes': [ + 'error', + 'single', + { + avoidEscape: true, + }, + ], + '@stylistic/semi': [ + 'error', + 'always', + { + omitLastInOneLineBlock: false, + }, + ], + }, + }, +]); + +const nodeConfig = defineConfig([ + // Node plugin + plugins.node, + { + files: ['**/cli/*.js'], + languageOptions: { + globals: { + ...globals.node, + }, + }, + rules: { + ...rules.node.base.rules, + ...rules.node.globals.rules, + ...rules.node.noUnsupportedFeatures.rules, + ...rules.node.promises.rules, + 'n/no-sync': 'off', + 'n/no-process-exit': 'off', + 'n/hashbang': 'off', + }, + }, +]); + +const jsonConfig = defineConfig([ + { + files: ['**/*.json'], + ignores: ['package-lock.json'], + plugins: { json }, + language: 'json/json', + extends: ['json/recommended'], + }, +]); + +const markdownConfig = defineConfig([ + { + files: ['**/*.md'], + plugins: { markdown }, + language: 'markdown/gfm', + processor: 'markdown/markdown', + extends: ['markdown/recommended'], + }, +]); + +// const cssConfig = defineConfig([ +// { +// files: ['**/*.css'], +// language: 'css/css', +// plugins: { css }, +// extends: ['css/recommended'], +// rules: { +// 'css/font-family-fallbacks': 'off', +// 'css/no-invalid-properties': [ +// 'error', +// { +// allowUnknownVariables: true, +// }, +// ], +// 'css/no-important': 'off', +// 'css/use-baseline': [ +// 'warn', +// { +// available: 'newly', +// }, +// ], +// }, +// }, +// ]); + +// const htmlConfig = defineConfig([ +// { +// files: ['**/*.html'], +// plugins: { +// html, +// }, +// extends: ['html/recommended'], +// language: 'html/html', +// rules: { +// 'html/indent': [ +// 'warn', +// 2, +// ], +// 'html/no-duplicate-class': 'error', +// }, +// }, +// ]); + +export default defineConfig([ + // Ignore files and folders listed in .gitignore + includeIgnoreFile(gitignorePath), + globalIgnores([ + '**/node_modules', + '**/extensions', + '**/extensions-builtin', + '**/repositories', + '**/venv', + '**/panZoom.js', + '**/split.js', + '**/exifr.js', + '**/jquery.js', + '**/sparkline.js', + '**/iframeResizer.min.js', + ]), + ...jsConfig, + ...nodeConfig, + ...jsonConfig, + ...markdownConfig, + // ...cssConfig, + // ...htmlConfig, +]); diff --git a/javascript/gallery.js b/javascript/gallery.js index fc36f5152..f1b81766c 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -1,5 +1,4 @@ /* eslint-disable max-classes-per-file */ -/* eslint lines-between-class-members: ["error", "always", { "exceptAfterSingleLine": true }] */ let ws; let url; let currentImage; @@ -973,7 +972,8 @@ async function monitorGalleries() { async function setOverlayAnimation() { const busyAnimation = document.createElement('style'); - busyAnimation.textContent = '.idbBusyAnim{width:16px;height:16px;border-radius:50%;display:block;margin:40px;position:relative;background:#ff3d00;color:#fff;box-shadow:-24px 0,24px 0;box-sizing:border-box;animation:2s ease-in-out infinite overlayRotation}@keyframes overlayRotation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}'; // eslint-disable-line max-len + // eslint-disable-next-line @stylistic/max-len + busyAnimation.textContent = '.idbBusyAnim{width:16px;height:16px;border-radius:50%;display:block;margin:40px;position:relative;background:#ff3d00;color:#fff;box-shadow:-24px 0,24px 0;box-sizing:border-box;animation:2s ease-in-out infinite overlayRotation}@keyframes overlayRotation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}'; document.head.append(busyAnimation); } diff --git a/package.json b/package.json index cfbf92e6a..8c8649d6d 100644 --- a/package.json +++ b/package.json @@ -34,19 +34,19 @@ "test": ". venv/bin/activate; python launch.py --debug --test" }, "devDependencies": { - "esbuild": "^0.18.20" + "@eslint/compat": "^2.0.0", + "@eslint/css": "^0.14.1", + "@eslint/js": "^9.39.2", + "@eslint/json": "^0.14.0", + "@eslint/markdown": "^7.5.1", + "@html-eslint/eslint-plugin": "^0.52.1", + "esbuild": "^0.27.2", + "eslint": "^9.39.2", + "eslint-config-airbnb-extended": "^3.0.0", + "globals": "^17.0.0" }, "dependencies": { - "@google/generative-ai": "^0.21.0", - "@typescript-eslint/eslint-plugin": "^8.47.0", - "argparse": "^2.0.1", - "eslint": "^8.57.1", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-css": "^0.9.2", - "eslint-plugin-html": "^8.1.3", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-json": "^3.1.0", - "eslint-plugin-markdown": "^4.0.1", - "eslint-plugin-node": "^11.1.0" + "@google/generative-ai": "^0.24.1", + "argparse": "^2.0.1" } }