import type { FsDirent, FilesystemApi } from './types'; export type VaultIpcApi = { showOpenDialog: () => Promise<{ canceled: boolean; filePaths: string[] }>; readdir: (dirPath: string) => Promise; readFile: (filePath: string) => Promise; writeFile: (filePath: string, content: string) => Promise; fileExists: (filePath: string) => Promise; mkdir: (dirPath: string) => Promise; rename: (oldPath: string, newPath: string) => Promise; delete: (filePath: string) => Promise; copyFile: (srcPath: string, destPath: string) => Promise; }; export class VaultFilesystemApi implements FilesystemApi { constructor(private ipc: VaultIpcApi) {} async readdir(dirPath: string): Promise { return this.ipc.readdir(dirPath); } async readFile(filePath: string): Promise { return this.ipc.readFile(filePath); } async writeFile(filePath: string, content: string): Promise { return this.ipc.writeFile(filePath, content); } async fileExists(filePath: string): Promise { return this.ipc.fileExists(filePath); } async mkdir(dirPath: string): Promise { return this.ipc.mkdir(dirPath); } async rename(oldPath: string, newPath: string): Promise { return this.ipc.rename(oldPath, newPath); } async deletePath(filePath: string): Promise { return this.ipc.delete(filePath); } async copyFile(srcPath: string, destPath: string): Promise { return this.ipc.copyFile(srcPath, destPath); } } /** * Get the basename of a path (last component). * Works with both / and \ separators. */ export function basename(filePath: string): string { const parts = filePath.split(/[/\\]/); return parts[parts.length - 1] || ''; } /** * Get the directory name of a path (everything except the last component). * Works with both / and \ separators. */ export function dirname(filePath: string): string { const parts = filePath.split(/[/\\]/); parts.pop(); return parts.join('/') || '/'; } /** * Join path segments. */ export function join(...segments: string[]): string { return segments .map((s) => s.replace(/\\/g, '/').replace(/\/$/, '')) .filter(Boolean) .join('/'); }