fix: replace any types with proper TypeScript types

Replace all `any` types with properly defined TypeScript interfaces and types throughout the codebase to improve type safety and eliminate type-related code quality issues.

Changes:
- Define ElectronSafeStorage interface for Electron's safeStorage API
- Create LegacySettings interface for settings migration in main.ts
- Define JSONValue, JSONRPCParams types for JSON-RPC protocol
- Define JSONSchemaProperty for tool input schemas
- Create YAMLValue type for frontmatter values
- Define FrontmatterValue type for adapter interfaces
- Update middleware to use proper Express NextFunction and JSONRPCResponse types
- Fix tool registry to handle args with proper typing (with eslint-disable for dynamic dispatch)
- Fix notifications to use proper types with eslint-disable where dynamic access is needed
- Add proper null safety assertions where appropriate
- Fix TFolder stat access with proper type extension

All type errors resolved. TypeScript compilation passes with --skipLibCheck.
This commit is contained in:
2025-11-07 11:10:52 -05:00
parent b0fc0be629
commit 2a7fce45af
13 changed files with 127 additions and 50 deletions

View File

@@ -1,5 +1,12 @@
// Define Electron SafeStorage interface
interface ElectronSafeStorage {
isEncryptionAvailable(): boolean;
encryptString(plainText: string): Buffer;
decryptString(encrypted: Buffer): string;
}
// Safely import safeStorage - may not be available in all environments
let safeStorage: any = null;
let safeStorage: ElectronSafeStorage | null = null;
try {
const electron = require('electron');
safeStorage = electron.safeStorage || null;
@@ -35,7 +42,7 @@ export function encryptApiKey(apiKey: string): string {
}
try {
const encrypted = safeStorage.encryptString(apiKey);
const encrypted = safeStorage!.encryptString(apiKey);
return `encrypted:${encrypted.toString('base64')}`;
} catch (error) {
console.error('Failed to encrypt API key, falling back to plaintext:', error);

View File

@@ -1,5 +1,16 @@
import { parseYaml } from 'obsidian';
/**
* YAML value types that can appear in frontmatter
*/
export type YAMLValue =
| string
| number
| boolean
| null
| YAMLValue[]
| { [key: string]: YAMLValue };
/**
* Utility class for parsing and extracting frontmatter from markdown files
*/
@@ -11,7 +22,7 @@ export class FrontmatterUtils {
static extractFrontmatter(content: string): {
hasFrontmatter: boolean;
frontmatter: string;
parsedFrontmatter: Record<string, any> | null;
parsedFrontmatter: Record<string, YAMLValue> | null;
content: string;
contentWithoutFrontmatter: string;
} {
@@ -59,7 +70,7 @@ export class FrontmatterUtils {
const contentWithoutFrontmatter = contentLines.join('\n');
// Parse YAML using Obsidian's built-in parser
let parsedFrontmatter: Record<string, any> | null = null;
let parsedFrontmatter: Record<string, YAMLValue> | null = null;
try {
parsedFrontmatter = parseYaml(frontmatter) || {};
} catch (error) {
@@ -80,17 +91,17 @@ export class FrontmatterUtils {
* Extract only the frontmatter summary (common fields)
* Useful for list operations without reading full content
*/
static extractFrontmatterSummary(parsedFrontmatter: Record<string, any> | null): {
static extractFrontmatterSummary(parsedFrontmatter: Record<string, YAMLValue> | null): {
title?: string;
tags?: string[];
aliases?: string[];
[key: string]: any;
[key: string]: YAMLValue | undefined;
} | null {
if (!parsedFrontmatter) {
return null;
}
const summary: Record<string, any> = {};
const summary: Record<string, YAMLValue> = {};
// Extract common fields
if (parsedFrontmatter.title) {
@@ -136,7 +147,7 @@ export class FrontmatterUtils {
* Serialize frontmatter object to YAML string with delimiters
* Returns the complete frontmatter block including --- delimiters
*/
static serializeFrontmatter(data: Record<string, any>): string {
static serializeFrontmatter(data: Record<string, YAMLValue>): string {
if (!data || Object.keys(data).length === 0) {
return '';
}
@@ -203,7 +214,7 @@ export class FrontmatterUtils {
isExcalidraw: boolean;
elementCount?: number;
hasCompressedData?: boolean;
metadata?: Record<string, any>;
metadata?: Record<string, YAMLValue>;
} {
try {
// Excalidraw files are typically markdown with a code block containing JSON
@@ -287,7 +298,7 @@ export class FrontmatterUtils {
// Check if data is compressed (base64 encoded)
const trimmedJson = jsonString.trim();
let jsonData: any;
let jsonData: Record<string, YAMLValue>;
if (trimmedJson.startsWith('N4KAk') || !trimmedJson.startsWith('{')) {
// Data is compressed - try to decompress
@@ -328,9 +339,9 @@ export class FrontmatterUtils {
// Parse the JSON (uncompressed format)
jsonData = JSON.parse(trimmedJson);
// Count elements
const elementCount = jsonData.elements ? jsonData.elements.length : 0;
const elementCount = Array.isArray(jsonData.elements) ? jsonData.elements.length : 0;
// Check for compressed data (files or images)
const hasCompressedData = !!(jsonData.files && Object.keys(jsonData.files).length > 0);