mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
refactor: improve eslint disable comments with justifications
Add eslint-plugin-eslint-comments to require descriptions on all disable directives. Replace generic eslint-disable comments with specific explanations of why rules are disabled. Change `any` type to `unknown` in DependencyService and add justification for remaining `any` usage in StreamingMarkdownService.
This commit is contained in:
parent
6b5eafa4a5
commit
3a97b5b076
11 changed files with 64 additions and 32 deletions
|
|
@ -28,6 +28,7 @@ export class ClaudeConversationNamingService implements IConversationNamingServi
|
|||
}]
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals -- requestUrl doeesn't support AbortSignal
|
||||
const response = await fetch(AIProviderURL.Claude, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export class GeminiConversationNamingService implements IConversationNamingServi
|
|||
}]
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals -- requestUrl doeesn't support AbortSignal
|
||||
const response = await fetch(`${AIProviderURL.Gemini}/${AIProviderModel.GeminiNamer}:generateContent?key=${this.apiKey}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ export class OpenAIConversationNamingService implements IConversationNamingServi
|
|||
]
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals -- requestUrl doeesn't support AbortSignal
|
||||
const response = await fetch(AIProviderURL.OpenAI, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import type VaultkeeperAIPlugin from "main";
|
|||
|
||||
export function openPluginSettings(plugin: VaultkeeperAIPlugin) {
|
||||
// @ts-ignore - accessing internal API
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access -- required to open Settings menu – internal API, no alternative, low runtime risk
|
||||
plugin.app.setting.open();
|
||||
// @ts-ignore - accessing internal API
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access -- required to switch Settings tab – internal API, no alternative, low runtime risk
|
||||
plugin.app.setting.openTabById(plugin.manifest.id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const services = new Map<symbol, any>();
|
||||
const services = new Map<symbol, unknown>();
|
||||
|
||||
export function RegisterSingleton<T>(type: symbol, instance: T): void {
|
||||
services.set(type, instance);
|
||||
|
|
@ -10,7 +9,6 @@ export function RegisterTransient<T>(type: symbol, factory: () => T): void {
|
|||
}
|
||||
|
||||
export function Resolve<T>(type: symbol): T {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const service = services.get(type);
|
||||
if (!service) {
|
||||
throw new Error(`Service not found for type: ${type.description}`);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export class StreamingMarkdownService {
|
|||
private readonly htmlService: HTMLService = Resolve<HTMLService>(Services.HTMLService);
|
||||
private readonly fileSystemService: FileSystemService = Resolve<FileSystemService>(Services.FileSystemService);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- trying to explicitly define unified types gets very complex so allow use of any
|
||||
private readonly processor: Processor<any, any, any, any, any> | null = null;
|
||||
private streamingStates: Map<string, IStreamingState> = new Map<string, IStreamingState>();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export class StreamingService {
|
|||
additionalHeaders?: Record<string, string>
|
||||
): AsyncGenerator<IStreamChunk, void, unknown> {
|
||||
try {
|
||||
// eslint-disable-next-line no-restricted-globals -- requestUrl doeesn't support streaming
|
||||
const response = await fetch(
|
||||
url,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ export class MainView extends ItemView {
|
|||
return 'sparkles';
|
||||
}
|
||||
|
||||
// ItemView requires onOpen to return Promise<void>, but mount operations are synchronous
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
// eslint-disable-next-line @typescript-eslint/require-await -- mount operations are valid but synchronous
|
||||
async onOpen() {
|
||||
const container = this.contentEl;
|
||||
container.empty();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import js from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import obsidianmd from "eslint-plugin-obsidianmd";
|
||||
import eslintComments from "eslint-plugin-eslint-comments";
|
||||
|
||||
export default [
|
||||
// Ignore patterns
|
||||
|
|
@ -23,6 +24,7 @@ export default [
|
|||
files: ["**/*.ts"],
|
||||
plugins: {
|
||||
obsidianmd: obsidianmd,
|
||||
"eslint-comments": eslintComments,
|
||||
},
|
||||
languageOptions: {
|
||||
parser: tseslint.parser,
|
||||
|
|
@ -64,6 +66,15 @@ export default [
|
|||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-require-imports": "error",
|
||||
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
|
||||
// ESLint directive comment rules
|
||||
"eslint-comments/require-description": "error",
|
||||
"eslint-comments/no-unused-disable": "error",
|
||||
"eslint-comments/no-restricted-disable": [
|
||||
"error",
|
||||
"@typescript-eslint/no-explicit-any"
|
||||
],
|
||||
|
||||
// Console usage (allow warn, error, debug only)
|
||||
"no-console": ["error", { allow: ["warn", "error", "debug"] }],
|
||||
|
|
@ -114,29 +125,5 @@ export default [
|
|||
"no-redeclare": "off",
|
||||
"@typescript-eslint/no-redeclare": "off",
|
||||
}
|
||||
},
|
||||
|
||||
// Allow fetch() in streaming services (requires AbortController support)
|
||||
{
|
||||
files: [
|
||||
"**/StreamingService.ts",
|
||||
"**/ClaudeConversationNamingService.ts",
|
||||
"**/GeminiConversationNamingService.ts",
|
||||
"**/OpenAIConversationNamingService.ts"
|
||||
],
|
||||
rules: {
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
name: "app",
|
||||
message: "Avoid using the global app object. Instead use the reference provided by your plugin instance.",
|
||||
},
|
||||
{
|
||||
name: "localStorage",
|
||||
message: "Prefer `App#saveLocalStorage` / `App#loadLocalStorage` functions to write / read localStorage data that's unique to a vault."
|
||||
}
|
||||
// fetch is allowed in these files for streaming with AbortController
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
42
package-lock.json
generated
42
package-lock.json
generated
|
|
@ -35,6 +35,7 @@
|
|||
"zod": "^4.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@testing-library/svelte": "^5.2.8",
|
||||
"@types/express": "^5.0.5",
|
||||
"@types/node": "^24.10.0",
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
"esbuild": "^0.27.0",
|
||||
"esbuild-svelte": "^0.9.3",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-obsidianmd": "^0.1.8",
|
||||
"happy-dom": "^20.0.10",
|
||||
"obsidian": "latest",
|
||||
|
|
@ -3515,6 +3517,46 @@
|
|||
"eslint": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-eslint-comments": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
|
||||
"integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"ignore": "^5.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.5.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mysticatea"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=4.19.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-eslint-comments/node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import": {
|
||||
"version": "2.32.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@testing-library/svelte": "^5.2.8",
|
||||
"@types/express": "^5.0.5",
|
||||
"@types/node": "^24.10.0",
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
"esbuild": "^0.27.0",
|
||||
"esbuild-svelte": "^0.9.3",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-obsidianmd": "^0.1.8",
|
||||
"happy-dom": "^20.0.10",
|
||||
"obsidian": "latest",
|
||||
|
|
|
|||
Loading…
Reference in a new issue