From 13fa6688319277419b9a4213fd1acf02f87bae30 Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Mon, 6 Jul 2026 17:04:51 +0200 Subject: [PATCH 1/2] chore(lint): migrate from eslint to oxlint oxlint runs the same policy surface in ~1s with no typescript peer constraint of its own: - typescript/unicorn/oxc/import plugins + correctness category cover the old js/ts recommended sets; consistent-type-imports, no-unused-vars(args:none) and import/no-duplicates carried over - eslint-plugin-obsidianmd runs unchanged via oxlint jsPlugins (all 7 guideline rules verified firing, incl. nested-name rules) along with the no-restricted-globals app/fetch/localStorage policy - eslint itself remains only as an internal dependency of eslint-plugin-obsidianmd; our direct eslint/typescript-eslint/ import-x devDeps and eslint.config.mjs are gone Fixes for real issues oxlint surfaced that eslint missed: - main.ts imported ./store twice via different specifiers (src/store and ./store) - merged - useless {} fallbacks in loadedData spreads (main.ts) - ambiguous new Array(n) in assertFetchableUrl + TranscriptionService - unsafe optional-chain calls in main.activateView.test.ts Svelte files are excluded (parity with the old ts-only eslint globs; svelte-check owns those). --- .oxlintrc.json | 61 +++ eslint.config.mjs | 128 ------ package-lock.json | 557 +-------------------------- package.json | 10 +- src/main.activateView.test.ts | 5 +- src/main.ts | 6 +- src/services/TranscriptionService.ts | 2 +- src/utility/assertFetchableUrl.ts | 2 +- 8 files changed, 76 insertions(+), 695 deletions(-) create mode 100644 .oxlintrc.json delete mode 100644 eslint.config.mjs diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 00000000..40c9a1ea --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,61 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "unicorn", "oxc", "import"], + "jsPlugins": ["eslint-plugin-obsidianmd"], + "categories": { + "correctness": "error" + }, + "env": { + "browser": true, + "node": true, + "es2021": true + }, + "globals": { + "app": "readonly", + "activeWindow": "readonly", + "activeDocument": "readonly" + }, + "ignorePatterns": ["node_modules", "build", "npm", "main.js", "**/*.svelte"], + "rules": { + "no-unused-vars": ["error", { "args": "none" }], + "import/no-duplicates": "error", + "typescript/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "disallowTypeAnnotations": false, + "fixStyle": "inline-type-imports" + } + ] + }, + "overrides": [ + { + "files": ["src/**/*.ts"], + "excludeFiles": ["src/**/*.test.ts", "src/**/*.spec.ts"], + "rules": { + "obsidianmd/no-static-styles-assignment": "error", + "obsidianmd/prefer-window-timers": "error", + "obsidianmd/prefer-active-doc": "error", + "obsidianmd/detach-leaves": "error", + "obsidianmd/no-global-this": "error", + "obsidianmd/settings-tab/no-manual-html-headings": "error", + "obsidianmd/commands/no-plugin-name-in-command-name": "error", + "no-restricted-globals": [ + "error", + { + "name": "app", + "message": "Avoid the global app object. Use the reference provided by your plugin instance (this.app, or get(plugin).app for module-level code)." + }, + { + "name": "fetch", + "message": "Use Obsidian's requestUrl instead of fetch for network requests." + }, + { + "name": "localStorage", + "message": "Use App#saveLocalStorage / App#loadLocalStorage for vault-scoped storage instead of the global localStorage." + } + ] + } + } + ] +} diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 349e6b87..00000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,128 +0,0 @@ -import js from "@eslint/js"; -import tsPlugin from "@typescript-eslint/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; -import importX from "eslint-plugin-import-x"; -import obsidianmd from "eslint-plugin-obsidianmd"; -import globals from "globals"; - -const sharedGlobals = { - ...globals.browser, - ...globals.node, - ...globals.es2021, - app: "readonly", - // Obsidian exposes these globals (the active, possibly popped-out window / - // document); plugin code prefers them over bare window/document. - activeWindow: "readonly", - activeDocument: "readonly", -}; - -const vitestGlobals = { - afterAll: "readonly", - afterEach: "readonly", - beforeAll: "readonly", - beforeEach: "readonly", - describe: "readonly", - expect: "readonly", - it: "readonly", - test: "readonly", - vi: "readonly", - vitest: "readonly", -}; - -const languageOptions = { - parser: tsParser, - parserOptions: { - sourceType: "module", - }, - globals: sharedGlobals, -}; - -const plugins = { - "@typescript-eslint": tsPlugin, - import: importX, -}; - -const rules = { - ...js.configs.recommended.rules, - ...tsPlugin.configs.recommended.rules, - "no-unused-vars": "off", - "no-prototype-builtins": "off", - "import/no-duplicates": "error", - "@typescript-eslint/no-unused-vars": ["error", { args: "none" }], - "@typescript-eslint/ban-ts-comment": "off", - "@typescript-eslint/consistent-type-imports": [ - "error", - { - prefer: "type-imports", - disallowTypeAnnotations: false, - fixStyle: "inline-type-imports", - }, - ], - "@typescript-eslint/no-empty-function": "off", -}; - -// Obsidian developer-policy / guideline rules (from eslint-plugin-obsidianmd), -// enforced on the production plugin source so the fixes made for the community -// plugin review can't silently regress. Scoped to non-test source: the tests -// legitimately stub the global `app`, and these are AST-based rules so they need -// no type information. The remaining review findings backed by type-checked -// rules (no-floating-promises, no-misused-promises, no-duplicate-type-constituents) -// are kept correct via the existing checks/tests rather than enabling project-wide -// type-aware linting here. -const obsidianGuidelineRules = { - "obsidianmd/no-static-styles-assignment": "error", - "obsidianmd/prefer-window-timers": "error", - "obsidianmd/prefer-active-doc": "error", - "obsidianmd/detach-leaves": "error", - "obsidianmd/no-global-this": "error", - "obsidianmd/settings-tab/no-manual-html-headings": "error", - "obsidianmd/commands/no-plugin-name-in-command-name": "error", - "no-restricted-globals": [ - "error", - { - name: "app", - message: - "Avoid the global app object. Use the reference provided by your plugin instance (this.app, or get(plugin).app for module-level code).", - }, - { - name: "fetch", - message: - "Use Obsidian's requestUrl instead of fetch for network requests.", - }, - { - name: "localStorage", - message: - "Use App#saveLocalStorage / App#loadLocalStorage for vault-scoped storage instead of the global localStorage.", - }, - ], -}; - -export default [ - { - ignores: ["node_modules", "build", "npm", "main.js"], - }, - { - files: ["**/*.{ts,cts,mts}"], - languageOptions, - plugins, - rules, - }, - { - files: ["src/**/*.{ts,cts,mts}"], - ignores: ["src/**/*.{test,spec}.{ts,cts,mts}"], - plugins: { obsidianmd }, - rules: obsidianGuidelineRules, - }, - { - files: ["**/*.{test,spec}.{ts,cts,mts}"], - languageOptions: { - ...languageOptions, - globals: { - ...sharedGlobals, - ...vitestGlobals, - }, - }, - plugins, - rules, - }, -]; diff --git a/package-lock.json b/package-lock.json index 0ab61ad6..95c795c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,21 +14,17 @@ }, "devDependencies": { "@biomejs/biome": "^2.5.2", - "@eslint/js": "^9.39.1", "@semantic-release/git": "^10.0.1", "@sveltejs/vite-plugin-svelte": "^7.1.2", "@testing-library/jest-dom": "^6.9.1", "@testing-library/svelte": "^5.4.2", "@types/node": "^26.1.0", - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", "cz-conventional-changelog": "^3.3.0", - "eslint": "^9.39.1", - "eslint-plugin-import-x": "4.17.1", "eslint-plugin-obsidianmd": "^0.4.1", "jsdom": "^27.2.0", "obsidian": "1.13.1", "obsidian-e2e": "0.6.0", + "oxlint": "^1.67.0", "semantic-release": "^25.0.5", "svelte": "^5.43.14", "svelte-check": "^4.7.1", @@ -639,6 +635,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" @@ -651,6 +648,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -662,6 +660,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1774,7 +1773,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1792,7 +1790,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1810,7 +1807,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1828,7 +1824,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1846,7 +1841,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1864,7 +1858,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1882,7 +1875,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1903,7 +1895,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1924,7 +1915,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1945,7 +1935,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1966,7 +1955,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -1987,7 +1975,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2008,7 +1995,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2029,7 +2015,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2050,7 +2035,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2068,7 +2052,6 @@ "os": [ "openharmony" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2086,7 +2069,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2104,7 +2086,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -2122,7 +2103,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -3408,60 +3388,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz", - "integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/type-utils": "8.62.1", - "@typescript-eslint/utils": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "8.62.1", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, "node_modules/@typescript-eslint/project-service": { "version": "8.62.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", @@ -3519,31 +3445,6 @@ "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz", - "integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1", - "debug": "^4.4.3", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, "node_modules/@typescript-eslint/types": { "version": "8.62.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", @@ -3680,319 +3581,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", - "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", - "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", - "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", - "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", - "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", - "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", - "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", - "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", - "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", - "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-loong64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", - "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", - "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", - "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", - "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", - "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", - "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", - "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-openharmony-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", - "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", - "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", - "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", - "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", - "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@vitest/expect": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", @@ -5370,16 +4958,6 @@ "dev": true, "license": "MIT" }, - "node_modules/comment-parser": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.7.tgz", - "integrity": "sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.0.0" - } - }, "node_modules/commitizen": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.2.tgz", @@ -6551,31 +6129,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } - } - }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -6694,43 +6247,6 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/eslint-plugin-import-x": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz", - "integrity": "sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "^8.56.0", - "comment-parser": "^1.4.1", - "debug": "^4.4.1", - "eslint-import-context": "^0.1.9", - "is-glob": "^4.0.3", - "minimatch": "^9.0.3 || ^10.1.2", - "semver": "^7.7.2", - "stable-hash-x": "^0.2.0", - "unrs-resolver": "^1.9.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-import-x" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^8.56.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "eslint-import-resolver-node": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/utils": { - "optional": true - }, - "eslint-import-resolver-node": { - "optional": true - } - } - }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", @@ -10283,22 +9799,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -12729,7 +12229,6 @@ "integrity": "sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "oxlint": "bin/oxlint" }, @@ -14460,16 +13959,6 @@ "through2": "~2.0.0" } }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -15934,44 +15423,6 @@ "node": ">= 10.0.0" } }, - "node_modules/unrs-resolver": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", - "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.4" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.12.2", - "@unrs/resolver-binding-android-arm64": "1.12.2", - "@unrs/resolver-binding-darwin-arm64": "1.12.2", - "@unrs/resolver-binding-darwin-x64": "1.12.2", - "@unrs/resolver-binding-freebsd-x64": "1.12.2", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", - "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", - "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", - "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", - "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-x64-musl": "1.12.2", - "@unrs/resolver-binding-openharmony-arm64": "1.12.2", - "@unrs/resolver-binding-wasm32-wasi": "1.12.2", - "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", - "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", - "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index ea38cb35..3e4c1daf 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "dev": "vite build --watch --mode development", "build": "npm run typecheck && vite build", "typecheck": "tsc --noEmit", - "lint": "eslint \"src/**/*.{ts,cts,mts}\" \"tests/e2e/**/*.ts\" \"scripts/**/*.test.ts\" --max-warnings=0", - "format:check": "biome check package.json manifest.json tsconfig.json eslint.config.mjs vite.config.ts vitest.config.ts vitest.e2e.config.ts tests/e2e scripts", + "lint": "oxlint --deny-warnings src tests/e2e scripts", + "format:check": "biome check package.json manifest.json tsconfig.json .oxlintrc.json vite.config.ts vitest.config.ts vitest.e2e.config.ts tests/e2e scripts", "version": "node version-bump.mjs && git add manifest.json versions.json", "semantic-release": "semantic-release", "test": "npm run check:a11y && vitest", @@ -29,21 +29,17 @@ }, "devDependencies": { "@biomejs/biome": "^2.5.2", - "@eslint/js": "^9.39.1", "@semantic-release/git": "^10.0.1", "@sveltejs/vite-plugin-svelte": "^7.1.2", "@testing-library/jest-dom": "^6.9.1", "@testing-library/svelte": "^5.4.2", "@types/node": "^26.1.0", - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", "cz-conventional-changelog": "^3.3.0", - "eslint": "^9.39.1", - "eslint-plugin-import-x": "4.17.1", "eslint-plugin-obsidianmd": "^0.4.1", "jsdom": "^27.2.0", "obsidian": "1.13.1", "obsidian-e2e": "0.6.0", + "oxlint": "^1.67.0", "semantic-release": "^25.0.5", "svelte": "^5.43.14", "svelte-check": "^4.7.1", diff --git a/src/main.activateView.test.ts b/src/main.activateView.test.ts index 452483e6..d781f55b 100644 --- a/src/main.activateView.test.ts +++ b/src/main.activateView.test.ts @@ -394,7 +394,8 @@ describe("PodNotes onload wiring (#55)", () => { const { commands, ribbonCalls, activateSpy } = await loadPlugin(); const showCmd = commands.find((c) => c.id === "podnotes-show-leaf"); - (showCmd?.callback as () => void)(); + expect(showCmd).toBeDefined(); + (showCmd!.callback as () => void)(); expect(activateSpy).toHaveBeenCalledTimes(1); const ribbon = ribbonCalls.find((r) => r.title === "Show PodNotes"); @@ -422,7 +423,7 @@ describe("PodNotes onload wiring (#55)", () => { const transcribeCmd = commands.find((c) => c.id === "podnotes-transcribe"); expect(transcribeCmd).toBeDefined(); expect( - (transcribeCmd?.checkCallback as (checking: boolean) => boolean)(true), + (transcribeCmd!.checkCallback as (checking: boolean) => boolean)(true), ).toBe(false); }); }); diff --git a/src/main.ts b/src/main.ts index d237dc8a..8e981ee3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ import { hidePlayedEpisodes, sanitizeEpisodeListLimit, playbackRate, + plugin, volume, subscribeQueueToCurrentEpisode, } from "src/store"; @@ -36,7 +37,6 @@ import { import { PodNotesSettingsTab } from "src/ui/settings/PodNotesSettingsTab"; import { MainView } from "src/ui/PodcastView"; import type { IPodNotesSettings } from "./types/IPodNotesSettings"; -import { plugin } from "./store"; import type { IPodNotes } from "./types/IPodNotes"; import { TimestampTemplateEngine } from "./TemplateEngine"; import { prepareTimestampForInsertion } from "./utility/prepareTimestampInsertion"; @@ -453,13 +453,13 @@ export default class PodNotes extends Plugin implements IPodNotes { this.settings = Object.assign({}, DEFAULT_SETTINGS, loadedData); this.settings.timestamp = { ...DEFAULT_SETTINGS.timestamp, - ...(loadedData?.timestamp ?? {}), + ...loadedData?.timestamp, }; // Build a fresh download object so we never mutate the shared // DEFAULT_SETTINGS.download, then migrate the legacy empty default (#183). this.settings.download = { ...DEFAULT_SETTINGS.download, - ...(loadedData?.download ?? {}), + ...loadedData?.download, }; this.settings.download.path = migrateDownloadPath( this.settings.download.path, diff --git a/src/services/TranscriptionService.ts b/src/services/TranscriptionService.ts index 111ba198..2ba9d758 100644 --- a/src/services/TranscriptionService.ts +++ b/src/services/TranscriptionService.ts @@ -310,7 +310,7 @@ export class TranscriptionService { updateNotice: (message: string) => void, ): Promise<{ text: string; failedChunks: number }> { const client = await this.getClient(); - const transcriptions: string[] = new Array(files.length); + const transcriptions: string[] = Array.from({ length: files.length }); let completedChunks = 0; let failedChunks = 0; let nextIndex = 0; diff --git a/src/utility/assertFetchableUrl.ts b/src/utility/assertFetchableUrl.ts index 9dd62931..8effcf06 100644 --- a/src/utility/assertFetchableUrl.ts +++ b/src/utility/assertFetchableUrl.ts @@ -154,7 +154,7 @@ function parseIpv6(input: string): number[] | null { if (halves.length === 2) { const missing = 8 - left.length - right.length; if (missing < 1) return null; // "::" must stand for at least one zero group - return [...left, ...new Array(missing).fill(0), ...right]; + return [...left, ...Array.from({ length: missing }, () => 0), ...right]; } return left.length === 8 ? left : null; From cefd418b3430e9188d514d5eb2e7f8928c04060d Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Mon, 6 Jul 2026 17:11:35 +0200 Subject: [PATCH 2/2] chore(lint): carry over explicit rule relaxations from the old eslint config The repo lints clean either way today; pinning ban-ts-comment, no-empty-function and no-prototype-builtins off guards against these activating via category changes in future oxlint upgrades. --- .oxlintrc.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.oxlintrc.json b/.oxlintrc.json index 40c9a1ea..10d30061 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -17,6 +17,9 @@ }, "ignorePatterns": ["node_modules", "build", "npm", "main.js", "**/*.svelte"], "rules": { + "no-prototype-builtins": "off", + "typescript/ban-ts-comment": "off", + "typescript/no-empty-function": "off", "no-unused-vars": ["error", { "args": "none" }], "import/no-duplicates": "error", "typescript/consistent-type-imports": [