mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
refactor: improve type safety and remove unused imports
- Add explicit type casting for API call results - Fix regex escape sequences to use Unicode notation - Remove unused type imports across multiple services - Update file deletion to use FileManager.trashFile - Add missing switch case for folder modify events - Move CSS imports to ES6 import syntax
This commit is contained in:
parent
643129517a
commit
235609dc4c
10 changed files with 29 additions and 29 deletions
|
|
@ -31,7 +31,7 @@ export class ConversationFileSystemService {
|
|||
created: conversation.created.toISOString(),
|
||||
updated: conversation.updated.toISOString(),
|
||||
contents: conversation.contents
|
||||
.filter(content => content.content !== Copy.ApiRequestAborted)
|
||||
.filter(content => content.content !== Copy.ApiRequestAborted.toString())
|
||||
.map(content => ({
|
||||
role: content.role,
|
||||
content: content.content,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import type VaultkeeperAIPlugin from "main";
|
||||
import { TAbstractFile, TFile, TFolder, type Vault } from "obsidian";
|
||||
import { TAbstractFile, TFile, TFolder } from "obsidian";
|
||||
import { Resolve } from "./DependencyService";
|
||||
import { Services } from "./Services";
|
||||
import { isValidJson } from "Helpers/Helpers";
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ export interface ISanitizeOptions {
|
|||
|
||||
export class SanitiserService {
|
||||
// Regular expressions for different character classes
|
||||
private readonly illegalRe = /[\?<>\\:\*\|"]/g;
|
||||
private readonly controlRe = /[\x00-\x1f\x80-\x9f]/g;
|
||||
private readonly illegalRe = /[?<>\\:*|"]/g;
|
||||
private readonly controlRe = /[\u0000-\u001f\u0080-\u009f]/g;
|
||||
private readonly reservedRe = /^\.+$/;
|
||||
private readonly windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
|
||||
private readonly windowsTrailingRe = /[\. ]+$/;
|
||||
private readonly windowsTrailingRe = /[. ]+$/;
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
|
@ -42,16 +42,16 @@ export class SanitiserService {
|
|||
const outputSeparator = options.separator || "/";
|
||||
|
||||
// Detect if this is an absolute path
|
||||
const isAbsolute = input.startsWith("/") || /^[a-zA-Z]:[\\\/]/.test(input);
|
||||
const isAbsolute = input.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(input);
|
||||
|
||||
// Detect Windows drive letter (e.g., C:)
|
||||
const driveMatch = input.match(/^([a-zA-Z]:)[\\\/]/);
|
||||
const driveMatch = input.match(/^([a-zA-Z]:)[\\/]/);
|
||||
const driveLetter = driveMatch ? driveMatch[1] : "";
|
||||
|
||||
// Split by both forward and back slashes
|
||||
// Note: Forward slashes and backslashes are treated as path separators,
|
||||
// not as illegal characters within segments. This is intentional for cross-platform compatibility.
|
||||
let segments = input.split(/[\\\/]+/);
|
||||
let segments = input.split(/[\\/]+/);
|
||||
|
||||
// Remove empty segments (from leading/trailing slashes or multiple consecutive slashes)
|
||||
// But keep track of whether we started with a slash
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { StreamingMarkdownService } from "./StreamingMarkdownService";
|
|||
import { FileSystemService } from "./FileSystemService";
|
||||
import { ConversationFileSystemService } from "./ConversationFileSystemService";
|
||||
import { ConversationHistoryModal } from "Modals/ConversationHistoryModal";
|
||||
import { FileManager, type App } from "obsidian";
|
||||
import { FileManager } from "obsidian";
|
||||
import { AIFunctionService } from "./AIFunctionService";
|
||||
import { StreamingService } from "./StreamingService";
|
||||
import { AIFunctionDefinitions } from "AIClasses/FunctionDefinitions/AIFunctionDefinitions";
|
||||
|
|
@ -34,12 +34,12 @@ import { UserInputService } from "./UserInputService";
|
|||
import { SearchStateStore } from "Stores/SearchStateStore";
|
||||
import { InputService } from "./InputService";
|
||||
import { HTMLService } from "./HTMLService";
|
||||
import { SettingsService } from "./SettingsService";
|
||||
import { SettingsService, type IVaultkeeperAISettings } from "./SettingsService";
|
||||
import { HelpModal } from "Modals/HelpModal";
|
||||
|
||||
export async function RegisterPlugin(plugin: VaultkeeperAIPlugin) {
|
||||
RegisterSingleton<VaultkeeperAIPlugin>(Services.VaultkeeperAIPlugin, plugin);
|
||||
RegisterSingleton<SettingsService>(Services.SettingsService, new SettingsService(await plugin.loadData()));
|
||||
RegisterSingleton<SettingsService>(Services.SettingsService, new SettingsService(await plugin.loadData() as Partial<IVaultkeeperAISettings>));
|
||||
}
|
||||
|
||||
export function RegisterDependencies() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type VaultkeeperAIPlugin from "main";
|
||||
import { Resolve } from "./DependencyService";
|
||||
import { Services } from "./Services";
|
||||
import { Selector } from "Enums/Selector";
|
||||
|
||||
export class StatusBarService {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import type { AIFunctionCall } from "AIClasses/AIFunctionCall";
|
||||
import type { IAIClass } from "AIClasses/IAIClass";
|
||||
import { Selector } from "Enums/Selector";
|
||||
|
||||
export interface IStreamChunk {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ export class VaultCacheService {
|
|||
this.folders.delete(args.oldPath);
|
||||
}
|
||||
break;
|
||||
|
||||
case FileEvent.Modify:
|
||||
break; // ignore modifications for folders
|
||||
}
|
||||
this.fuzzySortPrepareFolders();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ export class VaultService {
|
|||
return { success: false, error: "File is in exclusion list" };
|
||||
}
|
||||
try {
|
||||
await this.vault.trash(file, true);
|
||||
await this.fileManager.trashFile(file);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error(`Error deleting file ${file.path}:`, error);
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@ const mockVault = {
|
|||
};
|
||||
|
||||
const mockFileManager = {
|
||||
renameFile: vi.fn()
|
||||
renameFile: vi.fn(),
|
||||
trashFile: vi.fn()
|
||||
} as unknown as FileManager & {
|
||||
renameFile: ReturnType<typeof vi.fn>;
|
||||
trashFile: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
|
||||
// Create a mutable settings object that tests can modify
|
||||
|
|
@ -400,12 +402,12 @@ describe('VaultService - Integration Tests', () => {
|
|||
describe('delete', () => {
|
||||
it('should delete file successfully when not excluded', async () => {
|
||||
const mockFile = createMockFile('note.md');
|
||||
mockVault.trash.mockResolvedValue(undefined);
|
||||
mockFileManager.trashFile.mockResolvedValue(undefined);
|
||||
|
||||
const result = await vaultService.delete(mockFile);
|
||||
|
||||
expect(result).toEqual({ success: true });
|
||||
expect(mockVault.trash).toHaveBeenCalledWith(mockFile, true);
|
||||
expect(mockFileManager.trashFile).toHaveBeenCalledWith(mockFile);
|
||||
});
|
||||
|
||||
it('should not delete file and return error when excluded', async () => {
|
||||
|
|
@ -414,22 +416,22 @@ describe('VaultService - Integration Tests', () => {
|
|||
const result = await vaultService.delete(mockFile, false);
|
||||
|
||||
expect(result).toEqual({ success: false, error: 'File is in exclusion list' });
|
||||
expect(mockVault.trash).not.toHaveBeenCalled();
|
||||
expect(mockFileManager.trashFile).not.toHaveBeenCalled();
|
||||
expect(consoleErrorSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pass force parameter to vault.delete', async () => {
|
||||
it('should call fileManager.trashFile to delete file', async () => {
|
||||
const mockFile = createMockFile('note.md');
|
||||
mockVault.trash.mockResolvedValue(undefined);
|
||||
mockFileManager.trashFile.mockResolvedValue(undefined);
|
||||
|
||||
await vaultService.delete(mockFile, true);
|
||||
|
||||
expect(mockVault.trash).toHaveBeenCalledWith(mockFile, true);
|
||||
expect(mockFileManager.trashFile).toHaveBeenCalledWith(mockFile);
|
||||
});
|
||||
|
||||
it('should return error when deletion fails', async () => {
|
||||
const mockFile = createMockFile('note.md');
|
||||
mockVault.trash.mockRejectedValue(new Error('Deletion failed'));
|
||||
mockFileManager.trashFile.mockRejectedValue(new Error('Deletion failed'));
|
||||
|
||||
const result = await vaultService.delete(mockFile);
|
||||
|
||||
|
|
@ -439,7 +441,7 @@ describe('VaultService - Integration Tests', () => {
|
|||
|
||||
it('should handle non-Error objects in catch block', async () => {
|
||||
const mockFile = createMockFile('note.md');
|
||||
mockVault.trash.mockRejectedValue('string error');
|
||||
mockFileManager.trashFile.mockRejectedValue('string error');
|
||||
|
||||
const result = await vaultService.delete(mockFile);
|
||||
|
||||
|
|
|
|||
8
main.ts
8
main.ts
|
|
@ -10,14 +10,12 @@ import { Path } from "Enums/Path";
|
|||
import { Copy } from "Enums/Copy";
|
||||
import type { SettingsService } from "Services/SettingsService";
|
||||
|
||||
import "katex/dist/katex.min.css";
|
||||
import "./styles.css";
|
||||
|
||||
export default class VaultkeeperAIPlugin extends Plugin {
|
||||
|
||||
public async onload() {
|
||||
// KaTeX CSS is bundled with the plugin to comply with CSP
|
||||
require("katex/dist/katex.min.css");
|
||||
// Plugin styles
|
||||
require("./styles.css");
|
||||
|
||||
await RegisterPlugin(this);
|
||||
RegisterDependencies();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue