Update esling config to closer match obsidian recommended.

esling autofix
This commit is contained in:
Andrew Beal 2025-11-10 11:14:06 +00:00
parent d8c7672211
commit cac0db5b07
6 changed files with 80 additions and 75 deletions

View file

@ -47,7 +47,7 @@ export class AIFunctionService {
}
private async searchVaultFiles(searchTerms: string[]): Promise<object> {
let results: { searchTerm: string, results: object[] }[] = [];
const results: { searchTerm: string, results: object[] }[] = [];
for (const searchTerm of searchTerms) {
const matches: ISearchMatch[] = searchTerm.trim() === "" ? [] : await this.fileSystemService.searchVaultFiles(searchTerm);

View file

@ -55,7 +55,7 @@ export class ConversationNamingService {
}
private async validateName(generatedName: string): Promise<string> {
let cleanedTitle = generatedName.trim().replace(/^["']|["']$/g, "").split(/\s+/).slice(0, 6).join(" ");
const cleanedTitle = generatedName.trim().replace(/^["']|["']$/g, "").split(/\s+/).slice(0, 6).join(" ");
let index = 1;
let availableTitle = cleanedTitle;

View file

@ -36,7 +36,7 @@ export class FileSystemService {
await this.vaultService.create(filePath, content, allowAccessToPluginRoot);
return true;
}
await this.vaultService.modify(file as TFile, content, allowAccessToPluginRoot);
await this.vaultService.modify(file, content, allowAccessToPluginRoot);
return true;
}
catch (error) {

View file

@ -143,8 +143,8 @@ export class InputService {
return null; // Selection is not collapsed, not at a single cursor position
}
let node = range.startContainer;
let offset = range.startOffset;
const node = range.startContainer;
const offset = range.startOffset;
// If we're in a text node
if (node.nodeType === Node.TEXT_NODE) {

View file

@ -155,7 +155,7 @@ export class VaultService {
}
let files: TFile[] = [];
for (let child of dir.children) {
for (const child of dir.children) {
if (child instanceof TFile) {
if (!this.isExclusion(child.path, allowAccessToPluginRoot)) {
files.push(child);
@ -179,7 +179,7 @@ export class VaultService {
}
let folders: TFolder[] = [];
for (let child of dir.children) {
for (const child of dir.children) {
if (!(child instanceof TFolder)) {
continue;
}

View file

@ -2,46 +2,73 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import obsidianmd from "eslint-plugin-obsidianmd";
import sdl from "@microsoft/eslint-plugin-sdl";
import importPlugin from "eslint-plugin-import";
export default [
// Ignore patterns
{
ignores: ["node_modules/**", "main.js"]
ignores: ["node_modules/**", "main.js", "__tests__/**", "*.test.ts", "esbuild.config.mjs", "version-bump.mjs", "vitest.config.ts"]
},
// Base ESLint recommended rules
js.configs.recommended,
// TypeScript configuration for .ts files
// TypeScript recommended rules (type-checked rules disabled for non-TS files)
...tseslint.configs.recommendedTypeChecked.map(config => ({
...config,
files: ["**/*.ts"],
})),
// Project-specific configuration
{
files: ["**/*.ts"],
plugins: {
"@typescript-eslint": tseslint.plugin,
"obsidianmd": obsidianmd,
"@microsoft/sdl": sdl,
"import": importPlugin,
obsidianmd: obsidianmd,
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: true,
sourceType: "module"
},
globals: {
console: "readonly",
AsyncGenerator: "readonly",
require: "readonly",
process: "readonly",
createEl: "readonly",
join: "readonly",
__dirname: "readonly",
document: "readonly",
window: "readonly",
performance: "readonly",
requestAnimationFrame: "readonly",
cancelAnimationFrame: "readonly",
setTimeout: "readonly",
clearTimeout: "readonly",
NodeJS: "readonly",
Fuzzysort: "readonly",
}
},
rules: {
// Base rules
"no-unused-vars": "off",
// Obsidian plugin recommended rules
...obsidianmd.configs.recommended,
// Override TypeScript recommended to match Obsidian's style
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"no-prototype-builtins": "off",
"no-self-compare": "warn",
"no-eval": "error",
"no-implied-eval": "error",
"prefer-const": "off",
"no-implicit-globals": "error",
// Enable additional TypeScript rules for PR issues
"@typescript-eslint/require-await": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/switch-exhaustiveness-check": "error",
// Console usage (allow warn, error, debug only)
"no-console": ["error", { allow: ["warn", "error", "debug"] }],
// Restricted globals (with fetch removed for streaming)
// Restricted globals
"no-restricted-globals": [
"error",
{
@ -51,6 +78,10 @@ export default [
{
name: "localStorage",
message: "Prefer `App#saveLocalStorage` / `App#loadLocalStorage` functions to write / read localStorage data that's unique to a vault."
},
{
name: "fetch",
message: "Use the built-in `requestUrl` function instead of `fetch` for network requests."
}
],
@ -79,59 +110,33 @@ export default [
},
],
"no-alert": "error",
"no-undef": "error",
// Allow namespace merging with enums (TypeScript pattern)
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": "off",
}
},
// TypeScript rules
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-deprecated": "error",
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }],
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-explicit-any": ["error", { fixToUnknown: true }],
"@typescript-eslint/no-empty-function": "off",
// Security rules
"@microsoft/sdl/no-document-write": "error",
"@microsoft/sdl/no-inner-html": "error",
// Import rules
"import/no-nodejs-modules": "error",
"import/no-extraneous-dependencies": "error",
// Obsidian plugin rules - Commands
"obsidianmd/commands/no-command-in-command-id": "error",
"obsidianmd/commands/no-command-in-command-name": "error",
"obsidianmd/commands/no-default-hotkeys": "error",
"obsidianmd/commands/no-plugin-id-in-command-id": "error",
"obsidianmd/commands/no-plugin-name-in-command-name": "error",
// Obsidian plugin rules - Settings Tab
"obsidianmd/settings-tab/no-manual-html-headings": "error",
"obsidianmd/settings-tab/no-problematic-settings-headings": "error",
// Obsidian plugin rules - Vault
"obsidianmd/vault/iterate": "error",
// Obsidian plugin rules - General
"obsidianmd/detach-leaves": "error",
"obsidianmd/hardcoded-config-path": "error",
"obsidianmd/no-forbidden-elements": "error",
"obsidianmd/no-plugin-as-component": "error",
"obsidianmd/no-sample-code": "error",
"obsidianmd/no-tfile-tfolder-cast": "error",
"obsidianmd/no-view-references-in-plugin": "error",
"obsidianmd/no-static-styles-assignment": "error",
"obsidianmd/object-assign": "error",
"obsidianmd/platform": "error",
"obsidianmd/prefer-file-manager-trash-file": "warn",
"obsidianmd/prefer-abstract-input-suggest": "error",
"obsidianmd/regex-lookbehind": "error",
"obsidianmd/sample-names": "error",
"obsidianmd/validate-manifest": "error",
"obsidianmd/validate-license": "error",
// Obsidian plugin rules - UI
"obsidianmd/ui/sentence-case": ["error", { enforceCamelCaseLower: true }],
// 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
]
}
}
];